From 765a437f1da0eddc7edac552f92ebf6757e6b2e8 Mon Sep 17 00:00:00 2001 From: Niellun Date: Mon, 3 Nov 2025 19:09:27 +0200 Subject: [PATCH] Option to send key presses from external app via named pipes --- settings.txt | 12 ++++++++ src/main.cpp | 5 +++- src/pipe_listener.cpp | 67 +++++++++++++++++++++++++++++++++++++++++++ src/pipe_listener.h | 22 ++++++++++++++ src/settings.h | 2 ++ 5 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 src/pipe_listener.cpp create mode 100644 src/pipe_listener.h diff --git a/settings.txt b/settings.txt index 115cc06..5f86687 100644 --- a/settings.txt +++ b/settings.txt @@ -147,6 +147,18 @@ #key-back = 0 #key-home = 0 +# Path for named pipe that keys are going to be listen on to. +# If empty pipe listening is disables. +# Example /tmp/fastcarplay_pipe +# Keys are bytes and defined directly as in protocol, examples: +# BTN_LEFT 100 +# BTN_RIGHT 101 +# BTN_SELECT_DOWN 104 +# BTN_SELECT_UP 105 +# BTN_BACK 106 +# BTN_HOME 200 +#key-pipe-path = + ############################################################################## # 4.Debug ############################################################################## diff --git a/src/main.cpp b/src/main.cpp index 414310a..8921240 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -20,6 +20,7 @@ extern "C" #include "decoder.h" #include "pcm_audio.h" #include "interface.h" +#include "pipe_listener.h" #define FRAME_DELAY_INACTIVE 200 @@ -102,7 +103,8 @@ void processKey(Protocol &protocol, SDL_Keysym key, RunParams ¶ms) else if (key.sym == Settings::keyHome) { protocol.sendKey(BTN_HOME); - } else + } + else { std::cout << "[Key] Unmapped key " << key.sym << std::endl; } @@ -228,6 +230,7 @@ void application() audioAux.start(&protocol.audioStreamAux, &audioMain); protocol.start(evtStatus, evtConnected); Interface interface(renderer); + PipeListener pipeListener(protocol, (Settings::keyPipe.value.length() > 2) ? Settings::keyPipe.value.c_str() : nullptr); std::cout << "[Main] Loop" << std::endl; uint32_t latestid = 0; diff --git a/src/pipe_listener.cpp b/src/pipe_listener.cpp new file mode 100644 index 0000000..d96eefa --- /dev/null +++ b/src/pipe_listener.cpp @@ -0,0 +1,67 @@ +#include "pipe_listener.h" + +#include +#include +#include +#include +#include + +PipeListener::PipeListener(Protocol &protocol, const char *path) + : _protocol(protocol), _path(path), _active(false) +{ + if(path == nullptr) + return; + unlink(_path); + if (mkfifo(_path, 0666) == -1) + if (errno != EEXIST) + { + std::cout << "[Pipe] Failed to create FIFO " << _path << ": " << std::strerror(errno) << std::endl; + return; + } + + _active = true; + _thread = std::thread(&PipeListener::loop, this); +} + +PipeListener::~PipeListener() +{ + if (!_active) + return; + // Signal the listening thread to exit by setting the active flag first. + _active = false; + int tmp = open(_path, O_WRONLY | O_NONBLOCK); + if (tmp >= 0) + { + write(tmp, "\0", 1); + close(tmp); + } + if (_thread.joinable()) + _thread.join(); + unlink(_path); +} + +void PipeListener::loop() +{ + std::cout << "[Pipe] Listening on " << _path << std::endl; + while (_active) + { + int fd = open(_path, O_RDONLY); + if (fd == -1) + { + std::cout << "[Pipe] Failed to open " << _path << ": " << std::strerror(errno) << std::endl; + return; + } + + char value; + while (_active && read(fd, &value, 1) > 0) + { + std::cout << "[Pipe] Received: " << (int)value << std::endl; + if (value != 0) + _protocol.sendKey(value); + } + + if (fd >= 0) + close(fd); + } + std::cout << "[Pipe] Finished on " << _path << std::endl; +} diff --git a/src/pipe_listener.h b/src/pipe_listener.h new file mode 100644 index 0000000..2111400 --- /dev/null +++ b/src/pipe_listener.h @@ -0,0 +1,22 @@ +#ifndef SRC_NAMED_PIPE_H +#define SRC_NAMED_PIPE_H + +#include +#include +#include "protocol.h" + +class PipeListener { +public: + PipeListener(Protocol &protocol, const char *path); + ~PipeListener(); + +private: + void loop(); + + Protocol &_protocol; + const char *_path; + bool _active; + std::thread _thread; +}; + +#endif // SRC_NAMED_PIPE_H diff --git a/src/settings.h b/src/settings.h index 1bf43a5..4fa4f84 100644 --- a/src/settings.h +++ b/src/settings.h @@ -49,6 +49,8 @@ public: static inline Setting keyEnter{"key-enter", 0}; static inline Setting keyBack{"key-back", 0}; static inline Setting keyHome{"key-home", 0}; + static inline Setting keyPipe{"key-pipe-path", ""}; + // Debug section static inline Setting protocolDebug{"protocol-debug", 0};