sdlwindow: put all the SDL I/O code in the same spot.
This commit is contained in:
parent
81b8e8c33c
commit
79cb130dcc
8 changed files with 226 additions and 205 deletions
|
@ -70,7 +70,7 @@ executable(
|
|||
'src/main.cpp',
|
||||
'src/wlserver.cpp',
|
||||
'src/drm.cpp',
|
||||
'src/inputsdl.cpp',
|
||||
'src/sdlwindow.cpp',
|
||||
'src/vblankmanager.cpp',
|
||||
[ 'src/rendervulkan.cpp', spirv_shader ],
|
||||
dependencies : [
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
// For the nested case, reads input from the SDL window and send to wayland
|
||||
|
||||
#pragma once
|
||||
|
||||
bool inputsdl_init( void );
|
34
src/main.cpp
34
src/main.cpp
|
@ -3,6 +3,7 @@
|
|||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
|
@ -10,14 +11,12 @@
|
|||
#include "steamcompmgr.hpp"
|
||||
#include "drm.hpp"
|
||||
#include "rendervulkan.hpp"
|
||||
#include "inputsdl.hpp"
|
||||
#include "sdlwindow.hpp"
|
||||
#include "wlserver.hpp"
|
||||
|
||||
int ac;
|
||||
char **av;
|
||||
|
||||
SDL_Window *window;
|
||||
|
||||
int g_nNestedWidth = 1280;
|
||||
int g_nNestedHeight = 720;
|
||||
int g_nNestedRefresh = 60;
|
||||
|
@ -156,34 +155,7 @@ int initOutput(void)
|
|||
{
|
||||
if ( g_bIsNested == true )
|
||||
{
|
||||
inputsdl_init();
|
||||
|
||||
uint32_t nSDLWindowFlags = SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE;
|
||||
|
||||
if ( g_bBorderlessOutputWindow == true )
|
||||
{
|
||||
nSDLWindowFlags |= SDL_WINDOW_BORDERLESS;
|
||||
}
|
||||
|
||||
window = SDL_CreateWindow( "gamescope",
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
g_nOutputWidth,
|
||||
g_nOutputHeight,
|
||||
nSDLWindowFlags );
|
||||
if ( window == nullptr )
|
||||
{
|
||||
fprintf(stderr, "Failed to create SDL window\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned int extCount = 0;
|
||||
SDL_Vulkan_GetInstanceExtensions( window, &extCount, nullptr );
|
||||
|
||||
g_vecSDLInstanceExts.resize( extCount );
|
||||
|
||||
SDL_Vulkan_GetInstanceExtensions( window, &extCount, g_vecSDLInstanceExts.data() );
|
||||
return 0;
|
||||
return sdlwindow_init() == false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
#include <SDL.h>
|
||||
#include <SDL_vulkan.h>
|
||||
|
||||
extern SDL_Window *window;
|
||||
#pragma once
|
||||
|
||||
int initOutput(void);
|
||||
|
||||
|
@ -21,6 +18,8 @@ extern int g_nOutputRefresh;
|
|||
|
||||
extern bool g_bFilterGameWindow;
|
||||
|
||||
extern bool g_bBorderlessOutputWindow;
|
||||
|
||||
extern bool g_bTakeScreenshot;
|
||||
|
||||
extern uint32_t g_nSubCommandArg;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "rendervulkan.hpp"
|
||||
#include "main.hpp"
|
||||
#include "steamcompmgr.hpp"
|
||||
#include "sdlwindow.hpp"
|
||||
|
||||
#include "composite.h"
|
||||
|
||||
|
@ -962,7 +963,7 @@ bool vulkan_make_output( VulkanOutput_t *pOutput )
|
|||
|
||||
if ( BIsNested() == true )
|
||||
{
|
||||
SDL_Vulkan_CreateSurface( window, instance, &pOutput->surface );
|
||||
SDL_Vulkan_CreateSurface( g_SDLWindow, instance, &pOutput->surface );
|
||||
|
||||
if ( pOutput->surface == VK_NULL_HANDLE )
|
||||
return false;
|
||||
|
|
|
@ -1,22 +1,4 @@
|
|||
// For the nested case, reads input from the SDL window and send to wayland
|
||||
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
|
||||
#include <signal.h>
|
||||
#include <linux/input-event-codes.h>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "inputsdl.hpp"
|
||||
#include "wlserver.hpp"
|
||||
#include "main.hpp"
|
||||
|
||||
std::mutex g_SDLInitLock;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Adapted from the key table in SDL/src/input/evdev/SDL_evdev.c
|
||||
//-----------------------------------------------------------------------------
|
||||
static uint32_t s_ScancodeTable[] =
|
||||
{
|
||||
KEY_RESERVED, /* SDL_SCANCODE_UNKNOWN 0 */
|
||||
|
@ -305,148 +287,3 @@ static uint32_t s_ScancodeTable[] =
|
|||
KEY_PROG1, /* SDL_SCANCODE_APP1 283 */
|
||||
KEY_RESERVED, /* SDL_SCANCODE_APP2 284 */
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Convert from the remote scancode to a Linux event keycode
|
||||
//-----------------------------------------------------------------------------
|
||||
static inline uint32_t SDLScancodeToLinuxKey( uint32_t nScancode )
|
||||
{
|
||||
if ( nScancode < sizeof( s_ScancodeTable ) / sizeof( s_ScancodeTable[0] ) )
|
||||
{
|
||||
return s_ScancodeTable[ nScancode ];
|
||||
}
|
||||
return KEY_RESERVED;
|
||||
}
|
||||
|
||||
static inline int SDLButtonToLinuxButton( int SDLButton )
|
||||
{
|
||||
switch ( SDLButton )
|
||||
{
|
||||
case SDL_BUTTON_LEFT: return BTN_LEFT;
|
||||
case SDL_BUTTON_MIDDLE: return BTN_MIDDLE;
|
||||
case SDL_BUTTON_RIGHT: return BTN_RIGHT;
|
||||
case SDL_BUTTON_X1: return BTN_FORWARD;
|
||||
case SDL_BUTTON_X2: return BTN_BACK;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void updateOutputRefresh( void )
|
||||
{
|
||||
int display_index = 0;
|
||||
SDL_DisplayMode mode = { SDL_PIXELFORMAT_UNKNOWN, 0, 0, 0, 0 };
|
||||
|
||||
display_index = SDL_GetWindowDisplayIndex( window );
|
||||
if ( SDL_GetDesktopDisplayMode( display_index, &mode ) == 0 )
|
||||
{
|
||||
g_nOutputRefresh = mode.refresh_rate;
|
||||
}
|
||||
}
|
||||
|
||||
void inputSDLThreadRun( void )
|
||||
{
|
||||
// see wlroots xwayland startup and how wl_event_loop_add_signal works
|
||||
sigset_t mask;
|
||||
sigemptyset(&mask);
|
||||
sigaddset(&mask, SIGUSR1);
|
||||
sigprocmask(SIG_BLOCK, &mask, NULL);
|
||||
|
||||
SDL_Event event;
|
||||
SDL_Keymod mod;
|
||||
uint32_t key;
|
||||
static bool bFullscreen = false;
|
||||
|
||||
SDL_Init( SDL_INIT_VIDEO | SDL_INIT_EVENTS );
|
||||
SDL_SetRelativeMouseMode(SDL_TRUE);
|
||||
|
||||
g_SDLInitLock.unlock();
|
||||
|
||||
while( SDL_WaitEvent( &event ) )
|
||||
{
|
||||
switch( event.type )
|
||||
{
|
||||
case SDL_MOUSEMOTION:
|
||||
wlserver_lock();
|
||||
wlserver_mousemotion( event.motion.xrel, event.motion.yrel, event.motion.timestamp );
|
||||
wlserver_unlock();
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
wlserver_lock();
|
||||
wlserver_mousebutton( SDLButtonToLinuxButton( event.button.button ),
|
||||
event.button.state == SDL_PRESSED,
|
||||
event.button.timestamp );
|
||||
wlserver_unlock();
|
||||
break;
|
||||
case SDL_MOUSEWHEEL:
|
||||
wlserver_lock();
|
||||
wlserver_mousewheel( -event.wheel.x, -event.wheel.y, event.wheel.timestamp );
|
||||
wlserver_unlock();
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP:
|
||||
mod = SDL_GetModState();
|
||||
key = SDLScancodeToLinuxKey( event.key.keysym.scancode );
|
||||
|
||||
if ( event.type == SDL_KEYUP && mod & KMOD_LGUI )
|
||||
{
|
||||
switch ( key )
|
||||
{
|
||||
case KEY_F:
|
||||
bFullscreen = !bFullscreen;
|
||||
SDL_SetWindowFullscreen( window, bFullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0 );
|
||||
break;
|
||||
case KEY_N:
|
||||
g_bFilterGameWindow = !g_bFilterGameWindow;
|
||||
break;
|
||||
case KEY_S:
|
||||
g_bTakeScreenshot = true;
|
||||
break;
|
||||
default:
|
||||
goto client;
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
client:
|
||||
wlserver_lock();
|
||||
wlserver_key( key, event.type == SDL_KEYDOWN, event.key.timestamp );
|
||||
wlserver_unlock();
|
||||
break;
|
||||
case SDL_WINDOWEVENT:
|
||||
switch( event.window.event )
|
||||
{
|
||||
default:
|
||||
break;
|
||||
case SDL_WINDOWEVENT_MOVED:
|
||||
case SDL_WINDOWEVENT_SHOWN:
|
||||
updateOutputRefresh();
|
||||
break;
|
||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||
g_nOutputWidth = event.window.data1;
|
||||
g_nOutputHeight = event.window.data2;
|
||||
|
||||
updateOutputRefresh();
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool inputsdl_init( void )
|
||||
{
|
||||
g_SDLInitLock.lock();
|
||||
|
||||
std::thread inputSDLThread( inputSDLThreadRun );
|
||||
inputSDLThread.detach();
|
||||
|
||||
// When this returns SDL_Init should be over
|
||||
g_SDLInitLock.lock();
|
||||
|
||||
return true;
|
||||
}
|
204
src/sdlwindow.cpp
Normal file
204
src/sdlwindow.cpp
Normal file
|
@ -0,0 +1,204 @@
|
|||
// For the nested case, reads input from the SDL window and send to wayland
|
||||
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
|
||||
#include <signal.h>
|
||||
#include <linux/input-event-codes.h>
|
||||
|
||||
#include "main.hpp"
|
||||
#include "wlserver.hpp"
|
||||
#include "sdlwindow.hpp"
|
||||
#include "rendervulkan.hpp"
|
||||
|
||||
#include "sdlscancodetable.hpp"
|
||||
|
||||
bool g_bSDLInitOK = false;
|
||||
std::mutex g_SDLInitLock;
|
||||
|
||||
SDL_Window *g_SDLWindow;
|
||||
uint32_t g_unSDLUserEventID;
|
||||
SDL_Event g_SDLUserEvent;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Convert from the remote scancode to a Linux event keycode
|
||||
//-----------------------------------------------------------------------------
|
||||
static inline uint32_t SDLScancodeToLinuxKey( uint32_t nScancode )
|
||||
{
|
||||
if ( nScancode < sizeof( s_ScancodeTable ) / sizeof( s_ScancodeTable[0] ) )
|
||||
{
|
||||
return s_ScancodeTable[ nScancode ];
|
||||
}
|
||||
return KEY_RESERVED;
|
||||
}
|
||||
|
||||
static inline int SDLButtonToLinuxButton( int SDLButton )
|
||||
{
|
||||
switch ( SDLButton )
|
||||
{
|
||||
case SDL_BUTTON_LEFT: return BTN_LEFT;
|
||||
case SDL_BUTTON_MIDDLE: return BTN_MIDDLE;
|
||||
case SDL_BUTTON_RIGHT: return BTN_RIGHT;
|
||||
case SDL_BUTTON_X1: return BTN_FORWARD;
|
||||
case SDL_BUTTON_X2: return BTN_BACK;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void updateOutputRefresh( void )
|
||||
{
|
||||
int display_index = 0;
|
||||
SDL_DisplayMode mode = { SDL_PIXELFORMAT_UNKNOWN, 0, 0, 0, 0 };
|
||||
|
||||
display_index = SDL_GetWindowDisplayIndex( g_SDLWindow );
|
||||
if ( SDL_GetDesktopDisplayMode( display_index, &mode ) == 0 )
|
||||
{
|
||||
g_nOutputRefresh = mode.refresh_rate;
|
||||
}
|
||||
}
|
||||
|
||||
void inputSDLThreadRun( void )
|
||||
{
|
||||
// see wlroots xwayland startup and how wl_event_loop_add_signal works
|
||||
sigset_t mask;
|
||||
sigemptyset(&mask);
|
||||
sigaddset(&mask, SIGUSR1);
|
||||
sigprocmask(SIG_BLOCK, &mask, NULL);
|
||||
|
||||
SDL_Event event;
|
||||
SDL_Keymod mod;
|
||||
uint32_t key;
|
||||
static bool bFullscreen = false;
|
||||
|
||||
SDL_Init( SDL_INIT_VIDEO | SDL_INIT_EVENTS );
|
||||
|
||||
g_unSDLUserEventID = SDL_RegisterEvents( 1 );
|
||||
|
||||
g_SDLUserEvent.type = g_unSDLUserEventID;
|
||||
g_SDLUserEvent.user.code = 32;
|
||||
|
||||
uint32_t nSDLWindowFlags = SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE;
|
||||
|
||||
if ( g_bBorderlessOutputWindow == true )
|
||||
{
|
||||
nSDLWindowFlags |= SDL_WINDOW_BORDERLESS;
|
||||
}
|
||||
|
||||
g_SDLWindow = SDL_CreateWindow( "gamescope",
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
g_nOutputWidth,
|
||||
g_nOutputHeight,
|
||||
nSDLWindowFlags );
|
||||
|
||||
if ( g_SDLWindow == nullptr )
|
||||
{
|
||||
g_SDLInitLock.unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int extCount = 0;
|
||||
SDL_Vulkan_GetInstanceExtensions( g_SDLWindow, &extCount, nullptr );
|
||||
|
||||
g_vecSDLInstanceExts.resize( extCount );
|
||||
|
||||
SDL_Vulkan_GetInstanceExtensions( g_SDLWindow, &extCount, g_vecSDLInstanceExts.data() );
|
||||
|
||||
SDL_SetRelativeMouseMode(SDL_TRUE);
|
||||
|
||||
g_bSDLInitOK = true;
|
||||
g_SDLInitLock.unlock();
|
||||
|
||||
while( SDL_WaitEvent( &event ) )
|
||||
{
|
||||
switch( event.type )
|
||||
{
|
||||
case SDL_MOUSEMOTION:
|
||||
wlserver_lock();
|
||||
wlserver_mousemotion( event.motion.xrel, event.motion.yrel, event.motion.timestamp );
|
||||
wlserver_unlock();
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
wlserver_lock();
|
||||
wlserver_mousebutton( SDLButtonToLinuxButton( event.button.button ),
|
||||
event.button.state == SDL_PRESSED,
|
||||
event.button.timestamp );
|
||||
wlserver_unlock();
|
||||
break;
|
||||
case SDL_MOUSEWHEEL:
|
||||
wlserver_lock();
|
||||
wlserver_mousewheel( -event.wheel.x, -event.wheel.y, event.wheel.timestamp );
|
||||
wlserver_unlock();
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP:
|
||||
mod = SDL_GetModState();
|
||||
key = SDLScancodeToLinuxKey( event.key.keysym.scancode );
|
||||
|
||||
if ( event.type == SDL_KEYUP && mod & KMOD_LGUI )
|
||||
{
|
||||
switch ( key )
|
||||
{
|
||||
case KEY_F:
|
||||
bFullscreen = !bFullscreen;
|
||||
SDL_SetWindowFullscreen( g_SDLWindow, bFullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0 );
|
||||
break;
|
||||
case KEY_N:
|
||||
g_bFilterGameWindow = !g_bFilterGameWindow;
|
||||
break;
|
||||
case KEY_S:
|
||||
g_bTakeScreenshot = true;
|
||||
break;
|
||||
default:
|
||||
goto client;
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
client:
|
||||
wlserver_lock();
|
||||
wlserver_key( key, event.type == SDL_KEYDOWN, event.key.timestamp );
|
||||
wlserver_unlock();
|
||||
break;
|
||||
case SDL_WINDOWEVENT:
|
||||
switch( event.window.event )
|
||||
{
|
||||
default:
|
||||
break;
|
||||
case SDL_WINDOWEVENT_MOVED:
|
||||
case SDL_WINDOWEVENT_SHOWN:
|
||||
updateOutputRefresh();
|
||||
break;
|
||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||
g_nOutputWidth = event.window.data1;
|
||||
g_nOutputHeight = event.window.data2;
|
||||
|
||||
updateOutputRefresh();
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool sdlwindow_init( void )
|
||||
{
|
||||
g_SDLInitLock.lock();
|
||||
|
||||
std::thread inputSDLThread( inputSDLThreadRun );
|
||||
inputSDLThread.detach();
|
||||
|
||||
// When this returns SDL_Init should be over
|
||||
g_SDLInitLock.lock();
|
||||
|
||||
return g_bSDLInitOK;
|
||||
}
|
||||
|
||||
void sdlwindow_update( void )
|
||||
{
|
||||
SDL_PushEvent( &g_SDLUserEvent );
|
||||
}
|
13
src/sdlwindow.hpp
Normal file
13
src/sdlwindow.hpp
Normal file
|
@ -0,0 +1,13 @@
|
|||
// For the nested case, manages SDL window for input/output
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_vulkan.h>
|
||||
|
||||
bool sdlwindow_init( void );
|
||||
|
||||
// called from other threads with interesting things have happened with clients that might warrant updating the nested window
|
||||
void sdlwindow_update( void );
|
||||
|
||||
extern SDL_Window *g_SDLWindow;
|
Loading…
Reference in a new issue