global hotkeys can now be configured with a file

This commit is contained in:
Lexi Quinn 2022-01-16 15:19:26 +11:00
parent f0dc3bde84
commit d15a5cefc8
6 changed files with 150 additions and 25 deletions

View File

@ -28,7 +28,7 @@ segments after the first use of the split file is currently unsupported.
| `T` | Toggle global hotkeys | YES |
| `C` | Toggle compact UI | NO |
Customisable hotkeys without editing the source code coming soon!
Hotkeys can be configured in `$HOME/.config/quest/keymaps/default`
## Third Party Integration

View File

@ -5,7 +5,37 @@ char buf;
int pipefd[2];
struct keymap km;
char *keystrings[2] = {"a", "b"};
char *keystrings[KEYNUM] = {
"a", "b", "c", "d", "e", "f",
"g", "h", "i", "j", "k", "l",
"m", "n", "o", "p", "q", "r",
"s", "t", "u", "v", "w", "x",
"y", "z", "1", "2", "3", "4",
"5", "6", "7", "8", "9", "0",
"F1", "F2", "F3", "F4", "F5", "F6",
"F7", "F8", "F9", "F10", "F11", "F12",
"F13", "F14", "F15", "F16", "F17", "F18",
"F19", "F20", "F21", "F22", "F23", "F24",
"ESC", "`", "-", "=", "BSP", "TAB",
"CAP", "[", "]", "\\", ";", "\"",
"ENT", ",", ".", "/", " ",
};
uint16_t uiohookKeycodes[KEYNUM] = {
VC_A, VC_B, VC_C, VC_D, VC_E, VC_F,
VC_G, VC_H, VC_I, VC_J, VC_K, VC_L,
VC_M, VC_N, VC_O, VC_P, VC_Q, VC_R,
VC_S, VC_T, VC_U, VC_V, VC_W, VC_X,
VC_Y, VC_Z, VC_1, VC_2, VC_3, VC_4,
VC_5, VC_6, VC_7, VC_8, VC_9, VC_0,
VC_F1, VC_F2, VC_F3, VC_F4, VC_F5, VC_F6,
VC_F7, VC_F8, VC_F9, VC_F10, VC_F11, VC_F12,
VC_F13, VC_F14, VC_F15, VC_F16, VC_F17, VC_F18,
VC_F19, VC_F20, VC_F21, VC_F22, VC_F23, VC_F24,
VC_ESCAPE, VC_BACKQUOTE, VC_MINUS, VC_EQUALS, VC_BACKSPACE, VC_TAB,
VC_CAPS_LOCK, VC_OPEN_BRACKET, VC_CLOSE_BRACKET, VC_BACK_SLASH, VC_SEMICOLON, VC_QUOTE,
VC_ENTER, VC_COMMA, VC_PERIOD, VC_SLASH, VC_SPACE
};
bool logger_proc(unsigned int level, const char *format, ...) {
return 0;
@ -70,3 +100,22 @@ int handleInput()
skip();
return 0;
}
void loadKeymap()
{
km.START = VC_R;
km.STOP = VC_F;
km.PAUSE = VC_D;
km.SPLIT = VC_E;
km.HOTKS = VC_T;
km.USPLT = VC_G;
km.SKIP = VC_V;
}
uint16_t keystringToKeycode(char *keystring) {
for (int i = 0; i < KEYNUM; i++)
if (strcmp(keystring, keystrings[i]) == 0)
return uiohookKeycodes[i];
return NULL;
}

View File

@ -14,6 +14,8 @@
#define K_USPLT 6
#define K_SKIP 7
#define KEYNUM 77
extern bool hotkeys_enabled;
struct keymap
@ -31,9 +33,13 @@ extern char buf;
extern int pipefd[2];
extern struct keymap km;
extern char *keystrings[77];
bool logger_proc(unsigned int level, const char *format, ...);
void dispatch_proc(uiohook_event * const event);
int handleInput();
void loadKeymap();
uint16_t keystringToKeycode(char *keystring);
#endif

View File

@ -1,14 +1,14 @@
#ifndef SPLITSIO
#define SPLITSIO
#ifndef SPLITSIO_H
#define SPLITSIO_H
#include "cJSON.h"
#include "timer.h"
const char *schemaver;
const char *timersname;
const char *timerlname;
const char *timerver;
const char *timerlink;
//const char *schemaver;
//const char *timersname;
//const char *timerlname;
//const char *timerver;
//const char *timerlink;
void importSplitsIO(cJSON *splitfile);
void exportSplitsIO();

View File

@ -21,6 +21,7 @@ bool dirty = false;
//Run data
char *filepath;
char *configpath;
char *gameTitle = "title not loaded";
char *categoryTitle = "category not loaded";
int attempts = 0;
@ -120,17 +121,6 @@ void skip()
stop();
}
void loadKeymap()
{
km.START = VC_R;
km.STOP = VC_F;
km.PAUSE = VC_D;
km.SPLIT = VC_E;
km.HOTKS = VC_T;
km.USPLT = VC_G;
km.SKIP = VC_V;
}
void ftime(char *timestr, int rms, int decimals, bool sign)
{
if (decimals > 3 || decimals < 0)
@ -452,15 +442,94 @@ void calculateBestSegs()
void loadConfig()
{
cJSON *config = NULL;
char path[256];
strcat(strcpy(path, getenv("HOME")), "/.config/quest");
mkdir(path, 0777);
strcat(strcpy(path, getenv("HOME")), "/.config/quest/keymaps");
mkdir(path, 0777);
strcat(strcpy(path, getenv("HOME")), "/.config/quest/keymaps/default");
configpath = malloc(strlen(path));
strcpy(configpath, path);
FILE* fp = fopen(path, "r");
fclose(fp);
long length;
FILE* f = fopen(path, "rb");
if (f != NULL) {
char *buffer = NULL;
fseek(f, 0, SEEK_END);
length = ftell(f);
fseek(f, 0, SEEK_SET);
buffer = malloc(length + 1);
if (buffer != NULL)
fread(buffer, 1, length, f);
fclose(f);
buffer[length] = '\0';
config = cJSON_Parse(buffer);
free(buffer);
cJSON *startkey = cJSON_GetItem(config, "start");
cJSON *stopkey = cJSON_GetItem(config, "stop");
cJSON *pausekey = cJSON_GetItem(config, "pause");
cJSON *splitkey = cJSON_GetItem(config, "split");
cJSON *hotkskey = cJSON_GetItem(config, "toggle hotkeys");
cJSON *uspltkey = cJSON_GetItem(config, "unsplit");
cJSON *skipkey = cJSON_GetItem(config, "skip");
if (cJSON_IsString(startkey) && (startkey->valuestring != NULL))
km.START = keystringToKeycode(startkey->valuestring);
if (cJSON_IsString(stopkey) && (stopkey->valuestring != NULL))
km.STOP = keystringToKeycode(stopkey->valuestring);
if (cJSON_IsString(pausekey) && (pausekey->valuestring != NULL))
km.PAUSE = keystringToKeycode(pausekey->valuestring);
if (cJSON_IsString(splitkey) && (splitkey->valuestring != NULL))
km.SPLIT = keystringToKeycode(splitkey->valuestring);
if (cJSON_IsString(hotkskey) && (hotkskey->valuestring != NULL))
km.HOTKS = keystringToKeycode(hotkskey->valuestring);
if (cJSON_IsString(uspltkey) && (uspltkey->valuestring != NULL))
km.USPLT = keystringToKeycode(uspltkey->valuestring);
if (cJSON_IsString(skipkey) && (skipkey->valuestring != NULL))
km.SKIP = keystringToKeycode(skipkey->valuestring);
} else {
config = cJSON_CreateObject();
km.START = VC_R;
km.STOP = VC_F;
km.PAUSE = VC_D;
km.SPLIT = VC_E;
km.HOTKS = VC_T;
km.USPLT = VC_G;
km.SKIP = VC_V;
cJSON *startkey = cJSON_CreateString("r");
cJSON_AddItemToObject(config, "start", startkey);
cJSON *stopkey = cJSON_CreateString("f");
cJSON_AddItemToObject(config, "stop", stopkey);
cJSON *pausekey = cJSON_CreateString("d");
cJSON_AddItemToObject(config, "pause", pausekey);
cJSON *splitkey = cJSON_CreateString("e");
cJSON_AddItemToObject(config, "split", splitkey);
cJSON *hotkskey = cJSON_CreateString("t");
cJSON_AddItemToObject(config, "toggle hotkeys", hotkskey);
cJSON *uspltkey = cJSON_CreateString("g");
cJSON_AddItemToObject(config, "unsplit", uspltkey);
cJSON *skipkey = cJSON_CreateString("v");
cJSON_AddItemToObject(config, "skip", skipkey);
saveConfig(config);
}
cJSON_Delete(config);
}
void saveConfig(cJSON *config)
{
char *string = cJSON_Print(config);
if (string != NULL) {
FILE *f = fopen(configpath, "w");
if (f == NULL)
return;
fwrite(string, 1, strlen(string), f);
fclose(f);
}
}
//TODO: it'll be more efficent if all the segments pointers point at the same
@ -655,7 +724,7 @@ int main(int argc, char **argv)
pipe(pipefd);
fcntl(pipefd[0], F_SETFL, O_NONBLOCK);
loadKeymap();
loadConfig();
cpid = fork();
if (cpid == 0) {

View File

@ -3,6 +3,7 @@
#include "display.h"
#include "keys.h"
#include "splitsio.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
@ -52,7 +53,6 @@ void split();
void tpause();
void unsplit();
void skip();
void loadKeymap();
void ftime(char *timestr, int rms, int decimals, bool sign);
int timespecToMS(struct timespec t);
void drawNotif();
@ -62,8 +62,9 @@ void drawTimeColumn();
void toggleCompact();
void drawDisplay();
void resize(int i);
void importSplitsIO(cJSON *splitfile);
void calculatePB();
void loadConfig();
void saveConfig(cJSON *config);
void loadFile();
void saveFile();
int main(int argc, char **argv);