diff --git a/examples/keylistener.cpp b/examples/keylistener.cpp index 3230402..9df92e6 100644 --- a/examples/keylistener.cpp +++ b/examples/keylistener.cpp @@ -28,16 +28,19 @@ #include #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 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 *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; diff --git a/src/application.h b/src/application.h index 9438240..f59eb9a 100644 --- a/src/application.h +++ b/src/application.h @@ -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(); diff --git a/src/interface.cpp b/src/interface.cpp index a0fca0b..4079564 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -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); + } } diff --git a/src/interface.h b/src/interface.h index 5b2acd1..b4ce42c 100644 --- a/src/interface.h +++ b/src/interface.h @@ -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 */ diff --git a/src/settings.h b/src/settings.h index fe28953..8c7264a 100644 --- a/src/settings.h +++ b/src/settings.h @@ -58,11 +58,14 @@ public: static inline Setting onDisconnect{"on-disconnect-script", ""}; // Key mapping section + static inline Setting keyPipe{"key-pipe-path", ""}; static inline KeySetting keySiri{"key-siri", 115, 5}; static inline KeySetting keyNightOn{"key-nightmode-on", 122, 16}; static inline KeySetting keyNightOff{"key-nightmode-off", 120, 17}; static inline KeySetting keyLeft{"key-left", 1073741904, 100}; + static inline KeySetting keyLeftExtra{"key-left-extra", 39, 100}; static inline KeySetting keyRight{"key-right", 1073741903, 101}; + static inline KeySetting keyRightExtra{"key-right-extra", 92, 101}; static inline KeySetting keyEnter{"key-enter", 13, 104}; static inline KeySetting keyEnterUp{"key-enterup", 0, 105}; static inline KeySetting keyBack{"key-back", 8, 106}; @@ -80,7 +83,20 @@ public: static inline KeySetting keyVideoRelease{"key-video-release", 98, 501}; static inline KeySetting keyNavFocus{"key-nav-focus", 110, 508}; static inline KeySetting keyNavRelease{"key-nav-release", 109, 509}; - static inline Setting keyPipe{"key-pipe-path", ""}; + + // Custom scripts + static inline Setting script1{"custom-script-1", ""}; + static inline Setting scriptKey1{"key-custom-script-1", 49}; + static inline Setting scriptName1{"custom-script-name-1", ""}; + static inline Setting script2{"custom-script-2", ""}; + static inline Setting scriptKey2{"key-custom-script-2", 50}; + static inline Setting scriptName2{"custom-script-name-2", ""}; + static inline Setting script3{"custom-script-3", ""}; + static inline Setting scriptKey3{"key-custom-script-3", 51}; + static inline Setting scriptName3{"custom-script-name-3", ""}; + static inline Setting script4{"custom-script-4", ""}; + static inline Setting scriptKey4{"key-custom-script-4", 52}; + static inline Setting scriptName4{"custom-script-name-4", ""}; // Debug section static inline Setting codecLowDelay{"decode-low-delay", true};