2021-02-20 06:23:48 +00:00
|
|
|
/*
|
|
|
|
Looking Glass - KVM FrameRelay (KVMFR) Client
|
|
|
|
Copyright (C) 2021 Guanzhong Chen (quantum2048@gmail.com)
|
|
|
|
Copyright (C) 2021 Tudor Brindus (contact@tbrindus.ca)
|
|
|
|
https://looking-glass.io
|
|
|
|
|
|
|
|
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
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
|
|
|
#include <wayland-client.h>
|
|
|
|
|
|
|
|
#if defined(ENABLE_EGL) || defined(ENABLE_OPENGL)
|
|
|
|
# include <wayland-egl.h>
|
|
|
|
# include <EGL/egl.h>
|
|
|
|
# include <EGL/eglext.h>
|
|
|
|
#endif
|
|
|
|
|
2021-05-11 20:49:39 +00:00
|
|
|
#include "egl_dynprocs.h"
|
2021-02-20 06:23:48 +00:00
|
|
|
#include "common/locking.h"
|
|
|
|
#include "common/countedbuffer.h"
|
|
|
|
#include "interface/displayserver.h"
|
|
|
|
|
|
|
|
#include "wayland-xdg-shell-client-protocol.h"
|
|
|
|
#include "wayland-xdg-decoration-unstable-v1-client-protocol.h"
|
|
|
|
#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"
|
|
|
|
#include "wayland-idle-inhibit-unstable-v1-client-protocol.h"
|
|
|
|
|
|
|
|
typedef void (*WaylandPollCallback)(uint32_t events, void * opaque);
|
|
|
|
|
|
|
|
struct WaylandPoll
|
|
|
|
{
|
|
|
|
int fd;
|
|
|
|
bool removed;
|
|
|
|
WaylandPollCallback callback;
|
|
|
|
void * opaque;
|
|
|
|
struct wl_list link;
|
|
|
|
};
|
|
|
|
|
2021-02-21 03:48:48 +00:00
|
|
|
struct WaylandOutput
|
|
|
|
{
|
|
|
|
uint32_t name;
|
|
|
|
int32_t scale;
|
|
|
|
struct wl_output * output;
|
2021-02-27 02:38:20 +00:00
|
|
|
uint32_t version;
|
2021-02-21 03:48:48 +00:00
|
|
|
struct wl_list link;
|
|
|
|
};
|
|
|
|
|
2021-02-21 05:10:08 +00:00
|
|
|
struct SurfaceOutput
|
|
|
|
{
|
|
|
|
struct wl_output * output;
|
|
|
|
struct wl_list link;
|
|
|
|
};
|
|
|
|
|
2021-05-11 20:49:39 +00:00
|
|
|
enum EGLSwapWithDamageState {
|
|
|
|
SWAP_WITH_DAMAGE_UNKNOWN,
|
|
|
|
SWAP_WITH_DAMAGE_UNSUPPORTED,
|
|
|
|
SWAP_WITH_DAMAGE_KHR,
|
|
|
|
SWAP_WITH_DAMAGE_EXT,
|
|
|
|
};
|
|
|
|
|
2021-02-20 06:23:48 +00:00
|
|
|
struct WaylandDSState
|
|
|
|
{
|
|
|
|
bool pointerGrabbed;
|
|
|
|
bool keyboardGrabbed;
|
2021-03-06 22:17:11 +00:00
|
|
|
bool pointerInSurface;
|
|
|
|
bool focusedOnSurface;
|
2021-02-20 06:23:48 +00:00
|
|
|
|
|
|
|
struct wl_display * display;
|
|
|
|
struct wl_surface * surface;
|
|
|
|
struct wl_registry * registry;
|
|
|
|
struct wl_seat * seat;
|
|
|
|
struct wl_shm * shm;
|
|
|
|
struct wl_compositor * compositor;
|
|
|
|
|
2021-02-21 05:10:08 +00:00
|
|
|
int32_t width, height, scale;
|
|
|
|
bool needsResize;
|
2021-02-20 06:23:48 +00:00
|
|
|
bool fullscreen;
|
|
|
|
uint32_t resizeSerial;
|
|
|
|
bool configured;
|
|
|
|
bool warpSupport;
|
|
|
|
double cursorX, cursorY;
|
|
|
|
|
2021-05-11 20:49:39 +00:00
|
|
|
#if defined(ENABLE_EGL) || defined(ENABLE_OPENGL)
|
2021-02-20 06:23:48 +00:00
|
|
|
struct wl_egl_window * eglWindow;
|
2021-05-11 20:49:39 +00:00
|
|
|
bool eglSwapWithDamageInit;
|
|
|
|
eglSwapBuffersWithDamageKHR_t eglSwapWithDamage;
|
|
|
|
EGLint * eglDamageRects;
|
|
|
|
int eglDamageRectCount;
|
2021-02-20 06:23:48 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef ENABLE_OPENGL
|
|
|
|
EGLDisplay glDisplay;
|
|
|
|
EGLConfig glConfig;
|
|
|
|
EGLSurface glSurface;
|
|
|
|
#endif
|
|
|
|
|
2021-03-06 12:09:44 +00:00
|
|
|
#ifdef ENABLE_LIBDECOR
|
|
|
|
struct libdecor * libdecor;
|
|
|
|
struct libdecor_frame * libdecorFrame;
|
|
|
|
#else
|
2021-02-20 06:23:48 +00:00
|
|
|
struct xdg_wm_base * xdgWmBase;
|
|
|
|
struct xdg_surface * xdgSurface;
|
|
|
|
struct xdg_toplevel * xdgToplevel;
|
|
|
|
struct zxdg_decoration_manager_v1 * xdgDecorationManager;
|
|
|
|
struct zxdg_toplevel_decoration_v1 * xdgToplevelDecoration;
|
2021-03-06 12:09:44 +00:00
|
|
|
#endif
|
2021-02-20 06:23:48 +00:00
|
|
|
|
|
|
|
struct wl_surface * cursor;
|
2021-04-06 00:06:49 +00:00
|
|
|
struct wl_buffer * cursorBuffer;
|
2021-02-20 06:23:48 +00:00
|
|
|
|
|
|
|
struct wl_data_device_manager * dataDeviceManager;
|
|
|
|
|
|
|
|
uint32_t capabilities;
|
|
|
|
|
|
|
|
struct wl_keyboard * keyboard;
|
|
|
|
struct zwp_keyboard_shortcuts_inhibit_manager_v1 * keyboardInhibitManager;
|
|
|
|
struct zwp_keyboard_shortcuts_inhibitor_v1 * keyboardInhibitor;
|
|
|
|
uint32_t keyboardEnterSerial;
|
|
|
|
|
|
|
|
struct wl_pointer * pointer;
|
|
|
|
struct zwp_relative_pointer_manager_v1 * relativePointerManager;
|
|
|
|
struct zwp_pointer_constraints_v1 * pointerConstraints;
|
|
|
|
struct zwp_relative_pointer_v1 * relativePointer;
|
|
|
|
struct zwp_confined_pointer_v1 * confinedPointer;
|
2021-05-04 00:37:01 +00:00
|
|
|
struct zwp_locked_pointer_v1 * lockedPointer;
|
2021-02-20 06:23:48 +00:00
|
|
|
bool showPointer;
|
|
|
|
uint32_t pointerEnterSerial;
|
|
|
|
|
|
|
|
struct zwp_idle_inhibit_manager_v1 * idleInhibitManager;
|
|
|
|
struct zwp_idle_inhibitor_v1 * idleInhibitor;
|
|
|
|
|
2021-02-21 03:48:48 +00:00
|
|
|
struct wl_list outputs; // WaylandOutput::link
|
2021-02-21 05:10:08 +00:00
|
|
|
struct wl_list surfaceOutputs; // SurfaceOutput::link
|
2021-02-21 03:48:48 +00:00
|
|
|
|
2021-02-20 06:23:48 +00:00
|
|
|
struct wl_list poll; // WaylandPoll::link
|
|
|
|
struct wl_list pollFree; // WaylandPoll::link
|
|
|
|
LG_Lock pollLock;
|
|
|
|
LG_Lock pollFreeLock;
|
|
|
|
int epollFd;
|
|
|
|
int displayFd;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct WCBTransfer
|
|
|
|
{
|
|
|
|
struct CountedBuffer * data;
|
|
|
|
const char ** mimetypes;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ClipboardRead
|
|
|
|
{
|
|
|
|
int fd;
|
|
|
|
size_t size;
|
|
|
|
size_t numRead;
|
|
|
|
uint8_t * buf;
|
|
|
|
enum LG_ClipboardData type;
|
|
|
|
struct wl_data_offer * offer;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct WCBState
|
|
|
|
{
|
|
|
|
struct wl_data_device * dataDevice;
|
|
|
|
char lgMimetype[64];
|
|
|
|
|
|
|
|
enum LG_ClipboardData pendingType;
|
|
|
|
char * pendingMimetype;
|
|
|
|
bool isSelfCopy;
|
|
|
|
|
|
|
|
enum LG_ClipboardData stashedType;
|
|
|
|
uint8_t * stashedContents;
|
|
|
|
ssize_t stashedSize;
|
|
|
|
|
|
|
|
bool haveRequest;
|
|
|
|
LG_ClipboardData type;
|
|
|
|
|
|
|
|
struct ClipboardRead * currentRead;
|
|
|
|
};
|
|
|
|
|
|
|
|
extern struct WaylandDSState wlWm;
|
|
|
|
extern struct WCBState wlCb;
|
|
|
|
|
|
|
|
// clipboard module
|
|
|
|
bool waylandCBInit(void);
|
|
|
|
void waylandCBRequest(LG_ClipboardData type);
|
|
|
|
void waylandCBNotice(LG_ClipboardData type);
|
|
|
|
void waylandCBRelease(void);
|
|
|
|
|
|
|
|
// cursor module
|
|
|
|
bool waylandCursorInit(void);
|
2021-04-06 00:06:49 +00:00
|
|
|
void waylandCursorFree(void);
|
2021-02-20 06:23:48 +00:00
|
|
|
void waylandShowPointer(bool show);
|
|
|
|
|
|
|
|
// gl module
|
|
|
|
#if defined(ENABLE_EGL) || defined(ENABLE_OPENGL)
|
|
|
|
bool waylandEGLInit(int w, int h);
|
|
|
|
EGLDisplay waylandGetEGLDisplay(void);
|
2021-05-11 20:49:39 +00:00
|
|
|
void waylandEGLSwapBuffers(EGLDisplay display, EGLSurface surface, const struct Rect * damage, int count);
|
2021-02-20 06:23:48 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef ENABLE_EGL
|
|
|
|
EGLNativeWindowType waylandGetEGLNativeWindow(void);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef ENABLE_OPENGL
|
|
|
|
bool waylandOpenGLInit(void);
|
|
|
|
LG_DSGLContext waylandGLCreateContext(void);
|
|
|
|
void waylandGLDeleteContext(LG_DSGLContext context);
|
|
|
|
void waylandGLMakeCurrent(LG_DSGLContext context);
|
|
|
|
void waylandGLSetSwapInterval(int interval);
|
|
|
|
void waylandGLSwapBuffers(void);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// idle module
|
|
|
|
bool waylandIdleInit(void);
|
|
|
|
void waylandIdleFree(void);
|
|
|
|
void waylandInhibitIdle(void);
|
|
|
|
void waylandUninhibitIdle(void);
|
|
|
|
|
|
|
|
// input module
|
|
|
|
bool waylandInputInit(void);
|
|
|
|
void waylandInputFree(void);
|
|
|
|
void waylandGrabKeyboard(void);
|
|
|
|
void waylandGrabPointer(void);
|
|
|
|
void waylandUngrabKeyboard(void);
|
|
|
|
void waylandUngrabPointer(void);
|
2021-05-04 00:16:51 +00:00
|
|
|
void waylandCapturePointer(void);
|
|
|
|
void waylandUncapturePointer(void);
|
2021-02-20 06:23:48 +00:00
|
|
|
void waylandRealignPointer(void);
|
|
|
|
void waylandWarpPointer(int x, int y, bool exiting);
|
2021-05-04 08:53:31 +00:00
|
|
|
void waylandGuestPointerUpdated(double x, double y, double localX, double localY);
|
2021-02-20 06:23:48 +00:00
|
|
|
|
2021-02-21 03:48:48 +00:00
|
|
|
// output module
|
|
|
|
bool waylandOutputInit(void);
|
|
|
|
void waylandOutputFree(void);
|
2021-02-25 00:44:49 +00:00
|
|
|
void waylandOutputBind(uint32_t name, uint32_t version);
|
2021-02-21 03:48:48 +00:00
|
|
|
void waylandOutputTryUnbind(uint32_t name);
|
|
|
|
int32_t waylandOutputGetScale(struct wl_output * output);
|
|
|
|
|
2021-02-20 06:23:48 +00:00
|
|
|
// poll module
|
|
|
|
bool waylandPollInit(void);
|
|
|
|
void waylandWait(unsigned int time);
|
2021-03-02 04:51:12 +00:00
|
|
|
bool waylandPollRegister(int fd, WaylandPollCallback callback, void * opaque, uint32_t events);
|
|
|
|
bool waylandPollUnregister(int fd);
|
2021-02-20 06:23:48 +00:00
|
|
|
|
|
|
|
// registry module
|
|
|
|
bool waylandRegistryInit(void);
|
|
|
|
void waylandRegistryFree(void);
|
|
|
|
|
2021-03-06 10:20:29 +00:00
|
|
|
// shell module
|
|
|
|
bool waylandShellInit(const char * title, bool fullscreen, bool maximize, bool borderless);
|
|
|
|
void waylandShellAckConfigureIfNeeded(void);
|
|
|
|
void waylandSetFullscreen(bool fs);
|
|
|
|
bool waylandGetFullscreen(void);
|
2021-05-06 12:25:38 +00:00
|
|
|
void waylandMinimize(void);
|
2021-03-06 10:20:29 +00:00
|
|
|
|
2021-02-20 06:23:48 +00:00
|
|
|
// window module
|
|
|
|
bool waylandWindowInit(const char * title, bool fullscreen, bool maximize, bool borderless);
|
|
|
|
void waylandWindowFree(void);
|
2021-02-22 07:19:03 +00:00
|
|
|
void waylandWindowUpdateScale(void);
|
2021-02-20 06:23:48 +00:00
|
|
|
void waylandSetWindowSize(int x, int y);
|
|
|
|
bool waylandIsValidPointerPos(int x, int y);
|