diff --git a/VERSION b/VERSION index 7699332d..9351c6a3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -a12-131-g10217fc8d9+1 \ No newline at end of file +a12-132-g5d254c7751+1 \ No newline at end of file diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 4fac4033..2b50c4f6 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -72,6 +72,7 @@ link_libraries( set(SOURCES src/main.c + src/app.c src/lg-renderer.c src/ll.c src/utils.c diff --git a/client/include/interface/app.h b/client/include/interface/app.h index 673548cb..25436f89 100644 --- a/client/include/interface/app.h +++ b/client/include/interface/app.h @@ -21,9 +21,26 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include +typedef enum LG_MsgAlert +{ + LG_ALERT_INFO , + LG_ALERT_SUCCESS, + LG_ALERT_WARNING, + LG_ALERT_ERROR +} +LG_MsgAlert; + typedef struct KeybindHandle * KeybindHandle; typedef void (*SuperEventFn)(SDL_Scancode key, void * opaque); +/** + * Show an alert on screen + * @param type The alert type + * param fmt The alert message format + @ param ... formatted message values + */ +void app_alert(LG_MsgAlert type, const char * fmt, ...); + /** * Register a handler for the + combination * @param key The scancode to register diff --git a/client/include/interface/renderer.h b/client/include/interface/renderer.h index 20c0073d..00d7a4e7 100644 --- a/client/include/interface/renderer.h +++ b/client/include/interface/renderer.h @@ -24,6 +24,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include #include +#include "app.h" #include "KVMFR.h" #define IS_LG_RENDERER_VALID(x) \ @@ -98,15 +99,6 @@ typedef enum LG_RendererCursor } LG_RendererCursor; -typedef enum LG_RendererOnAlert -{ - LG_ALERT_INFO , - LG_ALERT_SUCCESS, - LG_ALERT_WARNING, - LG_ALERT_ERROR -} -LG_RendererAlert; - typedef const char * (* LG_RendererGetName )(); typedef bool (* LG_RendererCreate )(void ** opaque, const LG_RendererParams params); typedef bool (* LG_RendererInitialize )(void * opaque, Uint32 * sdlFlags); @@ -115,7 +107,7 @@ typedef void (* LG_RendererOnResize )(void * opaque, const int width, typedef bool (* LG_RendererOnMouseShape)(void * opaque, const LG_RendererCursor cursor, const int width, const int height, const int pitch, const uint8_t * data); typedef bool (* LG_RendererOnMouseEvent)(void * opaque, const bool visible , const int x, const int y); typedef bool (* LG_RendererOnFrameEvent)(void * opaque, const LG_RendererFormat format, const uint8_t * data); -typedef void (* LG_RendererOnAlert )(void * opaque, const LG_RendererAlert alert, const char * message, bool ** closeFlag); +typedef void (* LG_RendererOnAlert )(void * opaque, const LG_MsgAlert alert, const char * message, bool ** closeFlag); typedef bool (* LG_RendererRender )(void * opaque, SDL_Window *window); typedef void (* LG_RendererUpdateFPS )(void * opaque, const float avgUPS, const float avgFPS); diff --git a/client/renderers/EGL/desktop.c b/client/renderers/EGL/desktop.c index 42acb343..67a909f2 100644 --- a/client/renderers/EGL/desktop.c +++ b/client/renderers/EGL/desktop.c @@ -130,6 +130,8 @@ void egl_desktop_toggle_nv(SDL_Scancode key, void * opaque) EGL_Desktop * desktop = (EGL_Desktop *)opaque; if (++desktop->nvGain == 4) desktop->nvGain = 0; + + app_alert(LG_ALERT_INFO, "Screen Gain +%d", desktop->nvGain); } void egl_desktop_free(EGL_Desktop ** desktop) diff --git a/client/renderers/EGL/egl.c b/client/renderers/EGL/egl.c index 1479fc8a..00bc5598 100644 --- a/client/renderers/EGL/egl.c +++ b/client/renderers/EGL/egl.c @@ -251,7 +251,7 @@ bool egl_on_frame_event(void * opaque, const LG_RendererFormat format, const uin return true; } -void egl_on_alert(void * opaque, const LG_RendererAlert alert, const char * message, bool ** closeFlag) +void egl_on_alert(void * opaque, const LG_MsgAlert alert, const char * message, bool ** closeFlag) { struct Inst * this = (struct Inst *)opaque; diff --git a/client/renderers/OpenGL/opengl.c b/client/renderers/OpenGL/opengl.c index 8c85398e..996bec75 100644 --- a/client/renderers/OpenGL/opengl.c +++ b/client/renderers/OpenGL/opengl.c @@ -377,7 +377,7 @@ bool opengl_on_frame_event(void * opaque, const LG_RendererFormat format, const return true; } -void opengl_on_alert(void * opaque, const LG_RendererAlert alert, const char * message, bool ** closeFlag) +void opengl_on_alert(void * opaque, const LG_MsgAlert alert, const char * message, bool ** closeFlag) { struct Inst * this = (struct Inst *)opaque; struct Alert * a = malloc(sizeof(struct Alert)); diff --git a/client/src/app.c b/client/src/app.c new file mode 100644 index 00000000..0883fbfa --- /dev/null +++ b/client/src/app.c @@ -0,0 +1,75 @@ +/* +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 +*/ + +#include "main.h" +#include "debug.h" +#include + +void app_alert(LG_MsgAlert type, const char * fmt, ...) +{ + if (!state.lgr || params.disableAlerts) + return; + + va_list args; + va_start(args, fmt); + const int length = vsnprintf(NULL, 0, fmt, args); + va_end(args); + + char *buffer = malloc(length + 1); + va_start(args, fmt); + vsnprintf(buffer, length + 1, fmt, args); + va_end(args); + + state.lgr->on_alert( + state.lgrData, + type, + buffer, + NULL + ); + + free(buffer); +} + +KeybindHandle app_register_keybind(SDL_Scancode key, SuperEventFn callback, void * opaque) +{ + // don't allow duplicate binds + if (state.bindings[key]) + { + DEBUG_INFO("Key already bound"); + return NULL; + } + + KeybindHandle handle = (KeybindHandle)malloc(sizeof(struct KeybindHandle)); + handle->key = key; + handle->callback = callback; + handle->opaque = opaque; + + state.bindings[key] = handle; + return handle; +} + +void app_release_keybind(KeybindHandle * handle) +{ + if (!handle) + return; + + state.bindings[(*handle)->key] = NULL; + free(*handle); + *handle = NULL; +} \ No newline at end of file diff --git a/client/src/main.c b/client/src/main.c index 3738f7bf..fea94273 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -17,9 +17,10 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "main.h" + #include #include -#include #include #include #include @@ -38,100 +39,13 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include "debug.h" #include "utils.h" #include "KVMFR.h" -#include "spice/spice.h" #include "kb.h" #include "ll.h" -#include "dynamic/renderers.h" -#include "dynamic/clipboards.h" - -#include "interface/app.h" - -struct AppState -{ - bool running; - bool ignoreInput; - bool escapeActive; - SDL_Scancode escapeAction; - KeybindHandle bindings[SDL_NUM_SCANCODES]; - bool keyDown[SDL_NUM_SCANCODES]; - - bool haveSrcSize; - int windowW, windowH; - SDL_Point srcSize; - LG_RendererRect dstRect; - SDL_Point cursor; - bool cursorVisible; - bool haveCursorPos; - float scaleX, scaleY; - float accX, accY; - - const LG_Renderer * lgr; - void * lgrData; - bool lgrResize; - - const LG_Clipboard * lgc; - SpiceDataType cbType; - struct ll * cbRequestList; - - SDL_Window * window; - int shmFD; - struct KVMFRHeader * shm; - unsigned int shmSize; - - uint64_t frameTime; - uint64_t lastFrameTime; - uint64_t renderTime; - uint64_t frameCount; - uint64_t renderCount; - - KeybindHandle kbFS; - KeybindHandle kbInput; -}; - -typedef struct RenderOpts -{ - unsigned int size; - unsigned int argc; - LG_RendererOptValue * argv; -} -RendererOpts; - -struct AppParams -{ - const char * configFile; - bool autoResize; - bool allowResize; - bool keepAspect; - bool borderless; - bool fullscreen; - bool center; - int x, y; - unsigned int w, h; - char * shmFile; - unsigned int shmSize; - unsigned int fpsLimit; - bool showFPS; - bool useSpiceInput; - bool useSpiceClipboard; - char * spiceHost; - unsigned int spicePort; - bool clipboardToVM; - bool clipboardToLocal; - bool scaleMouseInput; - bool hideMouse; - bool ignoreQuit; - bool allowScreensaver; - bool grabKeyboard; - SDL_Scancode escapeKey; - bool disableAlerts; - - bool forceRenderer; - unsigned int forceRendererIndex; - RendererOpts rendererOpts[LG_RENDERER_COUNT]; - - char * windowTitle; -}; +// forwards +static int cursorThread(void * unused); +static int renderThread(void * unused); +static int frameThread (void * unused); struct AppState state; struct AppParams params = @@ -162,31 +76,12 @@ struct AppParams params = .ignoreQuit = false, .allowScreensaver = true, .grabKeyboard = true, - .escapeKey = SDL_SCANCODE_SCROLLLOCK, + .escapeKey = SDL_SCANCODE_SCROLLLOCK, .disableAlerts = false, .forceRenderer = false, .windowTitle = "Looking Glass (Client)" }; -struct CBRequest -{ - SpiceDataType type; - LG_ClipboardReplyFn replyFn; - void * opaque; -}; - -struct KeybindHandle -{ - SDL_Scancode key; - SuperEventFn callback; - void * opaque; -}; - -// forwards -static int cursorThread(void * unused); -static int renderThread(void * unused); -static int frameThread (void * unused); - static void updatePositionInfo() { if (state.haveSrcSize) @@ -853,13 +748,10 @@ int eventFilter(void * userdata, SDL_Event * event) SDL_SetWindowGrab(state.window, serverMode); DEBUG_INFO("Server Mode: %s", serverMode ? "on" : "off"); - if (state.lgr && !params.disableAlerts) - state.lgr->on_alert( - state.lgrData, - serverMode ? LG_ALERT_SUCCESS : LG_ALERT_WARNING, - serverMode ? "Capture Enabled" : "Capture Disabled", - NULL - ); + app_alert( + serverMode ? LG_ALERT_SUCCESS : LG_ALERT_WARNING, + serverMode ? "Capture Enabled" : "Capture Disabled" + ); if (!serverMode) realignGuest = true; @@ -1028,6 +920,10 @@ static void toggle_fullscreen(SDL_Scancode key, void * opaque) static void toggle_input(SDL_Scancode key, void * opaque) { state.ignoreInput = !state.ignoreInput; + app_alert( + LG_ALERT_INFO, + state.ignoreInput ? "Input Disabled" : "Input Enabled" + ); } static void register_key_binds() @@ -1462,8 +1358,8 @@ void doHelp(char * app) params.w, params.h, params.escapeKey, - params.disableAlerts ? "disabled" : "enabled", - SDL_GetScancodeName(params.escapeKey) + SDL_GetScancodeName(params.escapeKey), + params.disableAlerts ? "disabled" : "enabled" ); } @@ -2000,32 +1896,4 @@ int main(int argc, char * argv[]) } return ret; -} - -KeybindHandle app_register_keybind(SDL_Scancode key, SuperEventFn callback, void * opaque) -{ - // don't allow duplicate binds - if (state.bindings[key]) - { - DEBUG_INFO("Key already bound"); - return NULL; - } - - KeybindHandle handle = (KeybindHandle)malloc(sizeof(struct KeybindHandle)); - handle->key = key; - handle->callback = callback; - handle->opaque = opaque; - - state.bindings[key] = handle; - return handle; -} - -void app_release_keybind(KeybindHandle * handle) -{ - if (!handle) - return; - - state.bindings[(*handle)->key] = NULL; - free(*handle); - *handle = NULL; } \ No newline at end of file diff --git a/client/src/main.h b/client/src/main.h new file mode 100644 index 00000000..50712a8d --- /dev/null +++ b/client/src/main.h @@ -0,0 +1,131 @@ +/* +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 +*/ + +#include +#include + +#include "interface/app.h" +#include "dynamic/renderers.h" +#include "dynamic/clipboards.h" + +#include "spice/spice.h" + +struct AppState +{ + bool running; + bool ignoreInput; + bool escapeActive; + SDL_Scancode escapeAction; + KeybindHandle bindings[SDL_NUM_SCANCODES]; + bool keyDown[SDL_NUM_SCANCODES]; + + bool haveSrcSize; + int windowW, windowH; + SDL_Point srcSize; + LG_RendererRect dstRect; + SDL_Point cursor; + bool cursorVisible; + bool haveCursorPos; + float scaleX, scaleY; + float accX, accY; + + const LG_Renderer * lgr; + void * lgrData; + bool lgrResize; + + const LG_Clipboard * lgc; + SpiceDataType cbType; + struct ll * cbRequestList; + + SDL_Window * window; + int shmFD; + struct KVMFRHeader * shm; + unsigned int shmSize; + + uint64_t frameTime; + uint64_t lastFrameTime; + uint64_t renderTime; + uint64_t frameCount; + uint64_t renderCount; + + KeybindHandle kbFS; + KeybindHandle kbInput; +}; + +typedef struct RenderOpts +{ + unsigned int size; + unsigned int argc; + LG_RendererOptValue * argv; +} +RendererOpts; + +struct AppParams +{ + const char * configFile; + bool autoResize; + bool allowResize; + bool keepAspect; + bool borderless; + bool fullscreen; + bool center; + int x, y; + unsigned int w, h; + char * shmFile; + unsigned int shmSize; + unsigned int fpsLimit; + bool showFPS; + bool useSpiceInput; + bool useSpiceClipboard; + char * spiceHost; + unsigned int spicePort; + bool clipboardToVM; + bool clipboardToLocal; + bool scaleMouseInput; + bool hideMouse; + bool ignoreQuit; + bool allowScreensaver; + bool grabKeyboard; + SDL_Scancode escapeKey; + bool disableAlerts; + + bool forceRenderer; + unsigned int forceRendererIndex; + RendererOpts rendererOpts[LG_RENDERER_COUNT]; + + char * windowTitle; +}; + +struct CBRequest +{ + SpiceDataType type; + LG_ClipboardReplyFn replyFn; + void * opaque; +}; + +struct KeybindHandle +{ + SDL_Scancode key; + SuperEventFn callback; + void * opaque; +}; + +// forwards +extern struct AppState state; +extern struct AppParams params; \ No newline at end of file