Add SDL input handling in the nested case, plumb basic mouse stuff.

Relative mouse broken right now.
This commit is contained in:
Pierre-Loup A. Griffais 2020-01-02 16:23:39 +09:00 committed by Pierre-Loup A. Griffais
parent b11f46d4e7
commit d357278b98
7 changed files with 162 additions and 14 deletions

View file

@ -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,

81
src/inputsdl.cpp Normal file
View file

@ -0,0 +1,81 @@
// 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.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;
}

13
src/inputsdl.hpp Normal file
View file

@ -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

View file

@ -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 );

View file

@ -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);

View file

@ -1,9 +1,13 @@
#define _POSIX_C_SOURCE 200112L
#define _GNU_SOURCE
#include <assert.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <sys/epoll.h>
#include <wayland-server-core.h>
@ -11,6 +15,7 @@
#include <wlr/backend/headless.h>
#include <wlr/backend/multi.h>
#include <wlr/backend/libinput.h>
#include <wlr/interfaces/wlr_pointer.h>
#include <wlr/render/wlr_renderer.h>
#include <wlr/util/log.h>
@ -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 );
}

View file

@ -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