Skip to content

Commit

Permalink
Grabbing all keyboards
Browse files Browse the repository at this point in the history
  • Loading branch information
houmain committed Jan 21, 2021
1 parent d66bdd7 commit 3eccdfd
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 25 deletions.
55 changes: 37 additions & 18 deletions src/linux/server/keyboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,33 +91,52 @@ int open_event_device(int index) {
return -1;
}

int grab_first_keyboard() {
std::vector<int> grab_keyboards() {
auto fds = std::vector<int>();
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))
return fd;
::close(fd);
grab_keyboard(fd, true)) {
fds.push_back(fd);
}
else {
::close(fd);
}
}
}
return -1;
return fds;
}

void release_keyboard(int fd) {
if (fd >= 0) {
grab_keyboard(fd, false);
::close(fd);
}
void release_keyboards(const std::vector<int>& fds) {
for (auto fd : fds)
if (fd >= 0) {
grab_keyboard(fd, false);
::close(fd);
}
}

bool read_event(int fd, int* type, int* code, int* value) {
auto ev = input_event{ };
if (!read_all(fd, reinterpret_cast<char*>(&ev), sizeof(input_event)))
return false;
*type = ev.type;
*code = ev.code;
*value = ev.value;
return true;
bool read_event(const std::vector<int>& fds, int* type, int* code, int* value) {
auto rfds = fd_set{ };
FD_ZERO(&rfds);
auto max_fd = 0;
for (auto fd : fds) {
max_fd = std::max(max_fd, fd);
FD_SET(fd, &rfds);
}

if (::select(max_fd + 1, &rfds, nullptr, nullptr, nullptr) > 0)
for (auto fd : fds)
if (FD_ISSET(fd, &rfds)) {
auto ev = input_event{ };
if (!read_all(fd, reinterpret_cast<char*>(&ev), sizeof(input_event)))
return false;
*type = ev.type;
*code = ev.code;
*value = ev.value;
return true;
}

return false;
}
8 changes: 5 additions & 3 deletions src/linux/server/keyboard.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

int grab_first_keyboard();
void release_keyboard(int fd);
bool read_event(int fd, int* type, int* code, int* value);
#include <vector>

std::vector<int> grab_keyboards();
void release_keyboards(const std::vector<int>& fds);
bool read_event(const std::vector<int>& fds, int* type, int* code, int* value);
8 changes: 4 additions & 4 deletions src/linux/server/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ int main() {

const auto stage = read_config(ipc_fd);
if (stage) {
const auto event_fd = grab_first_keyboard();
if (event_fd >= 0) {
const auto event_fds = grab_keyboards();
if (!event_fds.empty()) {
const auto uinput_fd = create_uinput_keyboard(uinput_keyboard_name);
if (uinput_fd >= 0) {
// main loop
Expand All @@ -28,7 +28,7 @@ int main() {
auto type = 0;
auto code = 0;
auto value = 0;
if (!read_event(event_fd, &type, &code, &value))
if (!read_event(event_fds, &type, &code, &value))
break;

// let client update configuration
Expand All @@ -54,7 +54,7 @@ int main() {
}
destroy_uinput_keyboard(uinput_fd);
}
release_keyboard(event_fd);
release_keyboards(event_fds);
}
}
shutdown_ipc(ipc_fd);
Expand Down

0 comments on commit 3eccdfd

Please sign in to comment.