displayLayout and Rendering TUI library | 
          
| git clone git://git.dimitrijedobrota.com/display.git | 
| Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING | 
| commit | f025ceaf680e36c28cef477714c94ee94e52f48f | 
| parent | a218da041827f634ceb1315a75c8547320388d0c | 
| author | Dimitrije Dobrota < mail@dimitrijedobrota.com > | 
| date | Sat, 1 Feb 2025 21:27:43 +0100 | 
Enter and exit raw mode
| M | example/example.cpp | | | ++ - | 
| M | include/display/display.hpp | | | +++++ ---- | 
| M | source/display.cpp | | | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ---- | 
3 files changed, 76 insertions(+), 9 deletions(-)
diff --git a/ example/example.cpp b/ example/example.cpp
          @@ -6,7 +6,8 @@ 
          int main()
        
        
          {
            display::start();
            (void)std::getchar();
            while (true) {
            }
            display::stop();
          diff --git a/ include/display/display.hpp b/ include/display/display.hpp
@@ -1,11 +1,12 @@
#pragma once
          #include "display/display_export.hpp"
          namespace display
          {
          void start();
          void stop();
          using exit_f = void();
          void exit();
          void start(exit_f f_exit = exit);
          void stop(bool force = false);
          }  // namespace display
        
        diff --git a/ source/display.cpp b/ source/display.cpp
@@ -1,20 +1,85 @@
#include <iostream>
          #include <stdexcept>
          #include "display/display.hpp"
          #include <alec/alec.hpp>
          #include <termios.h>
          #include <unistd.h>
          namespace
          {
          template<const char* Val>
          inline void write()
          {
            ::write(STDIN_FILENO, Val, sizeof(Val));
          }
          }  // namespace
          namespace display
          {
          void start()
          static int start_count = 0;  // NOLINT
          static struct termios orig_termios;  // NOLINT
          void exit()
          {
            std::cout << alec::abuf_enable_v << alec::cursor_hide_v;
            stop(/* force= */ true);
          }
          void stop()
          void start(exit_f f_exit)
          {
            std::cout << alec::abuf_disable_v;
            if (start_count++ > 0) {
              // already started
              return;
            }
            if (isatty(STDIN_FILENO) == 0) {
              throw std::runtime_error("STDIN_FILENO is not associated with a terminal");
            }
            if (atexit(f_exit) != 0) {
              throw std::runtime_error("Can't register new exit function");
            }
            if (tcgetattr(STDIN_FILENO, &orig_termios) == -1) {
              throw std::runtime_error("Can't read termios");
            }
            struct termios raw = orig_termios;
            // NOLINTBEGIN
            raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
            raw.c_oflag &= ~(OPOST);
            raw.c_cflag |= (CS8);
            raw.c_lflag &= ~(ECHO | ICANON | IEXTEN);  // | ISIG
            raw.c_cc[VMIN] = 0;
            raw.c_cc[VTIME] = 1;
            // NOLINTEND
            /* put terminal in raw mode after flushing */
            if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) < 0) {
              throw std::runtime_error("Can't write termios");
            }
            write<alec::abuf_enable_v>();
            write<alec::cursor_hide_v>();
          }
          void stop(bool force)
          {
            if (!force && --start_count > 0) {
              // still need to keep open
              return;
            }
            if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios) < 0) {
              throw std::runtime_error("Can't write termios");
            }
            write<alec::cursor_show_v>();
          }
          }  // namespace display