ladybird/Userland/keymap.cpp
Tibor Nagy 790eaab6f5 Keymap+Base: Keycode fixes, remove workaround
Add missing keymap entries for the dollar sign and escape key and reformat
the Hungarian keymap.

Remove the workaround for "0x08", replace it with '\b'.

Fix the octal/hex mixup in the value of escape key. (033 != 0x33, 033 == 0x1B)
2020-01-03 01:20:47 +01:00

109 lines
2.9 KiB
C++

#include <AK/JsonObject.h>
#include <LibCore/CFile.h>
#include <stdio.h>
#include <Kernel/Syscall.h>
#include <AK/Optional.h>
#include <AK/StdLibExtras.h>
#include <AK/kmalloc.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
char* read_map(const JsonObject& json, const String& name)
{
if (!json.has(name))
return nullptr;
char* map = new char[80];
auto map_arr = json.get(name).as_array();
for (int i = 0; i < map_arr.size(); i++) {
auto key_value = map_arr.at(i).as_string();
char character = 0;
if (key_value.length() == 0) {
;
} else if (key_value.length() == 1) {
character = key_value.characters()[0];
} else if (key_value.length() == 4) {
// FIXME: Replace this workaround with "\u001B" in the keymap files
// after these kind of escape sequences are implemented in JsonParser.
if (key_value == "0x1B") {
character = 0x1B;
}
} else {
fprintf(stderr, "Unknown character in %s[%u] = %s.\n", name.characters(), i, key_value.characters());
ASSERT_NOT_REACHED();
}
map[i] = character;
}
return map;
}
RefPtr<CFile> open_keymap_file(String& filename)
{
auto file = CFile::construct(filename);
if (file->open(CIODevice::ReadOnly))
return file;
if (!filename.ends_with(".json")) {
StringBuilder full_path;
full_path.append("/res/keymaps/");
full_path.append(filename);
full_path.append(".json");
filename = full_path.to_string();
file = CFile::construct(filename);
if (file->open(CIODevice::ReadOnly))
return file;
}
return file;
}
int read_map_from_file(String& filename)
{
auto file = open_keymap_file(filename);
if (!file->is_open()) {
fprintf(stderr, "Failed to open %s: %s\n", filename.characters(), file->error_string());
return 1;
}
auto file_contents = file->read_all();
auto json = JsonValue::from_string(file_contents).as_object();
char* map = read_map(json, "map");
char* shift_map = read_map(json, "shift_map");
char* alt_map = read_map(json, "alt_map");
char* altgr_map = read_map(json, "altgr_map");
if (!altgr_map) {
// AltGr map was not found, using Alt map as fallback.
altgr_map = alt_map;
}
Syscall::SC_setkeymap_params params { map, shift_map, alt_map, altgr_map };
return syscall(SC_setkeymap, &params);
}
int main(int argc, char** argv)
{
if (argc != 2) {
fprintf(stderr, "usage: keymap <name|file>\n");
return 0;
}
String filename = argv[1];
int ret_val = read_map_from_file(filename);
if (ret_val == -EPERM)
fprintf(stderr, "Permission denied.\n");
if (ret_val == 0)
fprintf(stderr, "New keymap loaded from \"%s\".\n", filename.characters());
return ret_val;
}