summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/hotkey.c113
-rw-r--r--src/hotkey.h53
-rw-r--r--src/main.c52
-rw-r--r--src/settings.c15
-rw-r--r--src/ui_readline.c20
-rw-r--r--src/ui_readline.h3
6 files changed, 245 insertions, 11 deletions
diff --git a/src/hotkey.c b/src/hotkey.c
new file mode 100644
index 0000000..b630b88
--- /dev/null
+++ b/src/hotkey.c
@@ -0,0 +1,113 @@
+/*
+Copyright (c) 2019
+ Michał Cichoń <thedmd@interia.pl>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#include "hotkey.h"
+#include <stdio.h>
+#include <stdbool.h>
+#include <fcntl.h>
+#include <io.h>
+#include <windows.h>
+
+static BarHotKey_t* g_HotKeys = NULL;
+static int g_HotKeyCapacity = 0;
+static int g_HotKeyCount = 0;
+
+void BarHotKeyInit ()
+{
+}
+
+void BarHotKeyDestroy ()
+{
+}
+
+void BarHotKeyPool (BarHotKeyHandler handler, void * userData)
+{
+ MSG msg = {0};
+ while (PeekMessage(&msg, NULL, WM_HOTKEY, WM_HOTKEY, PM_REMOVE) != 0)
+ {
+ int id = (int)msg.wParam;
+ if (id < 0)
+ continue;
+
+ handler(id, userData);
+ }
+}
+
+bool BarHotKeyRegister (BarHotKey_t hk)
+{
+ UINT modifiers = 0;
+ SHORT mappedVirtualKey = VkKeyScanA(tolower(hk.key));
+ BYTE keyCode = LOBYTE(mappedVirtualKey);
+ if (keyCode == 0)
+ return false;
+
+ if (hk.mods & BAR_HK_MOD_SHIFT)
+ modifiers |= MOD_SHIFT;
+ if (hk.mods & BAR_HK_MOD_ALT)
+ modifiers |= MOD_ALT;
+ if (hk.mods & BAR_HK_MOD_CTRL)
+ modifiers |= MOD_CONTROL;
+ if (hk.mods & BAR_HK_MOD_WIN)
+ modifiers |= MOD_WIN;
+
+ modifiers |= /*MOD_NOREPEAT*/0x4000;
+
+ return RegisterHotKey(NULL, hk.id, modifiers, keyCode);
+}
+
+void BarHotKeyUnregister (int id)
+{
+ UnregisterHotKey(NULL, id);
+}
+
+bool BarHotKeyParse (BarHotKey_t* result, const char *value)
+{
+ BarHotKey_t parsed = { 0 };
+ const char* p = value;
+ size_t s = 0;
+
+ while ((s = strcspn(p, " +")) > 0)
+ {
+ if ((s == 4 && strnicmp(p, "ctrl", 4) == 0) || (s == 7 && strnicmp(p, "control", 7) == 0))
+ parsed.mods |= BAR_HK_MOD_CTRL;
+ else if ((s == 5 && strnicmp(p, "shift", 5) == 0))
+ parsed.mods |= BAR_HK_MOD_SHIFT;
+ else if ((s == 3 && strnicmp(p, "alt", 3) == 0))
+ parsed.mods |= BAR_HK_MOD_ALT;
+ else if (s == 1)
+ parsed.key = *p;
+ else
+ return false;
+
+ p += s;
+ p += strspn(p, " +");
+ }
+
+ if (parsed.key == 0)
+ return false;
+
+ result->key = parsed.key;
+ result->mods = parsed.mods;
+
+ return true;
+} \ No newline at end of file
diff --git a/src/hotkey.h b/src/hotkey.h
new file mode 100644
index 0000000..fb59bc0
--- /dev/null
+++ b/src/hotkey.h
@@ -0,0 +1,53 @@
+/*
+Copyright (c) 2019
+ Michał Cichoń <thedmd@interia.pl>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+# pragma once
+
+#include "config.h"
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdbool.h>
+
+typedef enum {
+ BAR_HK_MOD_NONE = 0,
+ BAR_HK_MOD_SHIFT = 1,
+ BAR_HK_MOD_ALT = 2,
+ BAR_HK_MOD_CTRL = 4,
+ BAR_HK_MOD_WIN = 8
+} BarHotKeyMods_t;
+
+typedef struct {
+ int id;
+ char key;
+ BarHotKeyMods_t mods;
+} BarHotKey_t;
+
+typedef void (*BarHotKeyHandler)(int, void *);
+
+void BarHotKeyInit ();
+void BarHotKeyDestroy ();
+void BarHotKeyPool (BarHotKeyHandler, void *);
+bool BarHotKeyRegister (BarHotKey_t);
+void BarHotKeyUnregister (int);
+bool BarHotKeyParse (BarHotKey_t* result, const char* value);
+
diff --git a/src/main.c b/src/main.c
index a75388e..6dacba5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -28,6 +28,7 @@ THE SOFTWARE.
#include "main.h"
#include "console.h"
+#include "hotkey.h"
#include "ui.h"
#include "ui_dispatch.h"
#include "ui_readline.h"
@@ -179,17 +180,61 @@ static void BarMainGetInitialStation (BarApp_t *app) {
}
}
+static int BarMainHandleVirtualKey(int virtualKey, void *userData)
+{
+ BarApp_t *app = (BarApp_t *)userData;
+
+ switch (virtualKey)
+ {
+ case /*VK_VOLUME_MUTE*/ 0xAD: return 0;
+ case /*VK_VOLUME_DOWN*/ 0xAE: return 0;//app->settings.keys[BAR_KS_VOLDOWN];
+ case /*VK_VOLUME_UP*/ 0xAF: return 0;//app->settings.keys[BAR_KS_VOLUP];
+ case /*VK_MEDIA_NEXT_TRACK*/ 0xB0: return 0;//app->settings.keys[BAR_KS_SKIP];
+ case /*VK_MEDIA_PREV_TRACK*/ 0xB1: return 0;
+ case /*VK_MEDIA_STOP*/ 0xB2: return 0;
+ case /*VK_MEDIA_PLAY_PAUSE*/ 0xB3: return 0;//app->settings.keys[BAR_KS_PLAYPAUSE];
+ case /*VK_LAUNCH_MAIL*/ 0xB4: return 0;
+ case /*VK_LAUNCH_MEDIA_SELECT*/ 0xB5: return 0;
+ case /*VK_LAUNCH_APP1*/ 0xB6: return 0;
+ case /*VK_LAUNCH_APP2*/ 0xB7: return 0;
+ default: return 0;
+ }
+}
+
+static void BarMainHotKeyHandler(int hotKeyId, void *userData)
+{
+ if (hotKeyId == 0)
+ return;
+
+ BarApp_t *app = (BarApp_t *)userData;
+
+ BarUiDispatch(app, app->settings.keys[hotKeyId], app->curStation, app->playlist, true,
+ BAR_DC_GLOBAL);
+}
+
/* wait for user rl
*/
static void BarMainHandleUserInput(BarApp_t *app)
{
char buf[2];
- if (BarReadline(buf, sizeof(buf), NULL, app->rl,
- BAR_RL_FULLRETURN | BAR_RL_NOECHO, 1) > 0)
+ size_t readSize = 0;
+
+ BarReadlineSetVirtualKeyHandler(app->rl, BarMainHandleVirtualKey, app);
+
+ readSize = BarReadline(buf, sizeof(buf), NULL, app->rl,
+ BAR_RL_FULLRETURN | BAR_RL_NOECHO, 1);
+
+ BarReadlineSetVirtualKeyHandler(app->rl, NULL, NULL);
+
+ if (readSize > 0)
{
BarUiDispatch(app, buf[0], app->curStation, app->playlist, true,
BAR_DC_GLOBAL);
}
+ else
+ {
+ BarHotKeyPool(BarMainHotKeyHandler, app);
+ }
}
/* fetch new playlist
@@ -375,6 +420,8 @@ int main(int argc, char **argv)
BarConsoleSetTitle(TITLE);
+ BarHotKeyInit();
+
/* init some things */
BarSettingsInit(&app.settings);
BarSettingsRead(&app.settings);
@@ -432,6 +479,7 @@ int main(int argc, char **argv)
HttpDestroy(app.http2);
BarPlayer2Destroy(app.player);
BarSettingsDestroy(&app.settings);
+ BarHotKeyDestroy();
BarConsoleDestroy();
return 0;
diff --git a/src/settings.c b/src/settings.c
index affb7f2..a2ce3fb 100644
--- a/src/settings.c
+++ b/src/settings.c
@@ -29,6 +29,7 @@ THE SOFTWARE.
#include "config.h"
#include "ui.h"
#include "ui_dispatch.h"
+#include "hotkey.h"
#include <stdlib.h>
#include <assert.h>
#include <memory.h>
@@ -340,6 +341,20 @@ void BarSettingsRead (BarSettings_t *settings) {
break;
}
}
+ } else if (memcmp ("hk_act_", key, 7) == 0) {
+ size_t i;
+ char* actionKey = key + 3;
+ /* keyboard shortcuts */
+ for (i = 0; i < BAR_KS_COUNT; i++) {
+ if (streq (dispatchActions[i].configKey, actionKey)) {
+ BarHotKey_t hk = { 0 };
+ if (BarHotKeyParse(&hk, val)) {
+ hk.id = i;
+ BarHotKeyRegister(hk);
+ }
+ break;
+ }
+ }
} else if (streq ("audio_quality", key)) {
if (streq (val, "low")) {
settings->audioQuality = PIANO_AQ_LOW;
diff --git a/src/ui_readline.c b/src/ui_readline.c
index 5d6b7a7..687258a 100644
--- a/src/ui_readline.c
+++ b/src/ui_readline.c
@@ -75,6 +75,8 @@ static inline int BarReadlineEncodeUtf8 (int codePoint, char* utf8) {
struct _BarReadline_t {
DWORD DefaultAttr;
+ BarVirtualKeyHandler VirtualKeyHandler;
+ void *VirtualKeyHandlerUserData;
};
void BarReadlineInit(BarReadline_t* rl) {
@@ -85,6 +87,11 @@ void BarReadlineInit(BarReadline_t* rl) {
void BarReadlineDestroy(BarReadline_t rl) {
}
+void BarReadlineSetVirtualKeyHandler(BarReadline_t rl, BarVirtualKeyHandler handler, void *ud) {
+ rl->VirtualKeyHandler = handler;
+ rl->VirtualKeyHandlerUserData = ud;
+}
+
/* return size of previous UTF-8 character
*/
static size_t BarReadlinePrevUtf8 (char *ptr) {
@@ -248,16 +255,11 @@ size_t BarReadline (char *buf, const size_t bufSize, const char *mask,
char encodedCodePoint[5];
int encodedCodePointLength;
- /*
- if (keyCode == VK_MEDIA_PLAY_PAUSE) {
- codePoint = 'p';
- PlaySoundA("SystemNotification", NULL, SND_ASYNC);
- }
- else if (keyCode == VK_MEDIA_NEXT_TRACK) {
- codePoint = 'n';
- PlaySoundA("SystemNotification", NULL, SND_ASYNC);
+ if (input->VirtualKeyHandler != NULL) {
+ int newCodePoint = input->VirtualKeyHandler(keyCode, input->VirtualKeyHandlerUserData);
+ if (newCodePoint != 0)
+ codePoint = newCodePoint;
}
- */
if (codePoint <= 0x1F)
break;
diff --git a/src/ui_readline.h b/src/ui_readline.h
index 83214b9..bb2772a 100644
--- a/src/ui_readline.h
+++ b/src/ui_readline.h
@@ -36,8 +36,11 @@ typedef enum {
typedef struct _BarReadline_t *BarReadline_t;
+typedef int (*BarVirtualKeyHandler)(int, void*);
+
void BarReadlineInit(BarReadline_t*);
void BarReadlineDestroy(BarReadline_t);
+void BarReadlineSetVirtualKeyHandler(BarReadline_t, BarVirtualKeyHandler, void *);
size_t BarReadline (char *, const size_t, const char *,
BarReadline_t, const BarReadlineFlags_t, int);
size_t BarReadlineStr (char *, const size_t,