Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compile keymap into OSARA to replace Reaper default shortcuts #728

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/archBuild_sconscript
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import os.path
from makeConfigRc import makeConfigRc
from tools.kb2header import buildKeymapHeader

Import("env")

Expand Down Expand Up @@ -79,6 +80,7 @@ if env["PLATFORM"] == "win32":
"Advapi32",
"UIAutomationCore",
]
keymapFile = '#config/windows/reaper-kb.ini'

else: # Mac
swellDir = env.Dir("#include/WDL/WDL/swell")
Expand Down Expand Up @@ -113,6 +115,7 @@ else: # Mac
"config.rc",
[[php, "include/WDL/WDL/swell/swell_resgen.php", "$SOURCE"]])
env.Depends("reaper_osara.cpp", [res, dialogRes])
keymapFile = '#config/mac/reaper-kb.ini'

def addExternalSources(dir, files):
dir = env.Dir(dir)
Expand All @@ -132,6 +135,8 @@ addExternalSources("#include/tinygettext/src", (
))
addExternalSources("#include/fmt/src", ("format.cc", "os.cc"))

env.Command('osara_keymap.h', keymapFile, buildKeymapHeader)

env.SharedLibrary(
target="reaper_osara%s" % env["libSuffix"],
source=sources, LIBS=libs,
Expand Down
25 changes: 22 additions & 3 deletions src/reaper_osara.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
#include "buildVersion.h"
#include "fxChain.h"
#include "translation.h"

using namespace std;
#include "osara_keymap.h"
using namespace fmt::literals;

HINSTANCE pluginHInstance;
Expand Down Expand Up @@ -4026,7 +4026,7 @@ void cmdReportRegionMarkerItems(Command* command) {

Command COMMANDS[] = {
// Commands we want to intercept.
{MAIN_SECTION, {{0, 0, 40285}, NULL}, NULL, cmdGoToNextTrack}, // Track: Go to next track
{MAIN_SECTION, {{0, 'Y', 40285}, NULL}, NULL, cmdGoToNextTrack}, // Track: Go to next track
{MAIN_SECTION, {{0, 0, 40286}, NULL}, NULL, cmdGoToPrevTrack}, // Track: Go to previous track
{MAIN_SECTION, {{0, 0, 40287}, NULL}, NULL, cmdGoToNextTrackKeepSel}, // Track: Go to next track (leaving other tracks selected)
{MAIN_SECTION, {{0, 0, 40288}, NULL}, NULL, cmdGoToPrevTrackKeepSel}, // Track: Go to previous track (leaving other tracks selected)
Expand Down Expand Up @@ -4422,6 +4422,25 @@ bool handleMainCommandFallback(int command, int flag) {

IReaperControlSurface* surface = nullptr;

void initKeyMap() {
for(auto& [secId, keys, namedKeys] : osaraKeySections) {
auto sec = SectionFromUniqueID(secId);
if(!sec) {
continue;
}
keys.reserve(keys.size() + namedKeys.size());
for(auto& key : namedKeys) {
int cmd = NamedCommandLookup(key.cmd);
if(cmd <= 0){
continue;
}
keys.push_back({key.key, cmd, key.flags});
}
sec->def_keys_cnt = keys.size();
sec->def_keys = keys.data();
}
}

// Initialisation that must be done after REAPER_PLUGIN_ENTRYPOINT;
// e.g. because it depends on stuff registered by other plug-ins.
void CALLBACK delayedInit(HWND hwnd, UINT msg, UINT_PTR event, DWORD time) {
Expand All @@ -4439,7 +4458,6 @@ void CALLBACK delayedInit(HWND hwnd, UINT msg, UINT_PTR event, DWORD time) {
}
KillTimer(NULL, event);
}

#ifdef _WIN32

void annotateAccRole(HWND hwnd, long role) {
Expand Down Expand Up @@ -4623,6 +4641,7 @@ REAPER_PLUGIN_DLL_EXPORT int REAPER_PLUGIN_ENTRYPOINT(REAPER_PLUGIN_HINSTANCE hI
#ifdef _WIN32
keyboardHook = SetWindowsHookEx(WH_KEYBOARD, keyboardHookProc, nullptr, guiThread);
#endif
initKeyMap();
return 1;

} else {
Expand Down
78 changes: 78 additions & 0 deletions tools/kb2header.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
from . import sortKeymap

def buildKeyList(fn):
lines = open(fn, encoding='utf-8').readlines()
numericCommands = {
0:[], 100:[], 102:[], 103:[],
32060:[], 32061:[], 32062:[], 32063:[]}
namedCommands = {
0:[], 100:[], 102:[], 103:[],
32060:[], 32061:[], 32062:[], 32063:[]}
for line in lines:
key, match = sortKeymap.parseLine(line)
if key != 'KEY':
continue
section = int(match.group('section'))
modifiers = int(match.group('modifiers'))
key = int(match.group('key'))
id=match.group('actionId')
if id == 0:
continue
if id[0] == '_':
namedCommands[section].append((key, id, modifiers))
else:
numericCommands[section].append((key, int(id), modifiers))
return (numericCommands, namedCommands)

def formatArray(scList, isCustom):
s = ""
for sc in scList:
if s:
s += ',\n\t'
if isCustom:
s += f'{{{sc[0]}, "{sc[1]}", {sc[2]}}}'
else:
s += f'{{{sc[0]}, {sc[1]}, {sc[2]}}}'
return s

def buildKeymapHeader(target, source, env=None):
target = target[0].path
source = source[0].path
s = """
struct NamedKeyBindingInfo {
int key;
const char* cmd;
int flags;
};

"""
import sys
a,b = buildKeyList(source)
sections = ''
for section in a:
s += f'vector<KbdKeyBindingInfo> osaraKeySection{section}{{\n'
s += formatArray(a[section], False)
s+= '\n};\n'
if sections:
sections += ',\n'
sections += f'\t{{{section}, osaraKeySection{section}, osaraNamedKeySection{section}}}'
for section in b:
s += f'vector<NamedKeyBindingInfo> osaraNamedKeySection{section}{{\n'
s += formatArray(b[section], True)
s+= '\n};\n'

s += """
struct OsaraKeySection {
int section;
vector<KbdKeyBindingInfo>& keys;
vector<NamedKeyBindingInfo>& namedKeys;
};
vector<OsaraKeySection> osaraKeySections {
"""
s += sections;
s += """
};
"""


open(target, 'x', encoding='utf-8').write(s)