diff --git a/meson.build b/meson.build index e5574ff..c6c7e3a 100644 --- a/meson.build +++ b/meson.build @@ -46,6 +46,7 @@ executable( 'src/main.cpp', 'src/wlserver.c', 'src/drm.cpp', + 'src/inputsdl.cpp', [ 'src/rendervulkan.cpp', spirv_shader ], dependencies : [ dep_x11, dep_xdamage, dep_xcomposite, dep_xrender, dep_xext, diff --git a/src/inputsdl.cpp b/src/inputsdl.cpp new file mode 100644 index 0000000..8cc8f92 --- /dev/null +++ b/src/inputsdl.cpp @@ -0,0 +1,81 @@ +// For the nested case, reads input from the SDL window and send to wayland + +#include +#include + +#include +#include + +#include + +#include "inputsdl.hpp" +#include "wlserver.h" + +std::mutex g_SDLInitLock; + +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 inputSDLThreadRun( void ) +{ + // :/ + signal(SIGUSR1, SIG_IGN); + + SDL_Event event; + + SDL_Init( SDL_INIT_VIDEO | SDL_INIT_EVENTS ); + + g_SDLInitLock.unlock(); + + while( SDL_WaitEvent( &event ) ) + { + switch( event.type ) + { + case SDL_MOUSEMOTION: + wlserver_lock(); + wlserver_mousemotion( event.motion.x, event.motion.y, 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; + 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; +} diff --git a/src/inputsdl.hpp b/src/inputsdl.hpp new file mode 100644 index 0000000..38c7ced --- /dev/null +++ b/src/inputsdl.hpp @@ -0,0 +1,13 @@ +// For the nested case, reads input from the SDL window and send to wayland + +#pragma once + +#ifndef C_SIDE +extern "C" { +#endif + +bool inputsdl_init( void ); + +#ifndef C_SIDE +} +#endif diff --git a/src/main.cpp b/src/main.cpp index b1c5d81..14457df 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,6 +12,7 @@ #include "main.hpp" #include "drm.hpp" #include "rendervulkan.hpp" +#include "inputsdl.hpp" int ac; char **av; @@ -67,8 +68,10 @@ int main(int argc, char **argv) XInitThreads(); + inputsdl_init(); + initOutput(); - + wlserver_init(argc, argv, g_bIsNested == true ); wlserver_run(); @@ -96,8 +99,6 @@ void initOutput(void) if ( g_bIsNested == true ) { - SDL_Init(SDL_INIT_VIDEO); - window = SDL_CreateWindow( "steamcompmgr", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, g_nOutputWidth, g_nOutputHeight, SDL_WINDOW_VULKAN ); diff --git a/src/steamcompmgr.c b/src/steamcompmgr.c index f8e4466..9a5ebfb 100644 --- a/src/steamcompmgr.c +++ b/src/steamcompmgr.c @@ -945,6 +945,14 @@ determine_and_apply_focus (Display *dpy) } currentFocusWindow = focus->id; + + if ( w != focus ) + { + wlserver_lock(); + wlserver_mousefocus( focus->wlrsurface ); + wlserver_unlock(); + } + w = focus; set_win_hidden(dpy, w, False); diff --git a/src/wlserver.c b/src/wlserver.c index 37d31a9..cde6890 100644 --- a/src/wlserver.c +++ b/src/wlserver.c @@ -1,9 +1,13 @@ #define _POSIX_C_SOURCE 200112L +#define _GNU_SOURCE + #include #include #include #include #include +#include +#include #include #include @@ -11,6 +15,7 @@ #include #include #include +#include #include #include @@ -89,8 +94,8 @@ static void xwayland_ready(struct wl_listener *listener, void *data) struct wl_listener xwayland_ready_listener = { .notify = xwayland_ready }; -int wlserver_init(int argc, char **argv, Bool bIsNested) { - bool bIsDRM = bIsNested == False; +int wlserver_init(int argc, char **argv, bool bIsNested) { + bool bIsDRM = bIsNested == false; wlr_log_init(WLR_DEBUG, NULL); wlserver.wl_display = wl_display_create(); @@ -129,11 +134,11 @@ int wlserver_init(int argc, char **argv, Bool bIsNested) { } wlr_multi_backend_add(wlserver.wlr.backend, libinput_backend); } - else - { - wlserver.wlr.keyboard = wlr_headless_add_input_device( headless_backend, WLR_INPUT_DEVICE_KEYBOARD ); - wlserver.wlr.pointer = wlr_headless_add_input_device( headless_backend, WLR_INPUT_DEVICE_POINTER ); - } +// else +// { +// wlserver.wlr.keyboard_dev = wlr_headless_add_input_device( headless_backend, WLR_INPUT_DEVICE_KEYBOARD ); +// wlserver.wlr.pointer_dev = wlr_headless_add_input_device( headless_backend, WLR_INPUT_DEVICE_POINTER ); +// } wlserver.wlr.renderer = wlr_backend_get_renderer(wlserver.wlr.backend); @@ -167,6 +172,10 @@ int wlserver_init(int argc, char **argv, Bool bIsNested) { setenv("WAYLAND_DISPLAY", socket, true); wlserver.wlr.seat = wlr_seat_create(wlserver.wl_display, "seat0"); + + wlr_seat_set_capabilities( wlserver.wlr.seat, WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_KEYBOARD ); +// wlr_seat_set_keyboard( wlserver.wlr.seat, wlserver.wlr.keyboard_dev ); + wlr_xwayland_set_seat(wlserver.wlr.xwayland, wlserver.wlr.seat); wl_signal_add(&wlserver.wlr.xwayland->events.ready, &xwayland_ready_listener); @@ -233,3 +242,33 @@ int wlserver_run(void) wl_display_destroy(wlserver.wl_display); return 0; } + +void wlserver_mousefocus( struct wlr_surface *wlrsurface ) +{ + wlr_seat_pointer_notify_enter( wlserver.wlr.seat, wlrsurface, 0.5, 0.5 ); +} + +void wlserver_mousemotion( int x, int y, uint32_t time ) +{ + wlr_seat_pointer_notify_motion( wlserver.wlr.seat, time, x, y ); + wlr_seat_pointer_notify_frame( wlserver.wlr.seat ); +} + +void wlserver_mousebutton( int button, bool press, uint32_t time ) +{ + wlr_seat_pointer_notify_button( wlserver.wlr.seat, time, button, press ? WLR_BUTTON_PRESSED : WLR_BUTTON_RELEASED ); + wlr_seat_pointer_notify_frame( wlserver.wlr.seat ); +} + +void wlserver_mousewheel( int x, int y, uint32_t time ) +{ + if ( x != 0 ) + { + wlr_seat_pointer_notify_axis( wlserver.wlr.seat, time, WLR_AXIS_ORIENTATION_HORIZONTAL, x, x, WLR_AXIS_SOURCE_WHEEL ); + } + if ( y != 0 ) + { + wlr_seat_pointer_notify_axis( wlserver.wlr.seat, time, WLR_AXIS_ORIENTATION_VERTICAL, y, y, WLR_AXIS_SOURCE_WHEEL ); + } + wlr_seat_pointer_notify_frame( wlserver.wlr.seat ); +} diff --git a/src/wlserver.h b/src/wlserver.h index 64d0fb4..a7334b4 100644 --- a/src/wlserver.h +++ b/src/wlserver.h @@ -25,9 +25,9 @@ struct wlserver_t { struct wlr_seat *seat; struct wlr_output *output; - // Only for nested - struct wlr_input_device *keyboard; - struct wlr_input_device *pointer; +// // Only for nested (?) +// struct wlr_input_device *keyboard_dev; +// struct wlr_input_device *pointer_dev; } wlr; }; @@ -41,7 +41,7 @@ extern "C" { extern const struct wlr_surface_role xwayland_surface_role; -int wlserver_init( int argc, char **argv, Bool bIsNested ); +int wlserver_init( int argc, char **argv, bool bIsNested ); int wlserver_run(void); @@ -50,6 +50,11 @@ void nudge_steamcompmgr(void); void wlserver_lock(void); void wlserver_unlock(void); +void wlserver_mousefocus( struct wlr_surface *wlrsurface ); +void wlserver_mousemotion( int x, int y, uint32_t time ); +void wlserver_mousebutton( int button, bool press, uint32_t time ); +void wlserver_mousewheel( int x, int y, uint32_t time ); + #ifndef C_SIDE } #endif