Skip to content

Commit

Permalink
Exec linux support. Threads for multiple keyboards
Browse files Browse the repository at this point in the history
  • Loading branch information
Azarattum committed Dec 29, 2020
1 parent 171005e commit 5c76586
Show file tree
Hide file tree
Showing 11 changed files with 185 additions and 79 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ if(NOT WIN32)
src/linux/server/uinput_keyboard.cpp
src/linux/server/uinput_keyboard.h
)
target_link_libraries(keymapperd usb-1.0 udev)
target_link_libraries(keymapperd usb-1.0 udev pthread)
else(NOT WIN32)
option(ENABLE_INTERCEPTION "Enable Interception" TRUE)
if(ENABLE_INTERCEPTION)
Expand Down
4 changes: 2 additions & 2 deletions src/config/ParseConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,12 +217,12 @@ KeySequence ParseConfig::parse_input(It it, It end) {

Action ParseConfig::parse_output(It it, It end) {
skip_space(&it, end);
trim_comment(it, &end);
if (*it == '/') {
std::string command = preprocess(it + 1, end);
std::string command = std::string(it + 1, end);
return {ActionType::Command, command, KeySequence({})};
}
try {
trim_comment(it, &end);
return {ActionType::Sequence, "", m_parse_sequence(preprocess(it, end), false)};
}
catch (const std::exception& ex) {
Expand Down
28 changes: 24 additions & 4 deletions src/linux/client/ipc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include <poll.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <pwd.h>
#include <string.h>

namespace {
auto g_pipe_broken = false;
Expand Down Expand Up @@ -36,6 +38,13 @@ namespace {
send(fd, event.state);
}
}

void send(int fd, const Action& action) {
send(fd, static_cast<uint8_t>(action.type));
send(fd, action.sequence);
send(fd, static_cast<uint8_t>(action.command.size()));
write_all(fd, action.command.c_str(), action.command.size());
}
} // namespace

int initialize_ipc(const char* fifo_filename) {
Expand All @@ -49,13 +58,25 @@ void shutdown_ipc(int fd) {
::close(fd);
}

bool send_name(int fd) {
uid_t uid = geteuid();
struct passwd *pw = getpwuid(uid);
char *name = 0;
if (pw)
name = pw->pw_name;

send(fd, static_cast<uint16_t>(strlen(name)));
write_all(fd, name, strlen(name));

return !g_pipe_broken;
}

bool send_config(int fd, const Config& config) {
// send mappings
send(fd, static_cast<uint16_t>(config.commands.size()));
for (const auto& command : config.commands) {
send(fd, command.input);
///!SEND HERE!
send(fd, command.default_mapping.sequence);
send(fd, command.default_mapping);
}

// send mapping overrides
Expand All @@ -73,8 +94,7 @@ bool send_config(int fd, const Config& config) {
send(fd, static_cast<uint16_t>(context_mappings.size()));
for (const auto& mapping : context_mappings) {
send(fd, static_cast<uint16_t>(mapping.first));
///!SEND HERE!
send(fd, mapping.second->output.sequence);
send(fd, mapping.second->output);
}
}
return !g_pipe_broken;
Expand Down
1 change: 1 addition & 0 deletions src/linux/client/ipc.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ struct Config;

int initialize_ipc(const char* fifo_filename);
void shutdown_ipc(int fd);
bool send_name(int fd);
bool send_config(int fd, const Config& config);
bool send_active_override_set(int fd, int index);
bool is_pipe_broken(int fd);
6 changes: 6 additions & 0 deletions src/linux/client/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ int main(int argc, char* argv[]) {
::sleep(1);
continue;
}
// send user's name
if (!send_name(ipc_fd)) {
shutdown_ipc(ipc_fd);
::sleep(1);
continue;
}
// initialize focused window detection
auto focused_window = create_focused_window();

Expand Down
42 changes: 36 additions & 6 deletions src/linux/server/ipc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,27 @@ namespace {
return true;
}

bool read(int fd, Action* action) {
auto type = uint8_t{ };
if (!read(fd, &type))
return false;
action->type = static_cast<ActionType>(type);
if (!read(fd, &(action->sequence)))
return false;

auto size = uint8_t{ };
if (!read(fd, &size))
return false;

char buffer[size + 1];
buffer[size] = 0;
read_all(fd, buffer, size);

action->command = std::string(buffer);

return true;
}

bool read_active_override_set(int fd, Stage& stage) {
auto activate_override_set = int8_t{ };
if (!read(fd, &activate_override_set))
Expand All @@ -73,7 +94,18 @@ void shutdown_ipc(int fd) {
::close(fd);
}

std::unique_ptr<Stage> read_config(int fd) {
char *read_name(int fd) {
auto length = uint16_t{ };
if (!read(fd, &length))
return 0;
char *name = new char[length + 1];
name[length] = 0;
read_all(fd, name, length);

return name;
}

std::shared_ptr<Stage> read_config(int fd) {
// receive commands
auto commmand_count = uint16_t{ };
if (!read(fd, &commmand_count))
Expand All @@ -83,9 +115,8 @@ std::unique_ptr<Stage> read_config(int fd) {
auto input = KeySequence();
Action output = {ActionType::Sequence, "", KeySequence()};
for (auto i = 0; i < commmand_count; ++i) {
///!READ HERE!
if (!read(fd, &input) ||
!read(fd, &output.sequence))
!read(fd, &output))
return nullptr;
mappings.push_back({ std::move(input), std::move(output) });
}
Expand All @@ -106,15 +137,14 @@ std::unique_ptr<Stage> read_config(int fd) {

for (auto j = 0; j < overrides_count; ++j) {
auto mapping_index = uint16_t{ };
///!READ HERE!
if (!read(fd, &mapping_index) ||
!read(fd, &output.sequence))
!read(fd, &output))
return nullptr;
overrides.push_back({ mapping_index, std::move(output) });
}
}

return std::make_unique<Stage>(
return std::make_shared<Stage>(
std::move(mappings), std::move(override_sets));
}

Expand Down
3 changes: 2 additions & 1 deletion src/linux/server/ipc.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ class Stage;

int initialize_ipc(const char* fifo_filename);
void shutdown_ipc(int fd);
std::unique_ptr<Stage> read_config(int fd);
char *read_name(int fd);
std::shared_ptr<Stage> read_config(int fd);
bool update_ipc(int fd, Stage& stage);
35 changes: 11 additions & 24 deletions src/linux/server/keyboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,24 +77,6 @@ bool grab_keyboard(int fd, bool grab) {
return (::ioctl(fd, EVIOCGRAB, (grab ? 1 : 0)) == 0);
}

bool is_real(int fd) {
char led = 0;
ioctl(fd, EVIOCGLED(1), &led);
led = led & 1;

input_event ev = {EV_LED, LED_NUML, (u_int16_t) led};
write(fd, &ev, sizeof(input_event));

fd_set set;
FD_ZERO(&set);
FD_SET(fd, &set);
timeval timeout = {1};
if (select(fd + 1, &set, NULL, NULL, &timeout) <= 0)
return false;
read(fd, &ev, sizeof(input_event));
return ev.type == EV_MSC;
}

int open_event_device(int index) {
const auto paths = { "/dev/input/event%d", "/dev/event%d" };
for (const auto path : paths) {
Expand All @@ -109,19 +91,24 @@ int open_event_device(int index) {
return -1;
}

int grab_first_keyboard() {
std::vector<int> grab_all_keyboards() {
std::vector<int> keyboards({});

for (auto i = 0; i < EVDEV_MINORS; ++i) {
const auto fd = open_event_device(i);
if (fd >= 0) {
if (is_keyboard(fd) &&
wait_until_keys_released(fd) &&
grab_keyboard(fd, true) &&
is_real(fd))
return fd;
::close(fd);
grab_keyboard(fd, true)) {
keyboards.push_back(fd);
}
else {
::close(fd);
}
}
}
return -1;

return keyboards;
}

void release_keyboard(int fd) {
Expand Down
3 changes: 2 additions & 1 deletion src/linux/server/keyboard.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <vector>
#pragma once

int grab_first_keyboard();
std::vector<int> grab_all_keyboards();
void release_keyboard(int fd);
bool read_event(int fd, int* type, int* code, int* value);
Loading

0 comments on commit 5c76586

Please sign in to comment.