mirror of
https://github.com/niellun/FastCarPlay.git
synced 2026-09-19 09:02:14 +02:00
Option to send key presses from external app via named pipes
This commit is contained in:
@@ -147,6 +147,18 @@
|
|||||||
#key-back = 0
|
#key-back = 0
|
||||||
#key-home = 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
|
# 4.Debug
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|||||||
+4
-1
@@ -20,6 +20,7 @@ extern "C"
|
|||||||
#include "decoder.h"
|
#include "decoder.h"
|
||||||
#include "pcm_audio.h"
|
#include "pcm_audio.h"
|
||||||
#include "interface.h"
|
#include "interface.h"
|
||||||
|
#include "pipe_listener.h"
|
||||||
|
|
||||||
#define FRAME_DELAY_INACTIVE 200
|
#define FRAME_DELAY_INACTIVE 200
|
||||||
|
|
||||||
@@ -102,7 +103,8 @@ void processKey(Protocol &protocol, SDL_Keysym key, RunParams ¶ms)
|
|||||||
else if (key.sym == Settings::keyHome)
|
else if (key.sym == Settings::keyHome)
|
||||||
{
|
{
|
||||||
protocol.sendKey(BTN_HOME);
|
protocol.sendKey(BTN_HOME);
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
std::cout << "[Key] Unmapped key " << key.sym << std::endl;
|
std::cout << "[Key] Unmapped key " << key.sym << std::endl;
|
||||||
}
|
}
|
||||||
@@ -228,6 +230,7 @@ void application()
|
|||||||
audioAux.start(&protocol.audioStreamAux, &audioMain);
|
audioAux.start(&protocol.audioStreamAux, &audioMain);
|
||||||
protocol.start(evtStatus, evtConnected);
|
protocol.start(evtStatus, evtConnected);
|
||||||
Interface interface(renderer);
|
Interface interface(renderer);
|
||||||
|
PipeListener pipeListener(protocol, (Settings::keyPipe.value.length() > 2) ? Settings::keyPipe.value.c_str() : nullptr);
|
||||||
|
|
||||||
std::cout << "[Main] Loop" << std::endl;
|
std::cout << "[Main] Loop" << std::endl;
|
||||||
uint32_t latestid = 0;
|
uint32_t latestid = 0;
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
#include "pipe_listener.h"
|
||||||
|
|
||||||
|
#include <cerrno>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#ifndef SRC_NAMED_PIPE_H
|
||||||
|
#define SRC_NAMED_PIPE_H
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
#include <atomic>
|
||||||
|
#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
|
||||||
@@ -49,6 +49,8 @@ public:
|
|||||||
static inline Setting<int> keyEnter{"key-enter", 0};
|
static inline Setting<int> keyEnter{"key-enter", 0};
|
||||||
static inline Setting<int> keyBack{"key-back", 0};
|
static inline Setting<int> keyBack{"key-back", 0};
|
||||||
static inline Setting<int> keyHome{"key-home", 0};
|
static inline Setting<int> keyHome{"key-home", 0};
|
||||||
|
static inline Setting<std::string> keyPipe{"key-pipe-path", ""};
|
||||||
|
|
||||||
|
|
||||||
// Debug section
|
// Debug section
|
||||||
static inline Setting<int> protocolDebug{"protocol-debug", 0};
|
static inline Setting<int> protocolDebug{"protocol-debug", 0};
|
||||||
|
|||||||
Reference in New Issue
Block a user