Custom scripts, extra keys for pipe

This commit is contained in:
Niellune
2026-03-29 18:24:18 +03:00
parent 525d8168b6
commit a70bbec360
7 changed files with 188 additions and 34 deletions
+24 -15
View File
@@ -28,16 +28,19 @@
#include <signal.h>
#define FIFO_PATH "/tmp/fastcarplay_pipe"
#define LONG_PRESS 20
#define WIFI_SCRIPT "/opt/scripts/enable_ap.sh"
#define LONG_PRESS 40
#define EXTRA_LONG_PRESS 300
#define ADS1115_ADDRESS 0x48
#define FREQUENCY 50
#define FREQUENCY 100
#define BTN_LEFT 100
#define BTN_RIGHT 101
#define BTN_SELECT_DOWN 104
#define BTN_SELECT_UP 105
#define BTN_BACK 106
#define BTN_HOME 200
#define BTN_LEFT 39
#define BTN_RIGHT 92
#define BTN_SELECT_DOWN 13
#define BTN_SELECT_UP 61
#define BTN_BACK 8
#define BTN_HOME 104
#define WIFI_INFO 49
int fifo_fd = -1;
std::vector<double> voltages = {2.7, 1.9, 1.15, 0.45};
@@ -120,7 +123,7 @@ void send_key_code(uint8_t i)
// Callback examples
void callback0(int button_id, bool long_press)
{
//std::cout << "[Channel 0] Button " << button_id << " pressed. Long press: " << long_press << "\n";
// std::cout << "[Channel 0] Button " << button_id << " pressed. Long press: " << long_press << "\n";
if (button_id == 4)
{
if (long_press)
@@ -149,14 +152,20 @@ void callback0(int button_id, bool long_press)
void callback1(int button_id, bool long_press)
{
//std::cout << "[Channel 1] Button " << button_id << " pressed. Long press: " << long_press << "\n";
// std::cout << "[Channel 1] Button " << button_id << " pressed. Long press: " << long_press << "\n";
if (button_id == 3)
{
if (!long_press)
if (long_press)
{
std::cout << "Executing script \n";
std::system(WIFI_SCRIPT);
send_key_code(WIFI_INFO);
}
else
{
send_key_code(BTN_HOME);
}
}
}
}
double read_diff(int file_i2c, uint8_t mux)
@@ -198,7 +207,7 @@ int main()
}
ButtonProcessor proc0(callback0, LONG_PRESS);
ButtonProcessor proc1(callback1, LONG_PRESS);
ButtonProcessor proc1(callback1, EXTRA_LONG_PRESS);
constexpr double interval = 1.0 / FREQUENCY;
@@ -209,8 +218,8 @@ int main()
auto loop_start = std::chrono::steady_clock::now();
double v0 = read_diff(file_i2c, 0x04);
double v1 = read_diff(file_i2c, 0x05);
//if(v0<voltages[0] || v1<voltages[0])
// std::cout << "Channel 0: " << v0 << " Channel 1: " << v1;
// if(v0<voltages[0] || v1<voltages[0])
// std::cout << "Channel 0: " << v0 << " Channel 1: " << v1;
proc0.process_voltage(v0);
proc1.process_voltage(v1);
+35 -7
View File
@@ -188,13 +188,22 @@
# 4. Key mapping
##############################################################################
# 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 byte value [1..255]
# They are mapped to keys defined above
#key-pipe-path =
# Map keys to control
# If you set log-level and press keys you will see their codes in logs
#key-siri = 115 # S
#key-nightmode-on = 122 # Z
#key-nightmode-off = 120 # X
#key-left = 1073741904 # Left arrow
#key-left-extra = 39 # '
#key-right = 1073741903 # Right arrow
#key-right-extra = 92 # \
#key-enter = 13 # Enter
# For pipe to simulate key up after key-enter press
#key-enterup = 0 # unmapped by default
@@ -214,15 +223,34 @@
#key-nav-focus = 110 # N
#key-nav-release = 109 # M
# 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 byte value [1..255]
# They are mapped to keys defined above
#key-pipe-path =
##############################################################################
# 5. Custom scripts
##############################################################################
# Set custom script to be executed and/or message to be shown when key is pressed
# Custom script 1
#custom-script-1 =
#key-custom-script-1 = 49 # 1
#custom-script-name-1 =
# Custom script 2
#custom-script-2 =
#key-custom-script-2 = 50 # 2
#custom-script-name-2 =
# Custom script 3
#custom-script-3 =
#key-custom-script-3 = 51 # 3
#custom-script-name-3 =
# Custom script 4
#custom-script-4 =
#key-custom-script-4 = 52 # 4
#custom-script-name-4 =
##############################################################################
# 5.Debug
# 6.Debug
##############################################################################
# Enable FFMPEG AV_CODEC_FLAG_LOW_DELAY for HW decoder.
+64 -3
View File
@@ -13,13 +13,16 @@
#include "interface.h"
#include "decoder.h"
#include "pcm_audio.h"
#include "common/functions.h"
static KeySetting<int> *keyMap[] = {
&Settings::keySiri,
&Settings::keyNightOn,
&Settings::keyNightOff,
&Settings::keyLeft,
&Settings::keyLeftExtra,
&Settings::keyRight,
&Settings::keyRightExtra,
&Settings::keyEnter,
&Settings::keyEnterUp,
&Settings::keyBack,
@@ -208,6 +211,47 @@ bool Application::processSystemEvent(const SDL_Event &e)
_state.requestFrame = 1;
}
}
bool script = false;
std::string name = "";
std::string scriptPath = "";
if (e.key.keysym.sym == Settings::scriptKey1)
{
script = true;
name = Settings::scriptName1;
scriptPath = Settings::script1;
}
if (e.key.keysym.sym == Settings::scriptKey2)
{
script = true;
name = Settings::scriptName2;
scriptPath = Settings::script2;
}
if (e.key.keysym.sym == Settings::scriptKey3)
{
script = true;
name = Settings::scriptName3;
scriptPath = Settings::script3;
}
if (e.key.keysym.sym == Settings::scriptKey4)
{
script = true;
name = Settings::scriptName4;
scriptPath = Settings::script4;
}
if (script)
{
if (name.length() > 0)
{
_state.toast = name;
_state.showToast = 1;
}
if (scriptPath.length() > 1)
{
execute(scriptPath.c_str());
}
}
}
return false;
@@ -339,6 +383,23 @@ void Application::loop()
{
bool newFrame = false;
if (_state.showToast > 0)
{
if (_state.showToast == 1)
{
interface.showToast(_state.toast);
_state.showToast = SDL_GetTicks();
_state.dirty = true;
}
if (SDL_GetTicks() - _state.showToast >= TOAST_TIME * 1000)
{
interface.hideToast();
_state.showToast = 0;
_state.dirty = true;
}
}
if (protocol.state() != _state.latestState)
{
// On connect/disconnect
@@ -383,7 +444,7 @@ void Application::loop()
{
log_d("Request screen update");
protocol.send(Message::Control(BTN_SCREEN_REFRESH));
if (_state.requestFrame > Settings::forceRedraw*2)
if (_state.requestFrame > Settings::forceRedraw * 2)
_state.requestFrame = 0;
}
}
@@ -498,8 +559,8 @@ const std::string Application::status() const
{
SDL_RendererInfo info;
SDL_GetRenderDriverInfo(i, &info);
out << " ";
if(cr.name == info.name)
out << " ";
if (cr.name == info.name)
out << "[" << info.name << "]";
else
out << info.name;
+3 -1
View File
@@ -8,7 +8,7 @@
#include "protocol/connection.h"
#include "renderer.h"
#define REDRAW_REQUEST 5
#define TOAST_TIME 3
class Application
{
@@ -27,6 +27,8 @@ private:
bool fullscreen = false;
bool mouseDown = false;
int8_t latestState = PROTOCOL_STATUS_UNKNOWN;
uint32_t showToast = false;
std::string toast = "";
};
bool setAudioDriver();
+39 -7
View File
@@ -9,8 +9,10 @@ Interface::Interface(SDL_Renderer *renderer)
: Renderer(renderer),
_state(0),
_debug(false),
_toast(false),
_textStatus(font, font_len, Settings::fontSize),
_textDebug(font, font_len, 16),
_textToast(font, font_len, Settings::fontSize*0.75),
_mainImage(background, background_len)
{
}
@@ -34,6 +36,9 @@ bool Interface::render(AVFrame *frame)
(this->*_render)(frame);
SDL_RenderCopy(_renderer, _texture, &_sourceRect, nullptr);
if (_toast)
drawToast();
#ifndef NDEBUG
if (_debug)
{
@@ -89,6 +94,9 @@ bool Interface::drawHome(bool force, int state, std::string name)
if (drawText)
_textStatus.draw(_renderer, (width - _textStatus.width * Settings::aspectCorrection) / 2, height * 0.85 - _textStatus.height);
if (_toast)
drawToast();
if (_debug)
{
drawDebug();
@@ -105,6 +113,18 @@ void Interface::debug(const char *text)
_debug = true;
}
void Interface::showToast(const std::string &text)
{
_toastText = text;
_toast = true;
}
void Interface::hideToast()
{
_toastText.clear();
_toast = false;
}
void Interface::drawDebug()
{
if (_debugText.empty())
@@ -113,10 +133,6 @@ void Interface::drawDebug()
constexpr int padding = 8;
constexpr int lineSpacing = 2;
const SDL_Color debugColor = {255, 255, 255, 255};
SDL_BlendMode previousBlendMode;
Uint8 previousR, previousG, previousB, previousA;
SDL_GetRenderDrawBlendMode(_renderer, &previousBlendMode);
SDL_GetRenderDrawColor(_renderer, &previousR, &previousG, &previousB, &previousA);
SDL_SetRenderDrawBlendMode(_renderer, SDL_BLENDMODE_BLEND);
SDL_SetRenderDrawColor(_renderer, 0, 0, 0, 150);
@@ -144,7 +160,23 @@ void Interface::drawDebug()
lineStart = lineEnd + 1;
}
SDL_SetRenderDrawColor(_renderer, previousR, previousG, previousB, previousA);
SDL_SetRenderDrawBlendMode(_renderer, previousBlendMode);
}
void Interface::drawToast()
{
if (_toastText.empty())
return;
int padding = Settings::fontSize*0.3;
int width, height;
SDL_GetRendererOutputSize(_renderer, &width, &height);
SDL_SetRenderDrawBlendMode(_renderer, SDL_BLENDMODE_BLEND);
SDL_SetRenderDrawColor(_renderer, 0, 0, 0, 150);
if (_textToast.prepare(_renderer, _toastText, color4))
{
SDL_Rect backgroundRect = {0, 0, width, _textToast.height + padding * 2};
SDL_RenderFillRect(_renderer, &backgroundRect);
_textToast.draw(_renderer, (width - _textToast.width * Settings::aspectCorrection) / 2, padding);
}
}
+6
View File
@@ -12,16 +12,22 @@ public:
bool render(AVFrame *frame);
bool drawHome(bool force, int state, std::string name);
void debug(const char *text);
void showToast(const std::string &text);
void hideToast();
private:
void drawDebug();
void drawToast();
int _state;
bool _debug;
bool _toast;
RendererText _textStatus;
RendererText _textDebug;
RendererText _textToast;
RendererImage _mainImage;
std::string _debugText;
std::string _toastText;
};
#endif /* SRC_INTERFACE */
+17 -1
View File
@@ -58,11 +58,14 @@ public:
static inline Setting<std::string> onDisconnect{"on-disconnect-script", ""};
// Key mapping section
static inline Setting<std::string> keyPipe{"key-pipe-path", ""};
static inline KeySetting<int> keySiri{"key-siri", 115, 5};
static inline KeySetting<int> keyNightOn{"key-nightmode-on", 122, 16};
static inline KeySetting<int> keyNightOff{"key-nightmode-off", 120, 17};
static inline KeySetting<int> keyLeft{"key-left", 1073741904, 100};
static inline KeySetting<int> keyLeftExtra{"key-left-extra", 39, 100};
static inline KeySetting<int> keyRight{"key-right", 1073741903, 101};
static inline KeySetting<int> keyRightExtra{"key-right-extra", 92, 101};
static inline KeySetting<int> keyEnter{"key-enter", 13, 104};
static inline KeySetting<int> keyEnterUp{"key-enterup", 0, 105};
static inline KeySetting<int> keyBack{"key-back", 8, 106};
@@ -80,7 +83,20 @@ public:
static inline KeySetting<int> keyVideoRelease{"key-video-release", 98, 501};
static inline KeySetting<int> keyNavFocus{"key-nav-focus", 110, 508};
static inline KeySetting<int> keyNavRelease{"key-nav-release", 109, 509};
static inline Setting<std::string> keyPipe{"key-pipe-path", ""};
// Custom scripts
static inline Setting<std::string> script1{"custom-script-1", ""};
static inline Setting<int> scriptKey1{"key-custom-script-1", 49};
static inline Setting<std::string> scriptName1{"custom-script-name-1", ""};
static inline Setting<std::string> script2{"custom-script-2", ""};
static inline Setting<int> scriptKey2{"key-custom-script-2", 50};
static inline Setting<std::string> scriptName2{"custom-script-name-2", ""};
static inline Setting<std::string> script3{"custom-script-3", ""};
static inline Setting<int> scriptKey3{"key-custom-script-3", 51};
static inline Setting<std::string> scriptName3{"custom-script-name-3", ""};
static inline Setting<std::string> script4{"custom-script-4", ""};
static inline Setting<int> scriptKey4{"key-custom-script-4", 52};
static inline Setting<std::string> scriptName4{"custom-script-name-4", ""};
// Debug section
static inline Setting<bool> codecLowDelay{"decode-low-delay", true};