mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-10-13 19:08:11 +00:00
[client] all: use the defined keyboard mapping for keybinds
Fixes #1007
This commit is contained in:
@@ -38,6 +38,7 @@
|
||||
#include <stdarg.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
bool app_isRunning(void)
|
||||
{
|
||||
@@ -115,7 +116,7 @@ void app_handleFocusEvent(bool focused)
|
||||
if (g_params.releaseKeysOnFocusLoss)
|
||||
for (int key = 0; key < KEY_MAX; key++)
|
||||
if (g_state.keyDown[key])
|
||||
app_handleKeyRelease(key);
|
||||
app_handleKeyRelease(key, 0);
|
||||
|
||||
g_state.escapeActive = false;
|
||||
|
||||
@@ -304,7 +305,7 @@ void app_handleWheelMotion(double motion)
|
||||
g_state.io->MouseWheel -= motion;
|
||||
}
|
||||
|
||||
void app_handleKeyPress(int sc)
|
||||
void app_handleKeyPress(int sc, int charcode)
|
||||
{
|
||||
if (!app_isOverlayMode() || !g_state.io->WantCaptureKeyboard)
|
||||
{
|
||||
@@ -319,9 +320,16 @@ void app_handleKeyPress(int sc)
|
||||
if (g_state.escapeActive)
|
||||
{
|
||||
g_state.escapeAction = sc;
|
||||
KeybindHandle handle = g_state.bindings[sc];
|
||||
if (handle)
|
||||
handle->callback(sc, handle->opaque);
|
||||
KeybindHandle handle;
|
||||
ll_forEachNL(g_state.bindings, item, handle)
|
||||
{
|
||||
if ((handle->sc && handle->sc == sc ) ||
|
||||
(handle->charcode && handle->charcode == charcode))
|
||||
{
|
||||
handle->callback(sc, handle->opaque);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -357,7 +365,7 @@ void app_handleKeyPress(int sc)
|
||||
}
|
||||
}
|
||||
|
||||
void app_handleKeyRelease(int sc)
|
||||
void app_handleKeyRelease(int sc, int charcode)
|
||||
{
|
||||
if (g_state.escapeActive)
|
||||
{
|
||||
@@ -679,28 +687,48 @@ void app_showRecord(bool show)
|
||||
overlayStatus_set(LG_USER_STATUS_RECORDING, show);
|
||||
}
|
||||
|
||||
KeybindHandle app_registerKeybind(int sc, KeybindFn callback, void * opaque, const char * description)
|
||||
KeybindHandle app_registerKeybind(int sc, int charcode, KeybindFn callback,
|
||||
void * opaque, const char * description)
|
||||
{
|
||||
// don't allow duplicate binds
|
||||
if (g_state.bindings[sc])
|
||||
if (charcode != 0 && sc != 0)
|
||||
{
|
||||
DEBUG_INFO("Key already bound");
|
||||
DEBUG_ERROR("invalid keybind, one of scancode or charcode must be 0");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
KeybindHandle handle = malloc(sizeof(*handle));
|
||||
if (charcode && islower(charcode))
|
||||
{
|
||||
DEBUG_ERROR("invalid keybind, charcode must be uppercase");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
KeybindHandle handle;
|
||||
|
||||
// don't allow duplicate binds
|
||||
ll_forEachNL(g_state.bindings, item, handle)
|
||||
{
|
||||
if ((sc && handle->sc == sc ) ||
|
||||
(charcode && handle->charcode == charcode))
|
||||
{
|
||||
DEBUG_INFO("Key already bound");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
handle = malloc(sizeof(*handle));
|
||||
if (!handle)
|
||||
{
|
||||
DEBUG_ERROR("out of memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
handle->sc = sc;
|
||||
handle->callback = callback;
|
||||
handle->opaque = opaque;
|
||||
handle->sc = sc;
|
||||
handle->charcode = charcode;
|
||||
handle->callback = callback;
|
||||
handle->description = description;
|
||||
handle->opaque = opaque;
|
||||
|
||||
g_state.bindings[sc] = handle;
|
||||
g_state.keyDescription[sc] = description;
|
||||
ll_push(g_state.bindings, handle);
|
||||
return handle;
|
||||
}
|
||||
|
||||
@@ -709,19 +737,16 @@ void app_releaseKeybind(KeybindHandle * handle)
|
||||
if (!*handle)
|
||||
return;
|
||||
|
||||
g_state.bindings[(*handle)->sc] = NULL;
|
||||
ll_removeData(g_state.bindings, *handle);
|
||||
free(*handle);
|
||||
*handle = NULL;
|
||||
}
|
||||
|
||||
void app_releaseAllKeybinds(void)
|
||||
{
|
||||
for(int i = 0; i < KEY_MAX; ++i)
|
||||
if (g_state.bindings[i])
|
||||
{
|
||||
free(g_state.bindings[i]);
|
||||
g_state.bindings[i] = NULL;
|
||||
}
|
||||
KeybindHandle * handle;
|
||||
while(ll_shift(g_state.bindings, (void **)&handle))
|
||||
free(handle);
|
||||
}
|
||||
|
||||
GraphHandle app_registerGraph(const char * name, RingBuffer buffer,
|
||||
|
@@ -127,15 +127,15 @@ static void bind_toggleKey(int sc, void * opaque)
|
||||
|
||||
void keybind_commonRegister(void)
|
||||
{
|
||||
app_registerKeybind(KEY_F, bind_fullscreen , NULL,
|
||||
app_registerKeybind(0, 'F', bind_fullscreen , NULL,
|
||||
"Full screen toggle");
|
||||
app_registerKeybind(KEY_V, bind_video , NULL,
|
||||
app_registerKeybind(0, 'V', bind_video , NULL,
|
||||
"Video stream toggle");
|
||||
app_registerKeybind(KEY_R, bind_rotate , NULL,
|
||||
app_registerKeybind(0, 'R', bind_rotate , NULL,
|
||||
"Rotate the output clockwise by 90° increments");
|
||||
app_registerKeybind(KEY_Q, bind_quit , NULL,
|
||||
app_registerKeybind(0, 'Q', bind_quit , NULL,
|
||||
"Quit");
|
||||
app_registerKeybind(KEY_O, bind_toggleOverlay, NULL,
|
||||
app_registerKeybind(0, 'O', bind_toggleOverlay, NULL,
|
||||
"Toggle overlay");
|
||||
}
|
||||
|
||||
@@ -145,30 +145,30 @@ void keybind_spiceRegister(void)
|
||||
static bool firstTime = true;
|
||||
if (firstTime)
|
||||
{
|
||||
app_registerKeybind(KEY_I, bind_input, NULL,
|
||||
app_registerKeybind(0, 'I', bind_input, NULL,
|
||||
"Spice keyboard & mouse toggle");
|
||||
|
||||
app_registerKeybind(KEY_INSERT, bind_mouseSens, (void *) true ,
|
||||
"Increase mouse sensitivity in capture mode");
|
||||
app_registerKeybind(KEY_DELETE, bind_mouseSens, (void *) false,
|
||||
app_registerKeybind(KEY_INSERT, 0, bind_mouseSens, (void *) true ,
|
||||
"Increase mouse sensitivity 0, in capture mode");
|
||||
app_registerKeybind(KEY_DELETE, 0, bind_mouseSens, (void *) false,
|
||||
"Descrease mouse sensitivity in capture mode");
|
||||
|
||||
app_registerKeybind(KEY_UP , bind_toggleKey, (void *) PS2_VOLUME_UP ,
|
||||
app_registerKeybind(KEY_UP , 0 , bind_toggleKey, (void *) PS2_VOLUME_UP ,
|
||||
"Send volume up to the guest");
|
||||
app_registerKeybind(KEY_DOWN, bind_toggleKey, (void *) PS2_VOLUME_DOWN,
|
||||
app_registerKeybind(KEY_DOWN, 0 , bind_toggleKey, (void *) PS2_VOLUME_DOWN,
|
||||
"Send volume down to the guest");
|
||||
app_registerKeybind(KEY_M , bind_toggleKey, (void *) PS2_MUTE ,
|
||||
app_registerKeybind(0 , 'M', bind_toggleKey, (void *) PS2_MUTE ,
|
||||
"Send mute to the guest");
|
||||
|
||||
app_registerKeybind(KEY_LEFTMETA , bind_passthrough, NULL,
|
||||
app_registerKeybind(KEY_LEFTMETA , 0, bind_passthrough, NULL,
|
||||
"Send LWin to the guest");
|
||||
app_registerKeybind(KEY_RIGHTMETA, bind_passthrough, NULL,
|
||||
app_registerKeybind(KEY_RIGHTMETA, 0, bind_passthrough, NULL,
|
||||
"Send RWin to the guest");
|
||||
|
||||
#if ENABLE_AUDIO
|
||||
if (audio_supportsRecord())
|
||||
{
|
||||
app_registerKeybind(KEY_E, audio_recordToggleKeybind, NULL,
|
||||
app_registerKeybind(0, 'E', audio_recordToggleKeybind, NULL,
|
||||
"Toggle audio recording");
|
||||
}
|
||||
#endif
|
||||
@@ -186,29 +186,29 @@ void keybind_spiceRegister(void)
|
||||
/* register OS based keybinds */
|
||||
if (app_guestIsLinux())
|
||||
{
|
||||
handles[handleCount++] = app_registerKeybind(KEY_F1 , bind_ctrlAltFn, NULL,
|
||||
handles[handleCount++] = app_registerKeybind(KEY_F1 , 0, bind_ctrlAltFn, NULL,
|
||||
"Send Ctrl+Alt+F1 to the guest");
|
||||
handles[handleCount++] = app_registerKeybind(KEY_F2 , bind_ctrlAltFn, NULL,
|
||||
handles[handleCount++] = app_registerKeybind(KEY_F2 , 0, bind_ctrlAltFn, NULL,
|
||||
"Send Ctrl+Alt+F2 to the guest");
|
||||
handles[handleCount++] = app_registerKeybind(KEY_F3 , bind_ctrlAltFn, NULL,
|
||||
handles[handleCount++] = app_registerKeybind(KEY_F3 , 0, bind_ctrlAltFn, NULL,
|
||||
"Send Ctrl+Alt+F3 to the guest");
|
||||
handles[handleCount++] = app_registerKeybind(KEY_F4 , bind_ctrlAltFn, NULL,
|
||||
handles[handleCount++] = app_registerKeybind(KEY_F4 , 0, bind_ctrlAltFn, NULL,
|
||||
"Send Ctrl+Alt+F4 to the guest");
|
||||
handles[handleCount++] = app_registerKeybind(KEY_F5 , bind_ctrlAltFn, NULL,
|
||||
handles[handleCount++] = app_registerKeybind(KEY_F5 , 0, bind_ctrlAltFn, NULL,
|
||||
"Send Ctrl+Alt+F5 to the guest");
|
||||
handles[handleCount++] = app_registerKeybind(KEY_F6 , bind_ctrlAltFn, NULL,
|
||||
handles[handleCount++] = app_registerKeybind(KEY_F6 , 0, bind_ctrlAltFn, NULL,
|
||||
"Send Ctrl+Alt+F6 to the guest");
|
||||
handles[handleCount++] = app_registerKeybind(KEY_F7 , bind_ctrlAltFn, NULL,
|
||||
handles[handleCount++] = app_registerKeybind(KEY_F7 , 0, bind_ctrlAltFn, NULL,
|
||||
"Send Ctrl+Alt+F7 to the guest");
|
||||
handles[handleCount++] = app_registerKeybind(KEY_F8 , bind_ctrlAltFn, NULL,
|
||||
handles[handleCount++] = app_registerKeybind(KEY_F8 , 0, bind_ctrlAltFn, NULL,
|
||||
"Send Ctrl+Alt+F8 to the guest");
|
||||
handles[handleCount++] = app_registerKeybind(KEY_F9 , bind_ctrlAltFn, NULL,
|
||||
handles[handleCount++] = app_registerKeybind(KEY_F9 , 0, bind_ctrlAltFn, NULL,
|
||||
"Send Ctrl+Alt+F9 to the guest");
|
||||
handles[handleCount++] = app_registerKeybind(KEY_F10, bind_ctrlAltFn, NULL,
|
||||
handles[handleCount++] = app_registerKeybind(KEY_F10, 0, bind_ctrlAltFn, NULL,
|
||||
"Send Ctrl+Alt+F10 to the guest");
|
||||
handles[handleCount++] = app_registerKeybind(KEY_F11, bind_ctrlAltFn, NULL,
|
||||
handles[handleCount++] = app_registerKeybind(KEY_F11, 0, bind_ctrlAltFn, NULL,
|
||||
"Send Ctrl+Alt+F11 to the guest");
|
||||
handles[handleCount++] = app_registerKeybind(KEY_F12, bind_ctrlAltFn, NULL,
|
||||
handles[handleCount++] = app_registerKeybind(KEY_F12, 0, bind_ctrlAltFn, NULL,
|
||||
"Send Ctrl+Alt+F12 to the guest");
|
||||
}
|
||||
}
|
||||
|
@@ -1693,6 +1693,7 @@ static void lg_shutdown(void)
|
||||
}
|
||||
|
||||
app_releaseAllKeybinds();
|
||||
ll_free(g_state.bindings);
|
||||
|
||||
if (g_state.dsInitialized)
|
||||
g_state.ds->free();
|
||||
@@ -1742,6 +1743,8 @@ int main(int argc, char * argv[])
|
||||
egl_dynProcsInit();
|
||||
gl_dynProcsInit();
|
||||
|
||||
g_state.bindings = ll_new();
|
||||
|
||||
g_state.overlays = ll_new();
|
||||
app_registerOverlay(&LGOverlaySplash, NULL);
|
||||
app_registerOverlay(&LGOverlayConfig, NULL);
|
||||
|
@@ -90,8 +90,7 @@ struct AppState
|
||||
uint64_t escapeTime;
|
||||
int escapeAction;
|
||||
bool escapeHelp;
|
||||
KeybindHandle bindings[KEY_MAX];
|
||||
const char * keyDescription[KEY_MAX];
|
||||
struct ll * bindings;
|
||||
bool keyDown[KEY_MAX];
|
||||
|
||||
bool haveSrcSize;
|
||||
@@ -227,9 +226,11 @@ struct CBRequest
|
||||
|
||||
struct KeybindHandle
|
||||
{
|
||||
int sc;
|
||||
KeybindFn callback;
|
||||
void * opaque;
|
||||
int sc;
|
||||
int charcode;
|
||||
KeybindFn callback;
|
||||
const char * description;
|
||||
void * opaque;
|
||||
};
|
||||
|
||||
enum WarpState
|
||||
|
@@ -53,7 +53,7 @@ static void fps_earlyInit(void)
|
||||
|
||||
static bool fps_init(void ** udata, const void * params)
|
||||
{
|
||||
app_registerKeybind(KEY_D, showFPSKeybind, NULL, "FPS display toggle");
|
||||
app_registerKeybind(0, 'D', showFPSKeybind, NULL, "FPS display toggle");
|
||||
showFPS = option_get_bool("win", "showFPS");
|
||||
return true;
|
||||
}
|
||||
|
@@ -78,7 +78,7 @@ static void graphs_earlyInit(void)
|
||||
static bool graphs_init(void ** udata, const void * params)
|
||||
{
|
||||
app_overlayConfigRegister("Performance Metrics", configCallback, NULL);
|
||||
app_registerKeybind(KEY_T, showTimingKeybind, NULL,
|
||||
app_registerKeybind(0, 'T', showTimingKeybind, NULL,
|
||||
"Show frame timing information");
|
||||
return true;
|
||||
}
|
||||
|
@@ -63,14 +63,20 @@ static int help_render(void * udata, bool interactive, struct Rect * windowRects
|
||||
igTableNextColumn();
|
||||
igText("Toggle capture mode");
|
||||
|
||||
for (int i = 0; i < KEY_MAX; ++i)
|
||||
if (g_state.keyDescription[i])
|
||||
{
|
||||
igTableNextColumn();
|
||||
igText("%s+%s", escapeName, linux_to_display[i]);
|
||||
igTableNextColumn();
|
||||
igText(g_state.keyDescription[i]);
|
||||
}
|
||||
KeybindHandle handle;
|
||||
ll_forEachNL(g_state.bindings, item, handle)
|
||||
{
|
||||
if (!handle->description)
|
||||
continue;
|
||||
|
||||
igTableNextColumn();
|
||||
if (handle->sc)
|
||||
igText("%s+%s", escapeName, linux_to_display[handle->sc]);
|
||||
else
|
||||
igText("%s+%c", escapeName, handle->charcode);
|
||||
igTableNextColumn();
|
||||
igText(handle->description);
|
||||
}
|
||||
|
||||
igEndTable();
|
||||
}
|
||||
|
Reference in New Issue
Block a user