diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index e0607e17..c027fa3c 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -53,6 +53,10 @@ add_compile_options( set(EXE_FLAGS "-Wl,--gc-sections -z noexecstack") set(CMAKE_C_STANDARD 11) +if (ENABLE_EGL) + add_definitions(-D ENABLE_EGL) +endif() + if(ENABLE_ASAN) add_compile_options("-fno-omit-frame-pointer" "-fsanitize=address") set(EXE_FLAGS "${EXE_FLAGS} -fno-omit-frame-pointer -fsanitize=address") @@ -108,6 +112,7 @@ set(SOURCES src/util.c src/clipboard.c src/kb.c + src/egl_dynprocs.c ) add_subdirectory("${PROJECT_TOP}/common" "${CMAKE_BINARY_DIR}/common" ) diff --git a/client/displayservers/SDL/sdl.c b/client/displayservers/SDL/sdl.c index d697b473..05597e52 100644 --- a/client/displayservers/SDL/sdl.c +++ b/client/displayservers/SDL/sdl.c @@ -20,14 +20,27 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include "interface/displayserver.h" #include +#include + +#include + +#if defined(SDL_VIDEO_DRIVER_WAYLAND) +#include +#endif #include "app.h" #include "kb.h" +#include "egl_dynprocs.h" #include "common/types.h" #include "common/debug.h" struct SDLDSState { + SDL_Window * window; + SDL_Cursor * cursor; + + EGLNativeWindowType wlDisplay; + bool keyboardGrabbed; bool pointerGrabbed; bool exiting; @@ -35,14 +48,72 @@ struct SDLDSState static struct SDLDSState sdl; -static bool sdlEarlyInit(void) +/* forwards */ +static int sdlEventFilter(void * userdata, SDL_Event * event); + +static bool sdlProbe(void) { return true; } -static bool sdlInit(SDL_SysWMinfo * info) +static bool sdlEarlyInit(void) +{ + // Allow screensavers for now: we will enable and disable as needed. + SDL_SetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER, "1"); + + if (SDL_Init(SDL_INIT_VIDEO) < 0) + { + DEBUG_ERROR("SDL_Init Failed"); + return false; + } + + return true; +} + +static bool sdlInit(const LG_DSInitParams params) { memset(&sdl, 0, sizeof(sdl)); + + sdl.window = SDL_CreateWindow( + params.title, + params.center ? SDL_WINDOWPOS_CENTERED : params.x, + params.center ? SDL_WINDOWPOS_CENTERED : params.y, + params.w, + params.h, + ( + SDL_WINDOW_HIDDEN | + (params.resizable ? SDL_WINDOW_RESIZABLE : 0) | + (params.borderless ? SDL_WINDOW_BORDERLESS : 0) | + (params.maximize ? SDL_WINDOW_MAXIMIZED : 0) + ) + ); + + if (sdl.window == NULL) + { + DEBUG_ERROR("Could not create an SDL window: %s\n", SDL_GetError()); + return 1; + } + + const uint8_t data[4] = {0xf, 0x9, 0x9, 0xf}; + const uint8_t mask[4] = {0xf, 0xf, 0xf, 0xf}; + sdl.cursor = SDL_CreateCursor(data, mask, 8, 4, 4, 0); + SDL_SetCursor(sdl.cursor); + + SDL_ShowWindow(sdl.window); + + SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, + params.minimizeOnFocusLoss ? "1" : "0"); + + if (params.fullscreen) + SDL_SetWindowFullscreen(sdl.window, SDL_WINDOW_FULLSCREEN_DESKTOP); + + if (!params.center) + SDL_SetWindowPosition(sdl.window, params.x, params.y); + + // ensure mouse acceleration is identical in server mode + SDL_SetHintWithPriority(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, "1", SDL_HINT_OVERRIDE); + + SDL_SetEventFilter(sdlEventFilter, NULL); return true; } @@ -52,10 +123,17 @@ static void sdlStartup(void) static void sdlShutdown(void) { + SDL_DestroyWindow(sdl.window); } static void sdlFree(void) { + if (sdl.cursor) + SDL_FreeCursor(sdl.cursor); + + if (sdl.window) + SDL_DestroyWindow(sdl.window); + SDL_Quit(); } static bool sdlGetProp(LG_DSProperty prop, void * ret) @@ -63,25 +141,120 @@ static bool sdlGetProp(LG_DSProperty prop, void * ret) return false; } -static bool sdlEventFilter(SDL_Event * event) +#ifdef ENABLE_EGL +static EGLDisplay sdlGetEGLDisplay(void) +{ + SDL_SysWMinfo wminfo; + SDL_VERSION(&wminfo.version); + if (!SDL_GetWindowWMInfo(sdl.window, &wminfo)) + { + DEBUG_ERROR("SDL_GetWindowWMInfo failed"); + return EGL_NO_DISPLAY; + } + + EGLNativeDisplayType native; + EGLenum platform; + + switch(wminfo.subsystem) + { + case SDL_SYSWM_X11: + native = (EGLNativeDisplayType)wminfo.info.x11.display; + platform = EGL_PLATFORM_X11_KHR; + break; + +#if defined(SDL_VIDEO_DRIVER_WAYLAND) + case SDL_SYSWM_WAYLAND: + native = (EGLNativeDisplayType)wminfo.info.wl.display; + platform = EGL_PLATFORM_WAYLAND_KHR; + break; +#endif + + default: + DEBUG_ERROR("Unsupported subsystem"); + return EGL_NO_DISPLAY; + } + + const char *early_exts = eglQueryString(NULL, EGL_EXTENSIONS); + + if (strstr(early_exts, "EGL_KHR_platform_base") != NULL && + g_egl_dynProcs.eglGetPlatformDisplay) + { + DEBUG_INFO("Using eglGetPlatformDisplay"); + return g_egl_dynProcs.eglGetPlatformDisplay(platform, native, NULL); + } + + if (strstr(early_exts, "EGL_EXT_platform_base") != NULL && + g_egl_dynProcs.eglGetPlatformDisplayEXT) + { + DEBUG_INFO("Using eglGetPlatformDisplayEXT"); + return g_egl_dynProcs.eglGetPlatformDisplayEXT(platform, native, NULL); + } + + DEBUG_INFO("Using eglGetDisplay"); + return eglGetDisplay(native); +} + +static EGLNativeWindowType sdlGetEGLNativeWindow(void) +{ + SDL_SysWMinfo wminfo; + SDL_VERSION(&wminfo.version); + if (!SDL_GetWindowWMInfo(sdl.window, &wminfo)) + { + DEBUG_ERROR("SDL_GetWindowWMInfo failed"); + return 0; + } + + switch(wminfo.subsystem) + { + case SDL_SYSWM_X11: + return (EGLNativeWindowType)wminfo.info.x11.window; + +#if defined(SDL_VIDEO_DRIVER_WAYLAND) + case SDL_SYSWM_WAYLAND: + { + if (sdl.wlDisplay) + return sdl.wlDisplay; + + int width, height; + SDL_GetWindowSize(sdl.window, &width, &height); + sdl.wlDisplay = (EGLNativeWindowType)wl_egl_window_create( + wminfo.info.wl.surface, width, height); + + return sdl.wlDisplay; + } +#endif + + default: + DEBUG_ERROR("Unsupported subsystem"); + return 0; + } +} +#endif + +static void sdlSwapBuffers(void) +{ + SDL_GL_SwapWindow(sdl.window); +} + +static int sdlEventFilter(void * userdata, SDL_Event * event) { switch(event->type) { case SDL_QUIT: app_handleCloseEvent(); - return true; + break; case SDL_MOUSEMOTION: // stop motion events during the warp out of the window if (sdl.exiting) - return true; + break; app_updateCursorPos(event->motion.x, event->motion.y); if (app_cursorIsGrabbed()) app_handleMouseGrabbed(event->motion.xrel, event->motion.yrel); else app_handleMouseNormal(event->motion.xrel, event->motion.yrel); - return true; + break; case SDL_MOUSEBUTTONDOWN: { @@ -90,7 +263,7 @@ static bool sdlEventFilter(SDL_Event * event) button += 2; app_handleButtonPress(button); - return true; + break; } case SDL_MOUSEBUTTONUP: @@ -100,7 +273,7 @@ static bool sdlEventFilter(SDL_Event * event) button += 2; app_handleButtonRelease(button); - return true; + break; } case SDL_MOUSEWHEEL: @@ -108,7 +281,7 @@ static bool sdlEventFilter(SDL_Event * event) int button = event->wheel.y > 0 ? 4 : 5; app_handleButtonPress(button); app_handleButtonRelease(button); - return true; + break; } case SDL_KEYDOWN: @@ -130,27 +303,27 @@ static bool sdlEventFilter(SDL_Event * event) { case SDL_WINDOWEVENT_ENTER: app_handleEnterEvent(true); - return true; + break; case SDL_WINDOWEVENT_LEAVE: sdl.exiting = false; app_handleEnterEvent(false); - return true; + break; case SDL_WINDOWEVENT_FOCUS_GAINED: app_handleFocusEvent(true); - return true; + break; case SDL_WINDOWEVENT_FOCUS_LOST: app_handleFocusEvent(false); - return true; + break; case SDL_WINDOWEVENT_SIZE_CHANGED: case SDL_WINDOWEVENT_RESIZED: { struct Border border; SDL_GetWindowBordersSize( - app_getWindow(), + sdl.window, &border.top, &border.left, &border.bottom, @@ -159,21 +332,21 @@ static bool sdlEventFilter(SDL_Event * event) app_handleResizeEvent(event->window.data1, event->window.data2, border); - return true; + break; } case SDL_WINDOWEVENT_MOVED: app_updateWindowPos(event->window.data1, event->window.data2); - return true; + break; case SDL_WINDOWEVENT_CLOSE: app_handleCloseEvent(); - return true; + break; } break; } - return false; + return 0; } static void sdlShowPointer(bool show) @@ -183,14 +356,14 @@ static void sdlShowPointer(bool show) static void sdlGrabPointer(void) { - SDL_SetWindowGrab(app_getWindow(), SDL_TRUE); + SDL_SetWindowGrab(sdl.window, SDL_TRUE); SDL_SetRelativeMouseMode(SDL_TRUE); sdl.pointerGrabbed = true; } static void sdlUngrabPointer(void) { - SDL_SetWindowGrab(app_getWindow(), SDL_FALSE); + SDL_SetWindowGrab(sdl.window, SDL_FALSE); SDL_SetRelativeMouseMode(SDL_FALSE); sdl.pointerGrabbed = false; } @@ -198,7 +371,7 @@ static void sdlUngrabPointer(void) static void sdlGrabKeyboard(void) { if (sdl.pointerGrabbed) - SDL_SetWindowGrab(app_getWindow(), SDL_FALSE); + SDL_SetWindowGrab(sdl.window, SDL_FALSE); else { DEBUG_WARN("SDL does not support grabbing only the keyboard, grabbing all"); @@ -206,16 +379,16 @@ static void sdlGrabKeyboard(void) } SDL_SetHint(SDL_HINT_GRAB_KEYBOARD, "1"); - SDL_SetWindowGrab(app_getWindow(), SDL_TRUE); + SDL_SetWindowGrab(sdl.window, SDL_TRUE); sdl.keyboardGrabbed = true; } static void sdlUngrabKeyboard(void) { SDL_SetHint(SDL_HINT_GRAB_KEYBOARD, "0"); - SDL_SetWindowGrab(app_getWindow(), SDL_FALSE); + SDL_SetWindowGrab(sdl.window, SDL_FALSE); if (sdl.pointerGrabbed) - SDL_SetWindowGrab(app_getWindow(), SDL_TRUE); + SDL_SetWindowGrab(sdl.window, SDL_TRUE); sdl.keyboardGrabbed = false; } @@ -231,7 +404,7 @@ static void sdlWarpPointer(int x, int y, bool exiting) SDL_SetRelativeMouseMode(SDL_FALSE); // issue the warp - SDL_WarpMouseInWindow(app_getWindow(), x, y); + SDL_WarpMouseInWindow(sdl.window, x, y); } static void sdlRealignPointer(void) @@ -264,26 +437,51 @@ static void sdlUninhibitIdle(void) SDL_EnableScreenSaver(); } +static void sdlWait(unsigned int time) +{ + SDL_WaitEventTimeout(NULL, time); +} + +static void sdlSetWindowSize(int x, int y) +{ + SDL_SetWindowSize(sdl.window, x, y); +} + +static void sdlSetFullscreen(bool fs) +{ + SDL_SetWindowFullscreen(sdl.window, fs ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); +} + struct LG_DisplayServerOps LGDS_SDL = { - .subsystem = SDL_SYSWM_UNKNOWN, - .earlyInit = sdlEarlyInit, - .init = sdlInit, - .startup = sdlStartup, - .shutdown = sdlShutdown, - .free = sdlFree, - .getProp = sdlGetProp, - .eventFilter = sdlEventFilter, - .showPointer = sdlShowPointer, - .grabPointer = sdlGrabPointer, - .ungrabPointer = sdlUngrabPointer, - .grabKeyboard = sdlGrabKeyboard, - .ungrabKeyboard = sdlUngrabKeyboard, - .warpPointer = sdlWarpPointer, - .realignPointer = sdlRealignPointer, - .isValidPointerPos = sdlIsValidPointerPos, - .inhibitIdle = sdlInhibitIdle, - .uninhibitIdle = sdlUninhibitIdle, + .probe = sdlProbe, + .earlyInit = sdlEarlyInit, + .init = sdlInit, + .startup = sdlStartup, + .shutdown = sdlShutdown, + .free = sdlFree, + .getProp = sdlGetProp, + +#ifdef ENABLE_EGL + .getEGLDisplay = sdlGetEGLDisplay, + .getEGLNativeWindow = sdlGetEGLNativeWindow, +#endif + + .glSwapBuffers = sdlSwapBuffers, + + .showPointer = sdlShowPointer, + .grabPointer = sdlGrabPointer, + .ungrabPointer = sdlUngrabPointer, + .grabKeyboard = sdlGrabKeyboard, + .ungrabKeyboard = sdlUngrabKeyboard, + .warpPointer = sdlWarpPointer, + .realignPointer = sdlRealignPointer, + .isValidPointerPos = sdlIsValidPointerPos, + .inhibitIdle = sdlInhibitIdle, + .uninhibitIdle = sdlUninhibitIdle, + .wait = sdlWait, + .setWindowSize = sdlSetWindowSize, + .setFullscreen = sdlSetFullscreen, /* SDL does not have clipboard support */ .cbInit = NULL, diff --git a/client/displayservers/Wayland/wayland.c b/client/displayservers/Wayland/wayland.c index d659ca7b..d56eb63b 100644 --- a/client/displayservers/Wayland/wayland.c +++ b/client/displayservers/Wayland/wayland.c @@ -343,7 +343,12 @@ static bool waylandEarlyInit(void) return true; } -static bool waylandInit(SDL_SysWMinfo * info) +static bool waylandProbe(void) +{ + return getenv("WAYLAND_DISPLAY") != NULL; +} + +static bool waylandInit(const LG_DSInitParams params) { memset(&wm, 0, sizeof(wm)); @@ -857,7 +862,7 @@ static void waylandCBRelease(void) struct LG_DisplayServerOps LGDS_Wayland = { - .subsystem = SDL_SYSWM_WAYLAND, + .probe = waylandProbe, .earlyInit = waylandEarlyInit, .init = waylandInit, .startup = waylandStartup, diff --git a/client/displayservers/X11/x11.c b/client/displayservers/X11/x11.c index 13809e64..9c3c30fe 100644 --- a/client/displayservers/X11/x11.c +++ b/client/displayservers/X11/x11.c @@ -88,7 +88,12 @@ static void x11CBSelectionIncr(const XPropertyEvent e); static void x11CBSelectionNotify(const XSelectionEvent e); static void x11CBXFixesSelectionNotify(const XFixesSelectionNotifyEvent e); -static bool x11Init(SDL_SysWMinfo * info) +static bool x11Probe(void) +{ + return getenv("DISPLAY") != NULL; +} + +static bool x11Init(const LG_DSInitParams params) { XIDeviceInfo *devinfo; int count; @@ -1107,7 +1112,7 @@ static void x11CBRequest(LG_ClipboardData type) struct LG_DisplayServerOps LGDS_X11 = { - .subsystem = SDL_SYSWM_X11, + .probe = x11Probe, .init = x11Init, .startup = x11Startup, .shutdown = x11Shutdown, diff --git a/client/include/app.h b/client/include/app.h index 8b7d3ec4..1ec3cd4e 100644 --- a/client/include/app.h +++ b/client/include/app.h @@ -35,9 +35,11 @@ typedef enum LG_MsgAlert } LG_MsgAlert; -SDL_Window * app_getWindow(void); - bool app_getProp(LG_DSProperty prop, void * ret); + +EGLNativeWindowType app_getEGLNativeWindow(void); +EGLDisplay app_getEGLDisplay(void); + bool app_inputEnabled(void); bool app_cursorIsGrabbed(void); bool app_cursorWantsRaw(void); @@ -56,6 +58,10 @@ void app_handleEnterEvent(bool entered); void app_handleFocusEvent(bool focused); void app_handleCloseEvent(void); +void app_setFullscreen(bool fs); + +void app_glSwapBuffers(void); + void app_clipboardRelease(void); void app_clipboardNotify(const LG_ClipboardData type, size_t size); void app_clipboardData(const LG_ClipboardData type, uint8_t * data, size_t size); @@ -93,4 +99,5 @@ void app_releaseKeybind(KeybindHandle * handle); */ void app_releaseAllKeybinds(void); + #endif diff --git a/client/renderers/EGL/dynprocs.h b/client/include/egl_dynprocs.h similarity index 90% rename from client/renderers/EGL/dynprocs.h rename to client/include/egl_dynprocs.h index 73b1aa83..a1912317 100644 --- a/client/renderers/EGL/dynprocs.h +++ b/client/include/egl_dynprocs.h @@ -17,7 +17,9 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include +#ifdef ENABLE_EGL + +#include #include typedef EGLDisplay (*eglGetPlatformDisplayEXT_t)(EGLenum platform, @@ -32,6 +34,10 @@ struct EGLDynProcs glEGLImageTargetTexture2DOES_t glEGLImageTargetTexture2DOES; }; -extern struct EGLDynProcs g_dynprocs; +extern struct EGLDynProcs g_egl_dynProcs; void egl_dynProcsInit(void); + +#else + #define egl_dynProcsInit(...) +#endif diff --git a/client/include/interface/decoder.h b/client/include/interface/decoder.h deleted file mode 100644 index a1b6ad39..00000000 --- a/client/include/interface/decoder.h +++ /dev/null @@ -1,75 +0,0 @@ -/* -Looking Glass - KVM FrameRelay (KVMFR) Client -Copyright (C) 2017-2019 Geoffrey McRae -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 -*/ - -#pragma once - -#include "renderer.h" - -#include -#include -#include - -#include - -typedef enum LG_OutFormat -{ - LG_OUTPUT_INVALID, - - LG_OUTPUT_BGRA, - LG_OUTPUT_RGBA, - LG_OUTPUT_RGBA10, - LG_OUTPUT_YUV420 -} -LG_OutFormat; - -typedef bool (* LG_DecoderCreate )(void ** opaque); -typedef void (* LG_DecoderDestroy )(void * opaque); -typedef bool (* LG_DecoderInitialize )(void * opaque, const LG_RendererFormat format, SDL_Window * window); -typedef void (* LG_DecoderDeInitialize )(void * opaque); -typedef LG_OutFormat (* LG_DecoderGetOutFormat )(void * opaque); -typedef unsigned int (* LG_DecoderGetFramePitch )(void * opaque); -typedef unsigned int (* LG_DecoderGetFrameStride)(void * opaque); -typedef bool (* LG_DecoderDecode )(void * opaque, const uint8_t * src, size_t srcSize); -typedef const uint8_t * (* LG_DecoderGetBuffer )(void * opaque); - -typedef bool (* LG_DecoderInitGLTexture )(void * opaque, GLenum target, GLuint texture, void ** ref); -typedef void (* LG_DecoderFreeGLTexture )(void * opaque, void * ref); -typedef bool (* LG_DecoderUpdateGLTexture)(void * opaque, void * ref); - -typedef struct LG_Decoder -{ - // mandatory support - const char * name; - LG_DecoderCreate create; - LG_DecoderDestroy destroy; - LG_DecoderInitialize initialize; - LG_DecoderDeInitialize deinitialize; - LG_DecoderGetOutFormat get_out_format; - LG_DecoderGetFramePitch get_frame_pitch; - LG_DecoderGetFrameStride get_frame_stride; - LG_DecoderDecode decode; - LG_DecoderGetBuffer get_buffer; - - // optional support - const bool has_gl; - LG_DecoderInitGLTexture init_gl_texture; - LG_DecoderFreeGLTexture free_gl_texture; - LG_DecoderUpdateGLTexture update_gl_texture; -} -LG_Decoder; \ No newline at end of file diff --git a/client/include/interface/displayserver.h b/client/include/interface/displayserver.h index c7120f0e..62f3b2f3 100644 --- a/client/include/interface/displayserver.h +++ b/client/include/interface/displayserver.h @@ -21,8 +21,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA #define _H_I_DISPLAYSERVER_ #include -#include -#include +#include typedef enum LG_ClipboardData { @@ -54,20 +53,34 @@ typedef enum LG_DSProperty } LG_DSProperty; +typedef struct LG_DSInitParams +{ + const char * title; + int x, y, w, h; + bool center; + bool fullscreen; + bool resizable; + bool borderless; + bool maximize; + bool minimizeOnFocusLoss; +} +LG_DSInitParams; + typedef void (* LG_ClipboardReplyFn)(void * opaque, const LG_ClipboardData type, uint8_t * data, uint32_t size); struct LG_DisplayServerOps { - const SDL_SYSWM_TYPE subsystem; + /* return true if the selected ds is valid for the current platform */ + bool (*probe)(void); - /* called before SDL has been initialized */ + /* called before anything has been initialized */ bool (*earlyInit)(void); - /* called after SDL has been initialized */ - bool (*init)(SDL_SysWMinfo * info); + /* called when it's time to create and show the application window */ + bool (*init)(const LG_DSInitParams params); - /* called at startup after window creation, renderer and/or SPICE is ready */ + /* called at startup after window creation, renderer and SPICE is ready */ void (*startup)(); /* called just before final window destruction, before final free */ @@ -83,8 +96,14 @@ struct LG_DisplayServerOps */ bool (*getProp)(LG_DSProperty prop, void * ret); - /* event filter, return true if the event has been handled */ - bool (*eventFilter)(SDL_Event * event); +#ifdef ENABLE_EGL + /* EGL support */ + EGLDisplay (*getEGLDisplay)(void); + EGLNativeWindowType (*getEGLNativeWindow)(void); +#endif + + /* opengl platform specific methods */ + void (*glSwapBuffers)(void); /* dm specific cursor implementations */ void (*showPointer)(bool show); @@ -108,6 +127,13 @@ struct LG_DisplayServerOps void (*inhibitIdle)(); void (*uninhibitIdle)(); + /* wait for the specified time without blocking UI processing/event loops */ + void (*wait)(unsigned int time); + + /* set the window dimensions */ + void (*setWindowSize)(int x, int y); + void (*setFullscreen)(bool fs); + /* clipboard support */ bool (*cbInit)(void); void (*cbNotice)(LG_ClipboardData type); diff --git a/client/include/interface/renderer.h b/client/include/interface/renderer.h index a0a5e88c..4a697b13 100644 --- a/client/include/interface/renderer.h +++ b/client/include/interface/renderer.h @@ -21,9 +21,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include #include -#include -#include - #include "app.h" #include "common/KVMFR.h" #include "common/framebuffer.h" @@ -107,7 +104,7 @@ typedef const char * (* LG_RendererGetName)(); typedef void (* LG_RendererSetup)(); typedef bool (* LG_RendererCreate )(void ** opaque, const LG_RendererParams params); -typedef bool (* LG_RendererInitialize )(void * opaque, Uint32 * sdlFlags); +typedef bool (* LG_RendererInitialize )(void * opaque); typedef void (* LG_RendererDeInitialize )(void * opaque); typedef bool (* LG_RendererSupports )(void * opaque, LG_RendererSupport support); typedef void (* LG_RendererOnRestart )(void * opaque); @@ -117,8 +114,8 @@ typedef bool (* LG_RendererOnMouseEvent )(void * opaque, const bool visi typedef bool (* LG_RendererOnFrameFormat)(void * opaque, const LG_RendererFormat format, bool useDMA); typedef bool (* LG_RendererOnFrame )(void * opaque, const FrameBuffer * frame, int dmaFD); typedef void (* LG_RendererOnAlert )(void * opaque, const LG_MsgAlert alert, const char * message, bool ** closeFlag); -typedef bool (* LG_RendererRenderStartup)(void * opaque, SDL_Window *window); -typedef bool (* LG_RendererRender )(void * opaque, SDL_Window *window, LG_RendererRotate rotate); +typedef bool (* LG_RendererRenderStartup)(void * opaque); +typedef bool (* LG_RendererRender )(void * opaque, LG_RendererRotate rotate); typedef void (* LG_RendererUpdateFPS )(void * opaque, const float avgUPS, const float avgFPS); typedef struct LG_Renderer diff --git a/client/renderers/EGL/CMakeLists.txt b/client/renderers/EGL/CMakeLists.txt index 6f75911e..3ecb4506 100644 --- a/client/renderers/EGL/CMakeLists.txt +++ b/client/renderers/EGL/CMakeLists.txt @@ -33,7 +33,6 @@ make_object( add_library(renderer_EGL STATIC egl.c - dynprocs.c egldebug.c shader.c texture.c diff --git a/client/renderers/EGL/egl.c b/client/renderers/EGL/egl.c index 4bb7ab2b..41d13299 100644 --- a/client/renderers/EGL/egl.c +++ b/client/renderers/EGL/egl.c @@ -27,17 +27,17 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include "util.h" #include "dynamic/fonts.h" -#include -#include +#include #if defined(SDL_VIDEO_DRIVER_WAYLAND) #include #endif #include +#include #include "app.h" -#include "dynprocs.h" +#include "egl_dynprocs.h" #include "model.h" #include "shader.h" #include "desktop.h" @@ -208,7 +208,7 @@ bool egl_create(void ** opaque, const LG_RendererParams params) return true; } -bool egl_initialize(void * opaque, Uint32 * sdlFlags) +bool egl_initialize(void * opaque) { struct Inst * this = (struct Inst *)opaque; DEBUG_INFO("Double buffering is %s", this->opt.doubleBuffer ? "on" : "off"); @@ -482,73 +482,17 @@ void egl_on_alert(void * opaque, const LG_MsgAlert alert, const char * message, this->showAlert = true; } -bool egl_render_startup(void * opaque, SDL_Window * window) +bool egl_render_startup(void * opaque) { struct Inst * this = (struct Inst *)opaque; - SDL_SysWMinfo wminfo; - SDL_VERSION(&wminfo.version); - if (!SDL_GetWindowWMInfo(window, &wminfo)) - { - DEBUG_ERROR("SDL_GetWindowWMInfo failed"); + this->nativeWind = app_getEGLNativeWindow(); + if (!this->nativeWind) return false; - } - - egl_dynProcsInit(); - - EGLNativeDisplayType native; - EGLenum platform; - - switch(wminfo.subsystem) - { - case SDL_SYSWM_X11: - native = (EGLNativeDisplayType)wminfo.info.x11.display; - platform = EGL_PLATFORM_X11_KHR; - this->nativeWind = (EGLNativeWindowType)wminfo.info.x11.window; - break; - -#if defined(SDL_VIDEO_DRIVER_WAYLAND) - case SDL_SYSWM_WAYLAND: - { - int width, height; - SDL_GetWindowSize(window, &width, &height); - native = (EGLNativeDisplayType)wminfo.info.wl.display; - platform = EGL_PLATFORM_WAYLAND_KHR; - this->nativeWind = (EGLNativeWindowType)wl_egl_window_create( - wminfo.info.wl.surface, width, height); - break; - } -#endif - - default: - DEBUG_ERROR("Unsupported subsystem"); - return false; - } - - const char *early_exts = eglQueryString(NULL, EGL_EXTENSIONS); - if (strstr(early_exts, "EGL_KHR_platform_base") != NULL && - g_dynprocs.eglGetPlatformDisplay) - { - DEBUG_INFO("Using eglGetPlatformDisplay"); - this->display = g_dynprocs.eglGetPlatformDisplay(platform, native, NULL); - } - else if (strstr(early_exts, "EGL_EXT_platform_base") != NULL && - g_dynprocs.eglGetPlatformDisplayEXT) - { - DEBUG_INFO("Using eglGetPlatformDisplayEXT"); - this->display = g_dynprocs.eglGetPlatformDisplayEXT(platform, native, NULL); - } - else - { - DEBUG_INFO("Using eglGetDisplay"); - this->display = eglGetDisplay(native); - } + this->display = app_getEGLDisplay(); if (this->display == EGL_NO_DISPLAY) - { - DEBUG_ERROR("eglGetDisplay failed"); return false; - } int maj, min; if (!eglInitialize(this->display, &maj, &min)) @@ -639,7 +583,7 @@ bool egl_render_startup(void * opaque, SDL_Window * window) DEBUG_INFO("EGL APIs : %s", eglQueryString(this->display, EGL_CLIENT_APIS)); DEBUG_INFO("Extensions: %s", client_exts); - if (g_dynprocs.glEGLImageTargetTexture2DOES) + if (g_egl_dynProcs.glEGLImageTargetTexture2DOES) { if (strstr(client_exts, "EGL_EXT_image_dma_buf_import") != NULL) { @@ -697,7 +641,7 @@ bool egl_render_startup(void * opaque, SDL_Window * window) return true; } -bool egl_render(void * opaque, SDL_Window * window, LG_RendererRotate rotate) +bool egl_render(void * opaque, LG_RendererRotate rotate) { struct Inst * this = (struct Inst *)opaque; diff --git a/client/renderers/EGL/texture.c b/client/renderers/EGL/texture.c index 0715c9ca..e84a2c4d 100644 --- a/client/renderers/EGL/texture.c +++ b/client/renderers/EGL/texture.c @@ -20,7 +20,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include "texture.h" #include "common/debug.h" #include "common/framebuffer.h" -#include "dynprocs.h" +#include "egl_dynprocs.h" #include "egldebug.h" #include @@ -393,7 +393,7 @@ bool egl_texture_update_from_dma(EGL_Texture * texture, const FrameBuffer * fram /* bind the texture and initiate the transfer */ glBindTexture(GL_TEXTURE_2D, texture->tex); - g_dynprocs.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); + g_egl_dynProcs.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); /* wait for completion */ framebuffer_wait(frame, texture->height * texture->stride); diff --git a/client/renderers/OpenGL/opengl.c b/client/renderers/OpenGL/opengl.c index 5763f7eb..d4e8930d 100644 --- a/client/renderers/OpenGL/opengl.c +++ b/client/renderers/OpenGL/opengl.c @@ -177,7 +177,7 @@ enum ConfigStatus }; static void deconfigure(struct Inst * this); -static enum ConfigStatus configure(struct Inst * this, SDL_Window *window); +static enum ConfigStatus configure(struct Inst * this); static void update_mouse_shape(struct Inst * this, bool * newShape); static bool draw_frame(struct Inst * this); static void draw_mouse(struct Inst * this); @@ -235,8 +235,11 @@ bool opengl_create(void ** opaque, const LG_RendererParams params) return true; } -bool opengl_initialize(void * opaque, Uint32 * sdlFlags) +bool opengl_initialize(void * opaque) { + //FIXME + return false; +#if 0 struct Inst * this = (struct Inst *)opaque; if (!this) return false; @@ -252,6 +255,7 @@ bool opengl_initialize(void * opaque, Uint32 * sdlFlags) SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE , 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE , 8); return true; +#endif } void opengl_deinitialize(void * opaque) @@ -492,16 +496,17 @@ void bitmap_to_texture(LG_FontBitmap * bitmap, GLuint texture) glBindTexture(GL_TEXTURE_2D, 0); } -bool opengl_render_startup(void * opaque, SDL_Window * window) +bool opengl_render_startup(void * opaque) { + //FIXME + return false; +#if 0 + struct Inst * this = (struct Inst *)opaque; - this->glContext = SDL_GL_CreateContext(window); + this->glContext = app_getGLContext(); if (!this->glContext) - { - DEBUG_ERROR("Failed to create the OpenGL context"); return false; - } DEBUG_INFO("Vendor : %s", glGetString(GL_VENDOR )); DEBUG_INFO("Renderer: %s", glGetString(GL_RENDERER)); @@ -549,15 +554,16 @@ bool opengl_render_startup(void * opaque, SDL_Window * window) SDL_GL_SetSwapInterval(this->opt.vsync ? 1 : 0); this->renderStarted = true; return true; +#endif } -bool opengl_render(void * opaque, SDL_Window * window, LG_RendererRotate rotate) +bool opengl_render(void * opaque, LG_RendererRotate rotate) { struct Inst * this = (struct Inst *)opaque; if (!this) return false; - switch(configure(this, window)) + switch(configure(this)) { case CONFIG_STATUS_ERROR: DEBUG_ERROR("configure failed"); @@ -657,11 +663,11 @@ bool opengl_render(void * opaque, SDL_Window * window, LG_RendererRotate rotate) if (this->opt.preventBuffer) { - SDL_GL_SwapWindow(window); + app_glSwapBuffers(); glFinish(); } else - SDL_GL_SwapWindow(window); + app_glSwapBuffers(); this->mouseUpdate = false; return true; @@ -879,7 +885,7 @@ static bool _check_gl_error(unsigned int line, const char * name) return true; } -static enum ConfigStatus configure(struct Inst * this, SDL_Window *window) +static enum ConfigStatus configure(struct Inst * this) { LG_LOCK(this->formatLock); if (!this->reconfigure) diff --git a/client/src/app.c b/client/src/app.c index 1c032fe4..1c27fcd8 100644 --- a/client/src/app.c +++ b/client/src/app.c @@ -28,7 +28,10 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include "kb.h" #include "common/debug.h" + #include +#include +#include void app_alert(LG_MsgAlert type, const char * fmt, ...) { @@ -98,9 +101,14 @@ bool app_getProp(LG_DSProperty prop, void * ret) return g_state.ds->getProp(prop, ret); } -SDL_Window * app_getWindow(void) +EGLNativeWindowType app_getEGLNativeWindow(void) { - return g_state.window; + return g_state.ds->getEGLNativeWindow(); +} + +EGLDisplay app_getEGLDisplay(void) +{ + return g_state.ds->getEGLDisplay(); } bool app_inputEnabled(void) @@ -280,7 +288,7 @@ void app_handleButtonPress(int button) g_cursor.buttons |= (1U << button); if (!spice_mouse_press(button)) - DEBUG_ERROR("SDL_MOUSEBUTTONDOWN: failed to send message"); + DEBUG_ERROR("app_handleButtonPress: failed to send message"); } void app_handleButtonRelease(int button) @@ -291,7 +299,7 @@ void app_handleButtonRelease(int button) g_cursor.buttons &= ~(1U << button); if (!spice_mouse_release(button)) - DEBUG_ERROR("SDL_MOUSEBUTTONUP: failed to send message"); + DEBUG_ERROR("app_handleButtonRelease: failed to send message"); } void app_handleKeyPress(int sc) @@ -325,7 +333,7 @@ void app_handleKeyPress(int sc) g_state.keyDown[sc] = true; else { - DEBUG_ERROR("SDL_KEYDOWN: failed to send message"); + DEBUG_ERROR("app_handleKeyPress: failed to send message"); return; } } @@ -372,7 +380,7 @@ void app_handleKeyRelease(int sc) g_state.keyDown[sc] = false; else { - DEBUG_ERROR("SDL_KEYUP: failed to send message"); + DEBUG_ERROR("app_handleKeyRelease: failed to send message"); return; } } @@ -613,3 +621,13 @@ void app_handleCloseEvent(void) if (!g_params.ignoreQuit || !g_cursor.inView) g_state.state = APP_STATE_SHUTDOWN; } + +void app_setFullscreen(bool fs) +{ + g_state.ds->setFullscreen(fs); +} + +void app_glSwapBuffers(void) +{ + g_state.ds->glSwapBuffers(); +} diff --git a/client/src/config.c b/client/src/config.c index 594a2d94..552a3199 100644 --- a/client/src/config.c +++ b/client/src/config.c @@ -19,6 +19,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include "main.h" #include "config.h" +#include "kb.h" + #include "common/option.h" #include "common/debug.h" #include "common/stringutils.h" @@ -26,10 +28,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include #include #include - -//FIXME: this should really not be included here and is an ugly hack to retain -//backwards compatibility with the escape key scancode -extern uint32_t sdl_to_xfree86[]; +#include // forwards static bool optRendererParse (struct Option * opt, const char * str); @@ -41,6 +40,7 @@ static char * optPosToString (struct Option * opt); static bool optSizeParse (struct Option * opt, const char * str); static StringList optSizeValues (struct Option * opt); static char * optSizeToString (struct Option * opt); +static bool optScancodeValidate(struct Option * opt, const char ** error); static char * optScancodeToString(struct Option * opt); static bool optRotateValidate (struct Option * opt, const char ** error); @@ -267,11 +267,12 @@ static struct Option options[] = { .module = "input", .name = "escapeKey", - .description = "Specify the escape key, see https://wiki.libsdl.org/SDLScancodeLookup for valid values", + .description = "Specify the escape key, see for valid values", .shortopt = 'm', .type = OPTION_TYPE_INT, - .value.x_int = SDL_SCANCODE_SCROLLLOCK, - .toString = optScancodeToString + .value.x_int = KEY_SCROLLLOCK, + .validator = optScancodeValidate, + .toString = optScancodeToString, }, { .module = "input", @@ -532,9 +533,6 @@ bool config_load(int argc, char * argv[]) g_params.alwaysShowCursor = option_get_bool("spice", "alwaysShowCursor"); } - //FIXME, this should be using linux keycodes - g_params.escapeKey = sdl_to_xfree86[g_params.escapeKey]; - return true; } @@ -682,11 +680,20 @@ static char * optSizeToString(struct Option * opt) return str; } +static bool optScancodeValidate(struct Option * opt, const char ** error) +{ + if (opt->value.x_int >= 0 && opt->value.x_int < KEY_MAX) + return true; + + *error = "Out of range"; + return false; +} + static char * optScancodeToString(struct Option * opt) { char * str; alloc_sprintf(&str, "%d = %s", opt->value.x_int, - SDL_GetScancodeName(opt->value.x_int)); + xfree86_to_str[opt->value.x_int]); return str; } diff --git a/client/src/core.c b/client/src/core.c index 85bff942..6233cb35 100644 --- a/client/src/core.c +++ b/client/src/core.c @@ -26,6 +26,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include "common/debug.h" #include +#include #define RESIZE_TIMEOUT (10 * 1000) // 10ms diff --git a/client/renderers/EGL/dynprocs.c b/client/src/egl_dynprocs.c similarity index 76% rename from client/renderers/EGL/dynprocs.c rename to client/src/egl_dynprocs.c index 44079f4b..f99783ba 100644 --- a/client/renderers/EGL/dynprocs.c +++ b/client/src/egl_dynprocs.c @@ -17,16 +17,20 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "dynprocs.h" +#ifdef ENABLE_EGL -struct EGLDynProcs g_dynprocs = {0}; +#include "egl_dynprocs.h" + +struct EGLDynProcs g_egl_dynProcs = {0}; void egl_dynProcsInit(void) { - g_dynprocs.eglGetPlatformDisplay = (eglGetPlatformDisplayEXT_t) + g_egl_dynProcs.eglGetPlatformDisplay = (eglGetPlatformDisplayEXT_t) eglGetProcAddress("eglGetPlatformDisplay"); - g_dynprocs.eglGetPlatformDisplayEXT = (eglGetPlatformDisplayEXT_t) + g_egl_dynProcs.eglGetPlatformDisplayEXT = (eglGetPlatformDisplayEXT_t) eglGetProcAddress("eglGetPlatformDisplayEXT"); - g_dynprocs.glEGLImageTargetTexture2DOES = (glEGLImageTargetTexture2DOES_t) + g_egl_dynProcs.glEGLImageTargetTexture2DOES = (glEGLImageTargetTexture2DOES_t) eglGetProcAddress("glEGLImageTargetTexture2DOES"); }; + +#endif diff --git a/client/src/kb.c b/client/src/kb.c index af9e34f6..b30a3601 100644 --- a/client/src/kb.c +++ b/client/src/kb.c @@ -145,4 +145,127 @@ const uint32_t xfree86_to_ps2[KEY_MAX] = [KEY_PRINT] /* = USB 70 */ = 0x00E037, }; +const char * xfree86_to_str[KEY_MAX] = +{ + [KEY_RESERVED] = "KEY_RESERVED", + [KEY_ESC] = "KEY_ESC", + [KEY_1] = "KEY_1", + [KEY_2] = "KEY_2", + [KEY_3] = "KEY_3", + [KEY_4] = "KEY_4", + [KEY_5] = "KEY_5", + [KEY_6] = "KEY_6", + [KEY_7] = "KEY_7", + [KEY_8] = "KEY_8", + [KEY_9] = "KEY_9", + [KEY_0] = "KEY_0", + [KEY_MINUS] = "KEY_MINUS", + [KEY_EQUAL] = "KEY_EQUAL", + [KEY_BACKSPACE] = "KEY_BACKSPACE", + [KEY_TAB] = "KEY_TAB", + [KEY_Q] = "KEY_Q", + [KEY_W] = "KEY_W", + [KEY_E] = "KEY_E", + [KEY_R] = "KEY_R", + [KEY_T] = "KEY_T", + [KEY_Y] = "KEY_Y", + [KEY_U] = "KEY_U", + [KEY_I] = "KEY_I", + [KEY_O] = "KEY_O", + [KEY_P] = "KEY_P", + [KEY_LEFTBRACE] = "KEY_LEFTBRACE", + [KEY_RIGHTBRACE] = "KEY_RIGHTBRACE", + [KEY_ENTER] = "KEY_ENTER", + [KEY_LEFTCTRL] = "KEY_LEFTCTRL", + [KEY_A] = "KEY_A", + [KEY_S] = "KEY_S", + [KEY_D] = "KEY_D", + [KEY_F] = "KEY_F", + [KEY_G] = "KEY_G", + [KEY_H] = "KEY_H", + [KEY_J] = "KEY_J", + [KEY_K] = "KEY_K", + [KEY_L] = "KEY_L", + [KEY_SEMICOLON] = "KEY_SEMICOLON", + [KEY_APOSTROPHE] = "KEY_APOSTROPHE", + [KEY_GRAVE] = "KEY_GRAVE", + [KEY_LEFTSHIFT] = "KEY_LEFTSHIFT", + [KEY_BACKSLASH] = "KEY_BACKSLASH", + [KEY_Z] = "KEY_Z", + [KEY_X] = "KEY_X", + [KEY_C] = "KEY_C", + [KEY_V] = "KEY_V", + [KEY_B] = "KEY_B", + [KEY_N] = "KEY_N", + [KEY_M] = "KEY_M", + [KEY_COMMA] = "KEY_COMMA", + [KEY_DOT] = "KEY_DOT", + [KEY_SLASH] = "KEY_SLASH", + [KEY_RIGHTSHIFT] = "KEY_RIGHTSHIFT", + [KEY_KPASTERISK] = "KEY_KPASTERISK", + [KEY_LEFTALT] = "KEY_LEFTALT", + [KEY_SPACE] = "KEY_SPACE", + [KEY_CAPSLOCK] = "KEY_CAPSLOCK", + [KEY_F1] = "KEY_F1", + [KEY_F2] = "KEY_F2", + [KEY_F3] = "KEY_F3", + [KEY_F4] = "KEY_F4", + [KEY_F5] = "KEY_F5", + [KEY_F6] = "KEY_F6", + [KEY_F7] = "KEY_F7", + [KEY_F8] = "KEY_F8", + [KEY_F9] = "KEY_F9", + [KEY_F10] = "KEY_F10", + [KEY_NUMLOCK] = "KEY_NUMLOCK", + [KEY_SCROLLLOCK] = "KEY_SCROLLLOCK", + [KEY_KP7] = "KEY_KP7", + [KEY_KP8] = "KEY_KP8", + [KEY_KP9] = "KEY_KP9", + [KEY_KPMINUS] = "KEY_KPMINUS", + [KEY_KP4] = "KEY_KP4", + [KEY_KP5] = "KEY_KP5", + [KEY_KP6] = "KEY_KP6", + [KEY_KPPLUS] = "KEY_KPPLUS", + [KEY_KP1] = "KEY_KP1", + [KEY_KP2] = "KEY_KP2", + [KEY_KP3] = "KEY_KP3", + [KEY_KP0] = "KEY_KP0", + [KEY_KPDOT] = "KEY_KPDOT", + [KEY_102ND] = "KEY_102ND", + [KEY_F11] = "KEY_F11", + [KEY_F12] = "KEY_F12", + [KEY_RO] = "KEY_RO", + [KEY_HENKAN] = "KEY_HENKAN", + [KEY_KATAKANAHIRAGANA] = "KEY_KATAKANAHIRAGANA", + [KEY_MUHENKAN] = "KEY_MUHENKAN", + [KEY_KPENTER] = "KEY_KPENTER", + [KEY_RIGHTCTRL] = "KEY_RIGHTCTRL", + [KEY_KPSLASH] = "KEY_KPSLASH", + [KEY_SYSRQ] = "KEY_SYSRQ", + [KEY_RIGHTALT] = "KEY_RIGHTALT", + [KEY_HOME] = "KEY_HOME", + [KEY_UP] = "KEY_UP", + [KEY_PAGEUP] = "KEY_PAGEUP", + [KEY_LEFT] = "KEY_LEFT", + [KEY_RIGHT] = "KEY_RIGHT", + [KEY_END] = "KEY_END", + [KEY_DOWN] = "KEY_DOWN", + [KEY_PAGEDOWN] = "KEY_PAGEDOWN", + [KEY_INSERT] = "KEY_INSERT", + [KEY_DELETE] = "KEY_DELETE", + [KEY_KPEQUAL] = "KEY_KPEQUAL", + [KEY_PAUSE] = "KEY_PAUSE", + [KEY_KPCOMMA] = "KEY_KPCOMMA", + [KEY_HANGEUL] = "KEY_HANGEUL", + [KEY_HANJA] = "KEY_HANJA", + [KEY_YEN] = "KEY_YEN", + [KEY_LEFTMETA] = "KEY_LEFTMETA", + [KEY_RIGHTMETA] = "KEY_RIGHTMETA", + [KEY_COMPOSE] = "KEY_COMPOSE", + [KEY_F13] = "KEY_F13", + [KEY_F14] = "KEY_F14", + [KEY_F15] = "KEY_F15", + [KEY_PRINT] = "KEY_PRINT", +}; + #endif diff --git a/client/src/kb.h b/client/src/kb.h index a00ba2c3..1a3fe9d0 100644 --- a/client/src/kb.h +++ b/client/src/kb.h @@ -21,3 +21,4 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include extern const uint32_t xfree86_to_ps2[KEY_MAX]; +extern const char * xfree86_to_str[KEY_MAX]; diff --git a/client/src/keybind.c b/client/src/keybind.c index 2103abb1..4004e7a1 100644 --- a/client/src/keybind.c +++ b/client/src/keybind.c @@ -26,10 +26,12 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include "spice/spice.h" +#include + static void bind_fullscreen(int sc, void * opaque) { - SDL_SetWindowFullscreen(g_state.window, g_params.fullscreen ? 0 : SDL_WINDOW_FULLSCREEN_DESKTOP); g_params.fullscreen = !g_params.fullscreen; + app_setFullscreen(g_params.fullscreen); } static void bind_video(int sc, void * opaque) diff --git a/client/src/main.c b/client/src/main.c index d529e044..67199b88 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -22,7 +22,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include #include -#include #include #include #include @@ -53,6 +52,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include "keybind.h" #include "clipboard.h" #include "ll.h" +#include "egl_dynprocs.h" // forwards static int cursorThread(void * unused); @@ -63,7 +63,6 @@ static LGEvent *e_frame = NULL; static LGThread *t_spice = NULL; static LGThread *t_render = NULL; static LGThread *t_cursor = NULL; -static SDL_Cursor *cursor = NULL; struct AppState g_state; struct CursorState g_cursor; @@ -89,14 +88,14 @@ static void lgInit(void) // if spice is not in use, hide the local cursor if (!app_inputEnabled() && g_params.hideMouse) - SDL_ShowCursor(SDL_DISABLE); + g_state.ds->showPointer(false); else - SDL_ShowCursor(SDL_ENABLE); + g_state.ds->showPointer(true); } static int renderThread(void * unused) { - if (!g_state.lgr->render_startup(g_state.lgrData, g_state.window)) + if (!g_state.lgr->render_startup(g_state.lgrData)) { g_state.state = APP_STATE_SHUTDOWN; @@ -129,7 +128,7 @@ static int renderThread(void * unused) atomic_compare_exchange_weak(&g_state.lgrResize, &resize, 0); } - if (!g_state.lgr->render(g_state.lgrData, g_state.window, g_params.winRotate)) + if (!g_state.lgr->render(g_state.lgrData, g_params.winRotate)) break; if (g_params.showFPS) @@ -158,8 +157,7 @@ static int renderThread(void * unused) if (!g_state.resizeDone && g_state.resizeTimeout < microtime()) { - SDL_SetWindowSize( - g_state.window, + g_state.ds->setWindowSize( g_state.dstRect.w, g_state.dstRect.h ); @@ -347,7 +345,6 @@ int main_frameThread(void * unused) if (useDMA) DEBUG_INFO("Using DMA buffer support"); - SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH); lgWaitEvent(e_startup, TIMEOUT_INFINITE); if (g_state.state != APP_STATE_RUNNING) return 0; @@ -404,7 +401,7 @@ int main_frameThread(void * unused) break; } - KVMFRFrame * frame = (KVMFRFrame *)msg.mem; + KVMFRFrame * frame = (KVMFRFrame *)msg.mem; struct DMAFrameInfo *dma = NULL; if (!g_state.formatValid || frame->formatVer != formatVer) @@ -473,7 +470,7 @@ int main_frameThread(void * unused) g_state.srcSize.y = lgrFormat.height; g_state.haveSrcSize = true; if (g_params.autoResize) - SDL_SetWindowSize(g_state.window, lgrFormat.width, lgrFormat.height); + g_state.ds->setWindowSize(lgrFormat.width, lgrFormat.height); g_cursor.guest.dpiScale = frame->mouseScalePercent; core_updatePositionInfo(); @@ -572,20 +569,6 @@ int spiceThread(void * arg) return 0; } -int eventFilter(void * userdata, SDL_Event * event) -{ - if (g_state.ds->eventFilter(event)) - return 0; - - // always include the default handler (SDL) for any unhandled events - if (g_state.ds != LG_DisplayServers[0]) - if (LG_DisplayServers[0]->eventFilter(event)) - return 0; - - // consume all events - return 0; -} - void intHandler(int sig) { switch(sig) @@ -607,7 +590,7 @@ void intHandler(int sig) } } -static bool tryRenderer(const int index, const LG_RendererParams lgrParams, Uint32 * sdlFlags) +static bool tryRenderer(const int index, const LG_RendererParams lgrParams) { const LG_Renderer *r = LG_Renderers[index]; @@ -623,7 +606,7 @@ static bool tryRenderer(const int index, const LG_RendererParams lgrParams, Uint return false; // initialize the renderer - if (!r->initialize(g_state.lgrData, sdlFlags)) + if (!r->initialize(g_state.lgrData)) { r->deinitialize(g_state.lgrData); return false; @@ -633,14 +616,6 @@ static bool tryRenderer(const int index, const LG_RendererParams lgrParams, Uint return true; } -static void initSDLCursor(void) -{ - const uint8_t data[4] = {0xf, 0x9, 0x9, 0xf}; - const uint8_t mask[4] = {0xf, 0xf, 0xf, 0xf}; - cursor = SDL_CreateCursor(data, mask, 8, 4, 4, 0); - SDL_SetCursor(cursor); -} - static int lg_run(void) { memset(&g_state, 0, sizeof(g_state)); @@ -649,16 +624,9 @@ static int lg_run(void) if (g_cursor.sens < -9) g_cursor.sens = -9; else if (g_cursor.sens > 9) g_cursor.sens = 9; - // try to early detect the platform - SDL_SYSWM_TYPE subsystem = SDL_SYSWM_UNKNOWN; - if (getenv("WAYLAND_DISPLAY")) subsystem = SDL_SYSWM_WAYLAND; - else if (getenv("DISPLAY" )) subsystem = SDL_SYSWM_X11; - else - DEBUG_WARN("Unknown subsystem, falling back to SDL default"); - // search for the best displayserver ops to use for(int i = 0; i < LG_DISPLAYSERVER_COUNT; ++i) - if (LG_DisplayServers[i]->subsystem == subsystem) + if (LG_DisplayServers[i]->probe()) { g_state.ds = LG_DisplayServers[i]; break; @@ -666,30 +634,6 @@ static int lg_run(void) assert(g_state.ds); - // set any null methods to the fallback -#define SET_FALLBACK(x) \ - if (!g_state.ds->x) g_state.ds->x = LG_DisplayServers[0]->x; - SET_FALLBACK(earlyInit); - SET_FALLBACK(getProp); - SET_FALLBACK(init); - SET_FALLBACK(startup); - SET_FALLBACK(shutdown); - SET_FALLBACK(free); - SET_FALLBACK(eventFilter); - SET_FALLBACK(showPointer); - SET_FALLBACK(grabPointer); - SET_FALLBACK(ungrabKeyboard); - SET_FALLBACK(warpPointer); - SET_FALLBACK(realignPointer); - SET_FALLBACK(isValidPointerPos); - SET_FALLBACK(inhibitIdle); - SET_FALLBACK(uninhibitIdle); - SET_FALLBACK(cbInit); - SET_FALLBACK(cbNotice); - SET_FALLBACK(cbRelease); - SET_FALLBACK(cbRequest); -#undef SET_FALLBACK - // init the subsystem if (!g_state.ds->earlyInit()) { @@ -697,16 +641,7 @@ static int lg_run(void) return -1; } - // Allow screensavers for now: we will enable and disable as needed. - SDL_SetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER, "1"); - - if (SDL_Init(SDL_INIT_VIDEO) < 0) - { - DEBUG_ERROR("SDL_Init Failed"); - return -1; - } - - // override SDL's SIGINIT handler so that we can tell the difference between + // override the SIGINIT handler so that we can tell the difference between // SIGINT and the user sending a close event, such as ALT+F4 signal(SIGINT , intHandler); signal(SIGTERM, intHandler); @@ -753,13 +688,11 @@ static int lg_run(void) LG_RendererParams lgrParams; lgrParams.showFPS = g_params.showFPS; lgrParams.quickSplash = g_params.quickSplash; - Uint32 sdlFlags; if (g_params.forceRenderer) { DEBUG_INFO("Trying forced renderer"); - sdlFlags = 0; - if (!tryRenderer(g_params.forceRendererIndex, lgrParams, &sdlFlags)) + if (!tryRenderer(g_params.forceRendererIndex, lgrParams)) { DEBUG_ERROR("Forced renderer failed to iniailize"); return -1; @@ -771,8 +704,7 @@ static int lg_run(void) // probe for a a suitable renderer for(unsigned int i = 0; i < LG_RENDERER_COUNT; ++i) { - sdlFlags = 0; - if (tryRenderer(i, lgrParams, &sdlFlags)) + if (tryRenderer(i, lgrParams)) { g_state.lgr = LG_Renderers[i]; break; @@ -786,59 +718,26 @@ static int lg_run(void) return -1; } - // all our ducks are in a line, create the window - g_state.window = SDL_CreateWindow( - g_params.windowTitle, - g_params.center ? SDL_WINDOWPOS_CENTERED : g_params.x, - g_params.center ? SDL_WINDOWPOS_CENTERED : g_params.y, - g_params.w, - g_params.h, - ( - SDL_WINDOW_HIDDEN | - (g_params.allowResize ? SDL_WINDOW_RESIZABLE : 0) | - (g_params.borderless ? SDL_WINDOW_BORDERLESS : 0) | - (g_params.maximize ? SDL_WINDOW_MAXIMIZED : 0) | - sdlFlags - ) - ); - - if (g_state.window == NULL) + const LG_DSInitParams params = { - DEBUG_ERROR("Could not create an SDL window: %s\n", SDL_GetError()); - return 1; - } + .title = g_params.windowTitle, + .x = g_params.x, + .y = g_params.y, + .w = g_params.w, + .h = g_params.h, + .center = g_params.center, + .fullscreen = g_params.fullscreen, + .resizable = g_params.allowResize, + .borderless = g_params.borderless, + .maximize = g_params.maximize, + .minimizeOnFocusLoss = g_params.minimizeOnFocusLoss + }; - SDL_VERSION(&g_state.wminfo.version); - if (!SDL_GetWindowWMInfo(g_state.window, &g_state.wminfo)) - { - DEBUG_ERROR("Could not get SDL window information %s", SDL_GetError()); - return -1; - } - - // enable WM events - SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); - - g_state.ds->init(&g_state.wminfo); - - // now init has been done we can show the window, doing this before init for - // X11 causes us to miss the first focus event - SDL_ShowWindow(g_state.window); - - SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, - g_params.minimizeOnFocusLoss ? "1" : "0"); - - if (g_params.fullscreen) - SDL_SetWindowFullscreen(g_state.window, SDL_WINDOW_FULLSCREEN_DESKTOP); - - if (!g_params.center) - SDL_SetWindowPosition(g_state.window, g_params.x, g_params.y); + g_state.ds->init(params); if (g_params.noScreensaver) g_state.ds->inhibitIdle(); - // ensure the initial window size is stored in the state - SDL_GetWindowSize(g_state.window, &g_state.windowW, &g_state.windowH); - // ensure renderer viewport is aware of the current window size core_updatePositionInfo(); @@ -855,8 +754,6 @@ static int lg_run(void) keybind_register(); - initSDLCursor(); - // setup the startup condition if (!(e_startup = lgCreateEvent(false, 0))) { @@ -880,10 +777,6 @@ static int lg_run(void) return -1; } - // ensure mouse acceleration is identical in server mode - SDL_SetHintWithPriority(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, "1", SDL_HINT_OVERRIDE); - SDL_SetEventFilter(eventFilter, NULL); - // wait for startup to complete so that any error messages below are output at // the end of the output lgWaitEvent(e_startup, TIMEOUT_INFINITE); @@ -906,7 +799,7 @@ static int lg_run(void) /* this short timeout is to allow the LGMP host to update the timestamp before * we start checking for a valid session */ - SDL_WaitEventTimeout(NULL, 200); + g_state.ds->wait(200); if (g_params.captureOnStart) core_setGrab(true); @@ -942,7 +835,7 @@ restart: DEBUG_INFO("Continuing to wait..."); } - SDL_WaitEventTimeout(NULL, 1000); + g_state.ds->wait(1000); } if (g_state.state != APP_STATE_RUNNING) @@ -975,7 +868,7 @@ restart: { DEBUG_INFO("Waiting for you to upgrade the host application"); while (g_state.state == APP_STATE_RUNNING && udata->version != KVMFR_VERSION) - SDL_WaitEventTimeout(NULL, 1000); + g_state.ds->wait(1000); if (g_state.state != APP_STATE_RUNNING) return -1; @@ -1005,7 +898,7 @@ restart: g_state.state = APP_STATE_RESTART; break; } - SDL_WaitEventTimeout(NULL, 100); + g_state.ds->wait(100); } if (g_state.state == APP_STATE_RESTART) @@ -1077,21 +970,9 @@ static void lg_shutdown(void) g_state.cbRequestList = NULL; } - if (g_state.window) - { - g_state.ds->free(); - SDL_DestroyWindow(g_state.window); - } - - if (cursor) - SDL_FreeCursor(cursor); - - ivshmemClose(&g_state.shm); - - // this must run last to ensure that we don't free any pointers still in use app_releaseAllKeybinds(); - - SDL_Quit(); + g_state.ds->free(); + ivshmemClose(&g_state.shm); } int main(int argc, char * argv[]) @@ -1110,6 +991,7 @@ int main(int argc, char * argv[]) config_init(); ivshmemOptionsInit(); + egl_dynProcsInit(); // early renderer setup for option registration for(unsigned int i = 0; i < LG_RENDERER_COUNT; ++i) diff --git a/client/src/main.h b/client/src/main.h index 145a9d05..54d3da39 100644 --- a/client/src/main.h +++ b/client/src/main.h @@ -19,7 +19,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include #include -#include #include #include "dynamic/displayservers.h" @@ -48,18 +47,18 @@ struct AppState bool stopVideo; bool ignoreInput; bool escapeActive; - SDL_Scancode escapeAction; + int escapeAction; KeybindHandle bindings[KEY_MAX]; bool keyDown[KEY_MAX]; bool haveSrcSize; - SDL_Point windowPos; + struct Point windowPos; int windowW, windowH; int windowCX, windowCY; LG_RendererRotate rotate; bool focused; struct Border border; - SDL_Point srcSize; + struct Point srcSize; LG_RendererRect dstRect; bool posInfoValid; bool alignToGuest; @@ -74,9 +73,6 @@ struct AppState size_t cbXfer; struct ll * cbRequestList; - SDL_SysWMinfo wminfo; - SDL_Window * window; - struct IVSHMEM shm; PLGMPClient lgmp; PLGMPClientQueue frameQueue; @@ -124,7 +120,7 @@ struct AppParams bool noScreensaver; bool grabKeyboard; bool grabKeyboardOnFocus; - SDL_Scancode escapeKey; + int escapeKey; bool ignoreWindowsKeys; bool showAlerts; bool captureOnStart; diff --git a/client/src/util.c b/client/src/util.c index 232f11d4..3234eafc 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -25,6 +25,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include #include #include +#include bool util_fileGetContents(const char * filename, char ** buffer, size_t * length) { diff --git a/common/include/common/types.h b/common/include/common/types.h index 253c9f2c..1a52f4c8 100644 --- a/common/include/common/types.h +++ b/common/include/common/types.h @@ -20,6 +20,11 @@ Place, Suite 330, Boston, MA 02111-1307 USA #ifndef _LG_TYPES_H_ #define _LG_TYPES_H_ +struct Point +{ + int x, y; +}; + struct DoublePoint { double x, y;