A cross-platform C++23 library with a platform-neutral public API and runtime-selected backends: - Input: Wayland virtual pointer/keyboard (Hyprland, wlroots), libei via the RemoteDesktop portal (GNOME, KDE), uinput, and Win32 SendInput - Capture: ScreenCast portal + PipeWire, and Win32 GDI - Windows: Hyprland IPC and Win32 enumeration - Monitors via wl_output/xdg-output and EnumDisplayMonitors - Optional OpenCV template matching (alvin::vision) Also adds the `alvin` CLI, Catch2 unit tests, install rules with find_package(Alvin) support, API docs (docs/API.md and the Obsidian vault), and README instructions for both ways of consuming the library. Windows backends are written but not yet compiled. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
61 lines
1.6 KiB
C++
61 lines
1.6 KiB
C++
#include <catch2/catch_test_macros.hpp>
|
|
#include <linux/input-event-codes.h>
|
|
|
|
#include "linux/keycodes.hpp"
|
|
#include "linux/xkb.hpp"
|
|
|
|
using namespace alvin;
|
|
using namespace alvin::linux_impl;
|
|
|
|
TEST_CASE("utf8 decoding") {
|
|
auto t = decodeUtf8("a\xc3\xa9\xe2\x82\xac\xf0\x9f\x98\x80");
|
|
REQUIRE(t);
|
|
CHECK(*t == U"aé€\U0001F600");
|
|
CHECK_FALSE(decodeUtf8("\xc3"));
|
|
CHECK_FALSE(decodeUtf8("\xff"));
|
|
}
|
|
|
|
TEST_CASE("us layout strokes") {
|
|
auto km = XkbKeymap::fromNames("us");
|
|
REQUIRE(km);
|
|
|
|
auto a = km->strokeFor(U'a');
|
|
REQUIRE(a);
|
|
CHECK(a->key == KEY_A);
|
|
CHECK(a->modifiers.empty());
|
|
|
|
auto upper = km->strokeFor(U'A');
|
|
REQUIRE(upper);
|
|
CHECK(upper->key == KEY_A);
|
|
CHECK(upper->modifiers == std::vector<std::uint32_t>{KEY_LEFTSHIFT});
|
|
|
|
auto bang = km->strokeFor(U'!');
|
|
REQUIRE(bang);
|
|
CHECK(bang->key == KEY_1);
|
|
|
|
CHECK(km->strokeFor(U'\n')->key == KEY_ENTER);
|
|
CHECK_FALSE(km->strokeFor(U'é')); // not on plain US
|
|
CHECK_FALSE(km->strokesFor(U"oké"));
|
|
}
|
|
|
|
TEST_CASE("synthesized keymaps compile and map codes 1..n") {
|
|
std::u32string alphabet = U"hé\U0001F600\n";
|
|
auto source = synthesizeKeymap(alphabet);
|
|
REQUIRE(source);
|
|
auto km = XkbKeymap::fromString(*source);
|
|
REQUIRE(km);
|
|
for (std::size_t i = 0; i < alphabet.size(); ++i) {
|
|
auto s = km->strokeFor(alphabet[i]);
|
|
REQUIRE(s);
|
|
CHECK(s->key == i + 1);
|
|
CHECK(s->modifiers.empty());
|
|
}
|
|
}
|
|
|
|
TEST_CASE("every key maps to an evdev code") {
|
|
for (int k = 1; k < static_cast<int>(Key::Count_); ++k) {
|
|
INFO("key index " << k);
|
|
CHECK(toEvdev(static_cast<Key>(k)) != 0);
|
|
}
|
|
}
|