2021-01-15 09:30:03 +00:00
|
|
|
/*
|
|
|
|
Looking Glass - KVM FrameRelay (KVMFR) Client
|
|
|
|
Copyright (C) 2017-2021 Geoffrey McRae <geoff@hostfission.com>
|
|
|
|
https://looking-glass.hostfission.com
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it under
|
|
|
|
the terms of the GNU General Public License as published by the Free Software
|
|
|
|
Foundation; either version 2 of the License, or (at your option) any later
|
|
|
|
version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
|
|
|
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License along with
|
|
|
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
|
|
|
Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*/
|
|
|
|
|
2021-01-27 04:06:02 +00:00
|
|
|
#define _GNU_SOURCE
|
2021-02-20 06:23:48 +00:00
|
|
|
#include "wayland.h"
|
|
|
|
|
2021-01-15 09:30:03 +00:00
|
|
|
#include <assert.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <fcntl.h>
|
2021-01-16 09:31:58 +00:00
|
|
|
#include <signal.h>
|
2021-01-17 05:37:32 +00:00
|
|
|
#include <stdbool.h>
|
2021-01-18 02:55:23 +00:00
|
|
|
#include <sys/mman.h>
|
2021-01-17 05:37:32 +00:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <linux/input.h>
|
2021-01-26 23:59:10 +00:00
|
|
|
#include <poll.h>
|
2021-02-11 06:52:41 +00:00
|
|
|
#include <sys/epoll.h>
|
2021-01-15 09:30:03 +00:00
|
|
|
|
|
|
|
#include <SDL2/SDL.h>
|
|
|
|
#include <wayland-client.h>
|
|
|
|
|
2021-01-27 20:13:35 +00:00
|
|
|
#if defined(ENABLE_EGL) || defined(ENABLE_OPENGL)
|
|
|
|
# include <wayland-egl.h>
|
|
|
|
# include "egl_dynprocs.h"
|
|
|
|
# include <EGL/eglext.h>
|
|
|
|
#endif
|
2021-01-26 23:59:10 +00:00
|
|
|
|
2021-01-15 09:30:03 +00:00
|
|
|
#include "app.h"
|
|
|
|
#include "common/debug.h"
|
2021-02-11 06:52:41 +00:00
|
|
|
#include "common/locking.h"
|
2021-02-11 09:02:08 +00:00
|
|
|
#include "common/countedbuffer.h"
|
2021-02-16 01:54:02 +00:00
|
|
|
#include "common/option.h"
|
2021-01-15 09:30:03 +00:00
|
|
|
|
2021-01-26 23:59:10 +00:00
|
|
|
#include "wayland-xdg-shell-client-protocol.h"
|
2021-01-27 04:53:02 +00:00
|
|
|
#include "wayland-xdg-decoration-unstable-v1-client-protocol.h"
|
2021-01-15 09:30:03 +00:00
|
|
|
#include "wayland-keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h"
|
|
|
|
#include "wayland-pointer-constraints-unstable-v1-client-protocol.h"
|
|
|
|
#include "wayland-relative-pointer-unstable-v1-client-protocol.h"
|
2021-01-18 06:20:02 +00:00
|
|
|
#include "wayland-idle-inhibit-unstable-v1-client-protocol.h"
|
2021-01-15 09:30:03 +00:00
|
|
|
|
2021-02-16 01:54:02 +00:00
|
|
|
static struct Option waylandOptions[] =
|
|
|
|
{
|
|
|
|
{
|
|
|
|
.module = "wayland",
|
|
|
|
.name = "warpSupport",
|
|
|
|
.description = "Enable cursor warping",
|
|
|
|
.type = OPTION_TYPE_BOOL,
|
|
|
|
.value.x_bool = true,
|
|
|
|
},
|
|
|
|
{0}
|
|
|
|
};
|
|
|
|
|
2021-01-26 23:59:10 +00:00
|
|
|
static bool waylandEarlyInit(void)
|
|
|
|
{
|
2021-01-16 09:31:58 +00:00
|
|
|
// Request to receive EPIPE instead of SIGPIPE when one end of a pipe
|
|
|
|
// disconnects while a write is pending. This is useful to the Wayland
|
|
|
|
// clipboard backend, where an arbitrary application is on the other end of
|
|
|
|
// that pipe.
|
|
|
|
signal(SIGPIPE, SIG_IGN);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-02-16 01:54:02 +00:00
|
|
|
static void waylandSetup(void)
|
|
|
|
{
|
|
|
|
option_register(waylandOptions);
|
|
|
|
}
|
|
|
|
|
2021-01-26 10:46:30 +00:00
|
|
|
static bool waylandProbe(void)
|
|
|
|
{
|
|
|
|
return getenv("WAYLAND_DISPLAY") != NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool waylandInit(const LG_DSInitParams params)
|
2021-01-15 09:30:03 +00:00
|
|
|
{
|
2021-02-20 06:23:48 +00:00
|
|
|
memset(&wlWm, 0, sizeof(wlWm));
|
2021-02-16 01:54:02 +00:00
|
|
|
|
2021-02-20 06:23:48 +00:00
|
|
|
wlWm.warpSupport = option_get_bool("wayland", "warpSupport");
|
2021-02-11 06:52:41 +00:00
|
|
|
|
2021-02-20 06:23:48 +00:00
|
|
|
wlWm.display = wl_display_connect(NULL);
|
2021-01-15 09:30:03 +00:00
|
|
|
|
2021-02-20 06:23:48 +00:00
|
|
|
if (!waylandPollInit())
|
2021-02-11 06:52:41 +00:00
|
|
|
return false;
|
2021-01-15 09:30:03 +00:00
|
|
|
|
2021-02-21 03:48:48 +00:00
|
|
|
if (!waylandOutputInit())
|
|
|
|
return false;
|
|
|
|
|
2021-02-20 06:23:48 +00:00
|
|
|
if (!waylandRegistryInit())
|
2021-01-16 18:01:30 +00:00
|
|
|
return false;
|
2021-01-26 23:59:10 +00:00
|
|
|
|
2021-02-20 06:23:48 +00:00
|
|
|
if (!waylandIdleInit())
|
|
|
|
return false;
|
2021-01-26 23:59:10 +00:00
|
|
|
|
2021-02-20 06:23:48 +00:00
|
|
|
if (!waylandInputInit())
|
|
|
|
return false;
|
2021-01-27 04:44:57 +00:00
|
|
|
|
2021-02-20 06:23:48 +00:00
|
|
|
if (!waylandWindowInit(params.title, params.fullscreen, params.maximize, params.borderless))
|
|
|
|
return false;
|
2021-01-26 23:59:10 +00:00
|
|
|
|
2021-02-20 06:23:48 +00:00
|
|
|
if (!waylandEGLInit(params.w, params.h))
|
|
|
|
return false;
|
2021-01-27 04:53:02 +00:00
|
|
|
|
2021-02-20 06:23:48 +00:00
|
|
|
if (!waylandCursorInit())
|
|
|
|
return false;
|
2021-01-27 04:06:02 +00:00
|
|
|
|
2021-01-27 20:13:35 +00:00
|
|
|
#ifdef ENABLE_OPENGL
|
2021-02-20 06:23:48 +00:00
|
|
|
if (params.opengl && !waylandOpenGLInit())
|
|
|
|
return false;
|
2021-01-27 20:13:35 +00:00
|
|
|
#endif
|
2021-01-27 20:03:55 +00:00
|
|
|
|
2021-02-20 06:23:48 +00:00
|
|
|
wlWm.width = params.w;
|
|
|
|
wlWm.height = params.h;
|
2021-01-26 23:59:10 +00:00
|
|
|
|
2021-01-16 18:01:30 +00:00
|
|
|
return true;
|
2021-01-15 09:30:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void waylandStartup(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-01-26 23:59:10 +00:00
|
|
|
static void waylandShutdown(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-02-20 06:23:48 +00:00
|
|
|
static void waylandFree(void)
|
2021-01-27 20:13:35 +00:00
|
|
|
{
|
2021-02-20 06:23:48 +00:00
|
|
|
waylandIdleFree();
|
|
|
|
waylandWindowFree();
|
|
|
|
waylandInputFree();
|
2021-02-21 03:48:48 +00:00
|
|
|
waylandOutputFree();
|
2021-02-20 06:23:48 +00:00
|
|
|
waylandRegistryFree();
|
|
|
|
wl_display_disconnect(wlWm.display);
|
2021-01-27 20:13:35 +00:00
|
|
|
}
|
|
|
|
|
2021-02-20 06:23:48 +00:00
|
|
|
static bool waylandGetProp(LG_DSProperty prop, void * ret)
|
2021-01-16 10:19:20 +00:00
|
|
|
{
|
|
|
|
if (prop == LG_DS_WARP_SUPPORT)
|
|
|
|
{
|
2021-02-20 06:23:48 +00:00
|
|
|
*(enum LG_DSWarpSupport*)ret = wlWm.warpSupport ? LG_DS_WARP_SURFACE : LG_DS_WARP_NONE;
|
2021-01-16 10:19:20 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-01-15 09:30:03 +00:00
|
|
|
struct LG_DisplayServerOps LGDS_Wayland =
|
|
|
|
{
|
2021-02-16 01:54:02 +00:00
|
|
|
.setup = waylandSetup,
|
2021-01-26 23:59:10 +00:00
|
|
|
.probe = waylandProbe,
|
|
|
|
.earlyInit = waylandEarlyInit,
|
|
|
|
.init = waylandInit,
|
|
|
|
.startup = waylandStartup,
|
|
|
|
.shutdown = waylandShutdown,
|
|
|
|
.free = waylandFree,
|
|
|
|
.getProp = waylandGetProp,
|
|
|
|
|
|
|
|
#ifdef ENABLE_EGL
|
|
|
|
.getEGLDisplay = waylandGetEGLDisplay,
|
|
|
|
.getEGLNativeWindow = waylandGetEGLNativeWindow,
|
|
|
|
.eglSwapBuffers = waylandEGLSwapBuffers,
|
|
|
|
#endif
|
|
|
|
|
2021-01-27 20:13:35 +00:00
|
|
|
#ifdef ENABLE_OPENGL
|
2021-01-27 19:36:30 +00:00
|
|
|
.glCreateContext = waylandGLCreateContext,
|
|
|
|
.glDeleteContext = waylandGLDeleteContext,
|
|
|
|
.glMakeCurrent = waylandGLMakeCurrent,
|
|
|
|
.glSetSwapInterval = waylandGLSetSwapInterval,
|
2021-01-26 23:59:10 +00:00
|
|
|
.glSwapBuffers = waylandGLSwapBuffers,
|
2021-01-27 20:13:35 +00:00
|
|
|
#endif
|
2021-01-26 23:59:10 +00:00
|
|
|
|
|
|
|
.showPointer = waylandShowPointer,
|
|
|
|
.grabPointer = waylandGrabPointer,
|
|
|
|
.ungrabPointer = waylandUngrabPointer,
|
|
|
|
.grabKeyboard = waylandGrabKeyboard,
|
|
|
|
.ungrabKeyboard = waylandUngrabKeyboard,
|
|
|
|
.warpPointer = waylandWarpPointer,
|
|
|
|
.realignPointer = waylandRealignPointer,
|
|
|
|
.isValidPointerPos = waylandIsValidPointerPos,
|
|
|
|
.inhibitIdle = waylandInhibitIdle,
|
|
|
|
.uninhibitIdle = waylandUninhibitIdle,
|
|
|
|
.wait = waylandWait,
|
|
|
|
.setWindowSize = waylandSetWindowSize,
|
|
|
|
.setFullscreen = waylandSetFullscreen,
|
|
|
|
.getFullscreen = waylandGetFullscreen,
|
2021-01-15 09:30:03 +00:00
|
|
|
|
|
|
|
.cbInit = waylandCBInit,
|
|
|
|
.cbNotice = waylandCBNotice,
|
|
|
|
.cbRelease = waylandCBRelease,
|
|
|
|
.cbRequest = waylandCBRequest
|
|
|
|
};
|