From 3518c8c0d9f4f466470c7da795097890c45d7c21 Mon Sep 17 00:00:00 2001 From: magiblot Date: Tue, 22 Oct 2024 17:17:21 +0200 Subject: [PATCH] platform: rename ConsoleCtl --- include/tvision/internal/ansiwrit.h | 8 +- .../tvision/internal/{stdioctl.h => conctl.h} | 20 ++--- include/tvision/internal/far2l.h | 4 +- include/tvision/internal/linuxcon.h | 11 +-- include/tvision/internal/ncurdisp.h | 4 +- include/tvision/internal/ncursinp.h | 6 +- include/tvision/internal/platform.h | 1 - include/tvision/internal/termdisp.h | 10 ++- include/tvision/internal/termio.h | 16 ++-- include/tvision/internal/unixcon.h | 9 +- include/tvision/internal/win32con.h | 22 ++--- source/platform/ansiwrit.cpp | 3 +- source/platform/{stdioctl.cpp => conctl.cpp} | 70 +++++++--------- source/platform/far2l.cpp | 9 +- source/platform/linuxcon.cpp | 8 +- source/platform/ncurdisp.cpp | 12 +-- source/platform/ncursinp.cpp | 18 ++-- source/platform/platfcon.cpp | 11 +-- source/platform/platform.cpp | 7 +- source/platform/termdisp.cpp | 7 +- source/platform/termio.cpp | 42 +++++----- source/platform/unixcon.cpp | 12 +-- source/platform/win32con.cpp | 84 ++++++++++--------- 23 files changed, 199 insertions(+), 195 deletions(-) rename include/tvision/internal/{stdioctl.h => conctl.h} (78%) rename source/platform/{stdioctl.cpp => conctl.cpp} (89%) diff --git a/include/tvision/internal/ansiwrit.h b/include/tvision/internal/ansiwrit.h index 28121d68..0b624c56 100644 --- a/include/tvision/internal/ansiwrit.h +++ b/include/tvision/internal/ansiwrit.h @@ -71,7 +71,7 @@ struct TermAttr // AnsiScreenWriter allows printing characters and color attributes directly // to screen using ANSI escape codes. -class StdioCtl; +class ConsoleCtl; class AnsiScreenWriter { @@ -91,7 +91,7 @@ class AnsiScreenWriter void reserve(size_t) noexcept; }; - const StdioCtl &io; + ConsoleCtl &con; Buffer buf; TermAttr lastAttr {}; @@ -100,8 +100,8 @@ class AnsiScreenWriter public: - AnsiScreenWriter(StdioCtl &aIo) noexcept : - io(aIo) + AnsiScreenWriter(ConsoleCtl &aCon) noexcept : + con(aCon) { } diff --git a/include/tvision/internal/stdioctl.h b/include/tvision/internal/conctl.h similarity index 78% rename from include/tvision/internal/stdioctl.h rename to include/tvision/internal/conctl.h index 870a6fb1..a8e42dea 100644 --- a/include/tvision/internal/stdioctl.h +++ b/include/tvision/internal/conctl.h @@ -1,5 +1,5 @@ -#ifndef TVISION_STDIOCTL_H -#define TVISION_STDIOCTL_H +#ifndef TVISION_CONCTL_H +#define TVISION_CONCTL_H #include #include @@ -11,7 +11,7 @@ namespace tvision { -class StdioCtl final +class ConsoleCtl { #ifdef _WIN32 enum { input = 0, startupOutput = 1, activeOutput = 2 }; @@ -27,21 +27,21 @@ class StdioCtl final bool ownsFiles {false}; #endif // _WIN32 - static StdioCtl *instance; + static ConsoleCtl *instance; - StdioCtl() noexcept; - ~StdioCtl(); + ConsoleCtl() noexcept; + ~ConsoleCtl(); public: - // On Windows, the StdioCtl instance is created every time the alternate + // On Windows, the ConsoleCtl instance is created every time the alternate // screen buffer is enabled and it is destroyed when restoring the console. - // On Unix, the StdioCtl instance is created just once at the beginning + // On Unix, the ConsoleCtl instance is created just once at the beginning // of the program execution (in static initialization) and destroyed when // exiting the program. // Creates a global instance if none exists, and returns it. - static StdioCtl &getInstance() noexcept; + static ConsoleCtl &getInstance() noexcept; // Destroys the global instance if it exists. static void destroyInstance() noexcept; @@ -65,4 +65,4 @@ class StdioCtl final } //namespace tvision -#endif // TVISION_STDIOCTL_H +#endif // TVISION_CONCTL_H diff --git a/include/tvision/internal/far2l.h b/include/tvision/internal/far2l.h index 44094d4d..76bf0d00 100644 --- a/include/tvision/internal/far2l.h +++ b/include/tvision/internal/far2l.h @@ -12,8 +12,8 @@ namespace tvision ParseResult parseFar2lAnswer(GetChBuf &, TEvent &, InputState &) noexcept; ParseResult parseFar2lInput(GetChBuf &, TEvent &, InputState &) noexcept; -bool setFar2lClipboard(StdioCtl &, TStringView, InputState &) noexcept; -bool requestFar2lClipboard(StdioCtl &, InputState &) noexcept; +bool setFar2lClipboard(ConsoleCtl &, TStringView, InputState &) noexcept; +bool requestFar2lClipboard(ConsoleCtl &, InputState &) noexcept; } // namespace tvision diff --git a/include/tvision/internal/linuxcon.h b/include/tvision/internal/linuxcon.h index cde02272..4989adfd 100644 --- a/include/tvision/internal/linuxcon.h +++ b/include/tvision/internal/linuxcon.h @@ -11,18 +11,19 @@ struct TEvent; namespace tvision { +class ConsoleCtl; class SigwinchHandler; class GpmInput; struct InputState; struct LinuxConsoleInput final : public EventSource { - StdioCtl &io; + ConsoleCtl &con; InputStrategy &input; - LinuxConsoleInput(StdioCtl &aIo, InputStrategy &aInput) noexcept : + LinuxConsoleInput(ConsoleCtl &aCon, InputStrategy &aInput) noexcept : EventSource(aInput.handle), - io(aIo), + con(aCon), input(aInput) { } @@ -51,9 +52,9 @@ class LinuxConsoleStrategy : public ConsoleStrategy public: // Pre: 'io.isLinuxConsole()' returns 'true'. - // The lifetime of 'io' and 'displayBuf' must exceed that of the returned object. + // The lifetime of 'con' and 'displayBuf' must exceed that of the returned object. // Takes ownership over 'inputState', 'display' and 'input'. - static LinuxConsoleStrategy &create( StdioCtl &io, + static LinuxConsoleStrategy &create( ConsoleCtl &con, DisplayBuffer &displayBuf, InputState &inputState, DisplayStrategy &display, diff --git a/include/tvision/internal/ncurdisp.h b/include/tvision/internal/ncurdisp.h index a7cbf016..0b527127 100644 --- a/include/tvision/internal/ncurdisp.h +++ b/include/tvision/internal/ncurdisp.h @@ -15,8 +15,8 @@ class NcursesDisplay : public TerminalDisplay { public: - // The lifetime of 'io' exceeds that of 'this'. - NcursesDisplay(StdioCtl &io) noexcept; + // The lifetime of 'con' exceeds that of 'this'. + NcursesDisplay(ConsoleCtl &con) noexcept; ~NcursesDisplay(); private: diff --git a/include/tvision/internal/ncursinp.h b/include/tvision/internal/ncursinp.h index 8ef76c7d..6f1416a4 100644 --- a/include/tvision/internal/ncursinp.h +++ b/include/tvision/internal/ncursinp.h @@ -30,7 +30,7 @@ class NcursesInput : public InputStrategy enum : char { KEY_ESC = '\x1B' }; enum { readTimeoutMs = 10 }; - StdioCtl &io; + ConsoleCtl &con; InputState &state; bool mouseEnabled; NcursesInputGetter in; @@ -44,8 +44,8 @@ class NcursesInput : public InputStrategy public: - // Lifetimes of 'io', 'display' and 'state' must exceed that of 'this'. - NcursesInput(StdioCtl &io, NcursesDisplay &display, InputState &state, bool mouse) noexcept; + // Lifetimes of 'con', 'display' and 'state' must exceed that of 'this'. + NcursesInput(ConsoleCtl &con, NcursesDisplay &display, InputState &state, bool mouse) noexcept; ~NcursesInput(); bool getEvent(TEvent &ev) noexcept override; diff --git a/include/tvision/internal/platform.h b/include/tvision/internal/platform.h index 4cadf95c..7d26a46e 100644 --- a/include/tvision/internal/platform.h +++ b/include/tvision/internal/platform.h @@ -4,7 +4,6 @@ #define Uses_TPoint #define Uses_TColorAttr #include -#include #include #include #include diff --git a/include/tvision/internal/termdisp.h b/include/tvision/internal/termdisp.h index 9b80ba19..4b79806c 100644 --- a/include/tvision/internal/termdisp.h +++ b/include/tvision/internal/termdisp.h @@ -6,6 +6,8 @@ namespace tvision { +class ConsoleCtl; + // Terminal quirk flags. const uint @@ -39,7 +41,7 @@ class TerminalDisplay : public DisplayStrategy protected: - StdioCtl &io; + ConsoleCtl &con; TermCap termcap; // The subclass must invoke this in the constructor. @@ -50,9 +52,9 @@ class TerminalDisplay : public DisplayStrategy public: - // The lifetime of 'aIo' exceeds that of 'this'. - TerminalDisplay(StdioCtl &aIo) noexcept : - io(aIo) + // The lifetime of 'aCon' exceeds that of 'this'. + TerminalDisplay(ConsoleCtl &aCon) noexcept : + con(aCon) { } diff --git a/include/tvision/internal/termio.h b/include/tvision/internal/termio.h index 1827ba98..ac41d181 100644 --- a/include/tvision/internal/termio.h +++ b/include/tvision/internal/termio.h @@ -10,7 +10,7 @@ namespace tvision { -class StdioCtl; +class ConsoleCtl; struct Far2lState { @@ -120,15 +120,15 @@ inline uint CSIData::getValue(uint i, uint defaultValue) const noexcept namespace TermIO { - void mouseOn(StdioCtl &) noexcept; - void mouseOff(StdioCtl &) noexcept; - void keyModsOn(StdioCtl &) noexcept; - void keyModsOff(StdioCtl &) noexcept; + void mouseOn(ConsoleCtl &) noexcept; + void mouseOff(ConsoleCtl &) noexcept; + void keyModsOn(ConsoleCtl &) noexcept; + void keyModsOff(ConsoleCtl &) noexcept; void normalizeKey(KeyDownEvent &keyDown) noexcept; - bool setClipboardText(StdioCtl &, TStringView, InputState &) noexcept; - bool requestClipboardText(StdioCtl &, void (&)(TStringView), InputState &) noexcept; + bool setClipboardText(ConsoleCtl &, TStringView, InputState &) noexcept; + bool requestClipboardText(ConsoleCtl &, void (&)(TStringView), InputState &) noexcept; ParseResult parseEvent(GetChBuf&, TEvent&, InputState&) noexcept; ParseResult parseEscapeSeq(GetChBuf&, TEvent&, InputState&) noexcept; @@ -145,7 +145,7 @@ namespace TermIO ParseResult parseWin32InputModeKeyOrEscapeSeq(const CSIData &, InputGetter&, TEvent&, InputState&) noexcept; char *readUntilBelOrSt(GetChBuf &) noexcept; - void consumeUnprocessedInput(StdioCtl &, InputGetter &, InputState &) noexcept; + void consumeUnprocessedInput(ConsoleCtl &, InputGetter &, InputState &) noexcept; } } // namespace tvision diff --git a/include/tvision/internal/unixcon.h b/include/tvision/internal/unixcon.h index b9013c2b..34a61b9f 100644 --- a/include/tvision/internal/unixcon.h +++ b/include/tvision/internal/unixcon.h @@ -9,6 +9,7 @@ namespace tvision { +class ConsoleCtl; class SigwinchHandler; struct InputState; class DisplayBuffer; @@ -17,20 +18,20 @@ class UnixConsoleStrategy : public ConsoleStrategy { StderrRedirector errRedir; - StdioCtl &io; + ConsoleCtl &con; DisplayBuffer &displayBuf; InputState &inputState; SigwinchHandler *sigwinch; - UnixConsoleStrategy( DisplayStrategy &, InputStrategy &, StdioCtl &, + UnixConsoleStrategy( DisplayStrategy &, InputStrategy &, ConsoleCtl &, DisplayBuffer &, InputState &, SigwinchHandler * ) noexcept; public: - // The lifetime of 'io' and 'displayBuf' must exceed that of the returned object. + // The lifetime of 'con' and 'displayBuf' must exceed that of the returned object. // Takes ownership over 'inputState', 'display' and 'input'. - static UnixConsoleStrategy &create( StdioCtl &io, + static UnixConsoleStrategy &create( ConsoleCtl &con, DisplayBuffer &displayBuf, InputState &inputState, DisplayStrategy &display, diff --git a/include/tvision/internal/win32con.h b/include/tvision/internal/win32con.h index 3352b7d4..b91f0894 100644 --- a/include/tvision/internal/win32con.h +++ b/include/tvision/internal/win32con.h @@ -15,21 +15,21 @@ void getWin32Mouse(const MOUSE_EVENT_RECORD &, TEvent &, InputState &) noexcept; #ifdef _WIN32 -class StdioCtl; +class ConsoleCtl; class Win32Input; class Win32Display; class Win32ConsoleStrategy final : public ConsoleStrategy { - StdioCtl &io; + ConsoleCtl &con; UINT cpInput, cpOutput; - Win32ConsoleStrategy( StdioCtl &aIo, + Win32ConsoleStrategy( ConsoleCtl &aCon, UINT cpInput, UINT cpOutput, DisplayStrategy &aDisplay, InputStrategy &aInput ) noexcept : ConsoleStrategy(aDisplay, aInput, {&aInput}), - io(aIo), + con(aCon), cpInput(cpInput), cpOutput(cpOutput) { @@ -49,7 +49,7 @@ class Win32ConsoleStrategy final : public ConsoleStrategy class Win32Input final : public InputStrategy { - StdioCtl &io; + ConsoleCtl &con; InputState state; bool getEvent(const INPUT_RECORD &, TEvent &ev) noexcept; @@ -57,12 +57,8 @@ class Win32Input final : public InputStrategy public: - // The lifetime of 'aIo' must exceed that of 'this'. - Win32Input(StdioCtl &aIo) noexcept : - InputStrategy(aIo.in()), - io(aIo) - { - } + // The lifetime of 'con' must exceed that of 'this'. + Win32Input(ConsoleCtl &aCon) noexcept; bool getEvent(TEvent &ev) noexcept override; int getButtonCount() noexcept override; @@ -74,8 +70,8 @@ class Win32Display : public TerminalDisplay { public: - // The lifetime of 'aIo' must exceed that of 'this'. - Win32Display(StdioCtl &aIo, bool useAnsi) noexcept; + // The lifetime of 'con' must exceed that of 'this'. + Win32Display(ConsoleCtl &con, bool useAnsi) noexcept; ~Win32Display(); private: diff --git a/source/platform/ansiwrit.cpp b/source/platform/ansiwrit.cpp index 4c391d90..d48bdc3c 100644 --- a/source/platform/ansiwrit.cpp +++ b/source/platform/ansiwrit.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #define CSI "\x1B[" @@ -116,7 +117,7 @@ void AnsiScreenWriter::lowlevelMoveCursor(uint x, uint y) noexcept void AnsiScreenWriter::lowlevelFlush() noexcept { - io.write(buf.data(), buf.size()); + con.write(buf.data(), buf.size()); buf.clear(); } diff --git a/source/platform/stdioctl.cpp b/source/platform/conctl.cpp similarity index 89% rename from source/platform/stdioctl.cpp rename to source/platform/conctl.cpp index 31f07489..2303e2e0 100644 --- a/source/platform/stdioctl.cpp +++ b/source/platform/conctl.cpp @@ -1,22 +1,22 @@ #define Uses_TPoint #include -#include +#include #include namespace tvision { -StdioCtl *StdioCtl::instance = nullptr; +ConsoleCtl *ConsoleCtl::instance = nullptr; -StdioCtl &StdioCtl::getInstance() noexcept +ConsoleCtl &ConsoleCtl::getInstance() noexcept { if (!instance) - instance = new StdioCtl; + instance = new ConsoleCtl; return *instance; } -void StdioCtl::destroyInstance() noexcept +void ConsoleCtl::destroyInstance() noexcept { delete instance; instance = nullptr; @@ -36,7 +36,7 @@ void StdioCtl::destroyInstance() noexcept namespace tvision { -StdioCtl::StdioCtl() noexcept +ConsoleCtl::ConsoleCtl() noexcept { if ( getEnv("TVISION_USE_STDIO").empty() && (files[0] = fopen("/dev/tty", "r")) != nullptr @@ -61,14 +61,14 @@ StdioCtl::StdioCtl() noexcept } } -StdioCtl::~StdioCtl() +ConsoleCtl::~ConsoleCtl() { if (ownsFiles) for (FILE *file : files) fclose(file); } -void StdioCtl::write(const char *data, size_t bytes) const noexcept +void ConsoleCtl::write(const char *data, size_t bytes) const noexcept { fflush(fout()); size_t written = 0; @@ -78,7 +78,7 @@ void StdioCtl::write(const char *data, size_t bytes) const noexcept written += r; } -TPoint StdioCtl::getSize() const noexcept +TPoint ConsoleCtl::getSize() const noexcept { struct winsize w; for (int fd : fds) @@ -96,7 +96,7 @@ TPoint StdioCtl::getSize() const noexcept return {0, 0}; } -TPoint StdioCtl::getFontSize() const noexcept +TPoint ConsoleCtl::getFontSize() const noexcept { #ifdef KDFONTOP struct console_font_op cfo {}; @@ -121,7 +121,7 @@ TPoint StdioCtl::getFontSize() const noexcept #ifdef __linux -bool StdioCtl::isLinuxConsole() const noexcept +bool ConsoleCtl::isLinuxConsole() const noexcept { // This is the same function used to get the Shift/Ctrl/Alt modifiers // on the console. It only succeeds if a console file descriptor is used. @@ -145,31 +145,27 @@ bool StdioCtl::isLinuxConsole() const noexcept namespace tvision { -namespace stdioctl -{ - static bool isValid(HANDLE h) - { - return h && h != INVALID_HANDLE_VALUE; - } - - static bool isConsole(HANDLE h) - { - DWORD mode; - return GetConsoleMode(h, &mode); - } +static bool isValid(HANDLE h) +{ + return h && h != INVALID_HANDLE_VALUE; +} - static COORD windowSize(SMALL_RECT srWindow) - { - return { - short(srWindow.Right - srWindow.Left + 1), - short(srWindow.Bottom - srWindow.Top + 1), - }; - } +static bool isConsole(HANDLE h) +{ + DWORD mode; + return GetConsoleMode(h, &mode); +} -} // namespace stdioctl +static COORD windowSize(SMALL_RECT srWindow) +{ + return { + short(srWindow.Right - srWindow.Left + 1), + short(srWindow.Bottom - srWindow.Top + 1), + }; +} -StdioCtl::StdioCtl() noexcept +ConsoleCtl::ConsoleCtl() noexcept { // The console can be accessed in two ways: through GetStdHandle() or through // CreateFile(). GetStdHandle() will be unable to return a console handle @@ -205,7 +201,6 @@ StdioCtl::StdioCtl() noexcept // We also need to remember whether we allocated a console or not, so that // we can free it when tearing down. If we don't, weird things may happen. - using namespace stdioctl; static constexpr struct { DWORD std; int index; } channels[] = { {STD_INPUT_HANDLE, input}, @@ -278,9 +273,8 @@ StdioCtl::StdioCtl() noexcept } } -StdioCtl::~StdioCtl() +ConsoleCtl::~ConsoleCtl() { - using namespace stdioctl; CONSOLE_SCREEN_BUFFER_INFO activeSbInfo {}; GetConsoleScreenBufferInfo(cn[activeOutput].handle, &activeSbInfo); CONSOLE_SCREEN_BUFFER_INFO startupSbInfo {}; @@ -322,7 +316,7 @@ StdioCtl::~StdioCtl() FreeConsole(); } -void StdioCtl::write(const char *data, size_t bytes) const noexcept +void ConsoleCtl::write(const char *data, size_t bytes) const noexcept { // Writing 0 bytes causes the cursor to become invisible for a short time // in old versions of the Windows console. @@ -330,7 +324,7 @@ void StdioCtl::write(const char *data, size_t bytes) const noexcept WriteConsoleA(out(), data, bytes, nullptr, nullptr); } -TPoint StdioCtl::getSize() const noexcept +TPoint ConsoleCtl::getSize() const noexcept { CONSOLE_SCREEN_BUFFER_INFO sbInfo; auto &srWindow = sbInfo.srWindow; @@ -342,7 +336,7 @@ TPoint StdioCtl::getSize() const noexcept return {0, 0}; } -TPoint StdioCtl::getFontSize() const noexcept +TPoint ConsoleCtl::getFontSize() const noexcept { CONSOLE_FONT_INFO fontInfo; if (GetCurrentConsoleFont(out(), FALSE, &fontInfo)) diff --git a/source/platform/far2l.cpp b/source/platform/far2l.cpp index 2607cade..589d7c88 100644 --- a/source/platform/far2l.cpp +++ b/source/platform/far2l.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -248,7 +249,7 @@ inline void pushFar2lRequest(std::vector &out, std::vector &tmp, Arg concat(&out[headLen], prefix, b64, suffix); } -bool setFar2lClipboard(StdioCtl &io, TStringView text, InputState &state) noexcept +bool setFar2lClipboard(ConsoleCtl &con, TStringView text, InputState &state) noexcept { if (state.far2l.enabled) { @@ -276,13 +277,13 @@ bool setFar2lClipboard(StdioCtl &io, TStringView text, InputState &state) noexce "cc", f2lNoAnswer ); - io.write(out.data(), out.size()); + con.write(out.data(), out.size()); return true; } return false; } -bool requestFar2lClipboard(StdioCtl &io, InputState &state) noexcept +bool requestFar2lClipboard(ConsoleCtl &con, InputState &state) noexcept { if (state.far2l.enabled) { @@ -305,7 +306,7 @@ bool requestFar2lClipboard(StdioCtl &io, InputState &state) noexcept "cc", f2lNoAnswer ); - io.write(out.data(), out.size()); + con.write(out.data(), out.size()); return true; } return false; diff --git a/source/platform/linuxcon.cpp b/source/platform/linuxcon.cpp index 35640ddf..1b04e172 100644 --- a/source/platform/linuxcon.cpp +++ b/source/platform/linuxcon.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include #include @@ -33,14 +33,14 @@ inline LinuxConsoleStrategy::LinuxConsoleStrategy( DisplayStrategy &aDisplay, { } -LinuxConsoleStrategy &LinuxConsoleStrategy::create( StdioCtl &io, +LinuxConsoleStrategy &LinuxConsoleStrategy::create( ConsoleCtl &con, DisplayBuffer &displayBuf, InputState &inputState, DisplayStrategy &display, InputStrategy &input ) noexcept { auto *sigwinch = SigwinchHandler::create(); - auto &wrapper = *new LinuxConsoleInput(io, input); + auto &wrapper = *new LinuxConsoleInput(con, input); auto *gpm = GpmInput::create(displayBuf); return *new LinuxConsoleStrategy(display, wrapper, inputState, sigwinch, gpm); } @@ -86,7 +86,7 @@ bool LinuxConsoleInput::hasPendingEvents() noexcept ushort LinuxConsoleInput::getKeyboardModifiers() noexcept { char res = 6; - if (ioctl(io.in(), TIOCLINUX, &res) != -1) + if (ioctl(con.in(), TIOCLINUX, &res) != -1) return convertLinuxKeyModifiers(res); return 0; } diff --git a/source/platform/ncurdisp.cpp b/source/platform/ncurdisp.cpp index fff1140f..4bc6dcd8 100644 --- a/source/platform/ncurdisp.cpp +++ b/source/platform/ncurdisp.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include #include @@ -12,12 +12,12 @@ namespace tvision { -NcursesDisplay::NcursesDisplay(StdioCtl &aIo) noexcept : - TerminalDisplay(aIo), - ansiScreenWriter(aIo) +NcursesDisplay::NcursesDisplay(ConsoleCtl &aCon) noexcept : + TerminalDisplay(aCon), + ansiScreenWriter(aCon) { // Start curses mode. - term = newterm(nullptr, io.fout(), io.fin()); + term = newterm(nullptr, con.fout(), con.fin()); if (!term) { fputs("Cannot initialize Ncurses: 'newterm' failed.\n", stderr); @@ -45,7 +45,7 @@ NcursesDisplay::~NcursesDisplay() void NcursesDisplay::reloadScreenInfo() noexcept { - TPoint size = io.getSize(); + TPoint size = con.getSize(); // 'resizeterm' causes terrible flickering, so we better use 'resize_term'. resize_term(size.y, size.x); ansiScreenWriter.resetAttributes(); diff --git a/source/platform/ncursinp.cpp b/source/platform/ncursinp.cpp index 1e0e11a5..0428c115 100644 --- a/source/platform/ncursinp.cpp +++ b/source/platform/ncursinp.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include #include @@ -269,10 +269,10 @@ void NcursesInputGetter::unget(int k) noexcept ++pendingCount; } -NcursesInput::NcursesInput( StdioCtl &aIo, NcursesDisplay &, +NcursesInput::NcursesInput( ConsoleCtl &aCon, NcursesDisplay &, InputState &aState, bool mouse ) noexcept : - InputStrategy(aIo.in()), - io(aIo), + InputStrategy(aCon.in()), + con(aCon), state(aState), mouseEnabled(mouse) { @@ -293,17 +293,17 @@ NcursesInput::NcursesInput( StdioCtl &aIo, NcursesDisplay &, * special key sequences, I believe. */ set_escdelay(getEnv("TVISION_ESCDELAY", 10)); - TermIO::keyModsOn(io); + TermIO::keyModsOn(con); if (mouseEnabled) - TermIO::mouseOn(io); + TermIO::mouseOn(con); } NcursesInput::~NcursesInput() { if (mouseEnabled) - TermIO::mouseOff(io); - TermIO::keyModsOff(io); - TermIO::consumeUnprocessedInput(io, in, state); + TermIO::mouseOff(con); + TermIO::keyModsOff(con); + TermIO::consumeUnprocessedInput(con, in, state); } int NcursesInput::getButtonCount() noexcept diff --git a/source/platform/platfcon.cpp b/source/platform/platfcon.cpp index e25912c0..e7f4359a 100644 --- a/source/platform/platfcon.cpp +++ b/source/platform/platfcon.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -21,14 +22,14 @@ ConsoleStrategy &Platform::createConsole() noexcept #ifdef _WIN32 return Win32ConsoleStrategy::create(); #else - auto &io = StdioCtl::getInstance(); + auto &con = ConsoleCtl::getInstance(); InputState &inputState = *new InputState; - NcursesDisplay &display = *new NcursesDisplay(io); + NcursesDisplay &display = *new NcursesDisplay(con); #ifdef __linux__ - if (io.isLinuxConsole()) - return LinuxConsoleStrategy::create(io, displayBuf, inputState, display, *new NcursesInput(io, display, inputState, false)); + if (con.isLinuxConsole()) + return LinuxConsoleStrategy::create(con, displayBuf, inputState, display, *new NcursesInput(con, display, inputState, false)); #endif // __linux__ - return UnixConsoleStrategy::create(io, displayBuf, inputState, display, *new NcursesInput(io, display, inputState, true)); + return UnixConsoleStrategy::create(con, displayBuf, inputState, display, *new NcursesInput(con, display, inputState, true)); #endif // _WIN32 } diff --git a/source/platform/platform.cpp b/source/platform/platform.cpp index 78b5f3a3..d50bb9ed 100644 --- a/source/platform/platform.cpp +++ b/source/platform/platform.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -35,8 +36,8 @@ void Platform::initEncodingStuff() noexcept #else setlocale(LC_ALL, ""); #ifdef __linux__ - auto &io = StdioCtl::getInstance(); - if (io.isLinuxConsole()) + auto &con = ConsoleCtl::getInstance(); + if (con.isLinuxConsole()) charWidth = &LinuxConsoleStrategy::charWidth; else #endif // __linux__ @@ -58,7 +59,7 @@ Platform::~Platform() { restoreConsole(); #ifndef _WIN32 - StdioCtl::destroyInstance(); + ConsoleCtl::destroyInstance(); #endif instance = nullptr; } diff --git a/source/platform/termdisp.cpp b/source/platform/termdisp.cpp index 7b168431..45d7285c 100644 --- a/source/platform/termdisp.cpp +++ b/source/platform/termdisp.cpp @@ -3,6 +3,7 @@ #include #include +#include #include namespace tvision @@ -28,7 +29,7 @@ TermCap TerminalDisplay::getCapabilities() noexcept termcap.colors = Indexed8; termcap.quirks |= qfBoldIsBright; #ifdef __linux__ - if (io.isLinuxConsole()) + if (con.isLinuxConsole()) termcap.quirks |= qfBlinkIsBright | qfNoItalic | qfNoUnderline; else #endif // __linux__ @@ -54,7 +55,7 @@ ushort TerminalDisplay::getScreenMode() noexcept else if (termcap.colors == Indexed256) mode |= TDisplay::smColor256; - TPoint fontSize = io.getFontSize(); + TPoint fontSize = con.getFontSize(); if (fontSize.x > 0 && fontSize.y > 0 && fontSize.x >= fontSize.y) mode |= TDisplay::smFont8x8; @@ -63,7 +64,7 @@ ushort TerminalDisplay::getScreenMode() noexcept bool TerminalDisplay::screenChanged() noexcept { - TPoint size = io.getSize(); + TPoint size = con.getSize(); bool changed = (size != lastSize); lastSize = size; return changed; diff --git a/source/platform/termio.cpp b/source/platform/termio.cpp index a6d851f1..06199cca 100644 --- a/source/platform/termio.cpp +++ b/source/platform/termio.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include #include @@ -254,27 +254,27 @@ bool CSIData::readFrom(GetChBuf &buf) noexcept // The default mouse experience with Ncurses is not always good. To work around // some issues, we request and parse mouse events manually. -void TermIO::mouseOn(StdioCtl &io) noexcept +void TermIO::mouseOn(ConsoleCtl &con) noexcept { TStringView seq = "\x1B[?1001s" // Save old highlight mouse reporting. "\x1B[?1000h" // Enable mouse reporting. "\x1B[?1002h" // Enable mouse drag reporting. "\x1B[?1006h" // Enable SGR extended mouse reporting. ; - io.write(seq.data(), seq.size()); + con.write(seq.data(), seq.size()); } -void TermIO::mouseOff(StdioCtl &io) noexcept +void TermIO::mouseOff(ConsoleCtl &con) noexcept { TStringView seq = "\x1B[?1006l" // Disable SGR extended mouse reporting. "\x1B[?1002l" // Disable mouse drag reporting. "\x1B[?1000l" // Disable mouse reporting. "\x1B[?1001r" // Restore old highlight mouse reporting. ; - io.write(seq.data(), seq.size()); + con.write(seq.data(), seq.size()); } -void TermIO::keyModsOn(StdioCtl &io) noexcept +void TermIO::keyModsOn(ConsoleCtl &con) noexcept { char buf[256]; @@ -314,10 +314,10 @@ void TermIO::keyModsOn(StdioCtl &io) noexcept "\x1B[2J" ); - io.write(buf, strlen(buf)); + con.write(buf, strlen(buf)); } -void TermIO::keyModsOff(StdioCtl &io) noexcept +void TermIO::keyModsOff(ConsoleCtl &con) noexcept { TStringView seq = far2lDisableSeq "\x1B[?9001l" // Disable win32-input-mode (Conpty). @@ -327,7 +327,7 @@ void TermIO::keyModsOff(StdioCtl &io) noexcept "\x1B[?2004r" // Restore bracketed paste. "\x1B[?1036r" // Restore metaSendsEscape (XTerm). ; - io.write(seq.data(), seq.size()); + con.write(seq.data(), seq.size()); } void TermIO::normalizeKey(KeyDownEvent &keyDown) noexcept @@ -818,7 +818,7 @@ ParseResult TermIO::parseWin32InputModeKeyOrEscapeSeq(const CSIData &csi, InputG return res; } -static bool setOsc52Clipboard(StdioCtl &io, TStringView text, InputState &state) noexcept +static bool setOsc52Clipboard(ConsoleCtl &con, TStringView text, InputState &state) noexcept { TStringView prefix = "\x1B]52;;"; TStringView suffix = "\x07"; @@ -827,7 +827,7 @@ static bool setOsc52Clipboard(StdioCtl &io, TStringView text, InputState &state) memcpy(buf, prefix.data(), prefix.size()); TStringView b64 = encodeBase64(text, buf + prefix.size()); memcpy(buf + prefix.size() + b64.size(), suffix.data(), suffix.size()); - io.write(buf, prefix.size() + b64.size() + suffix.size()); + con.write(buf, prefix.size() + b64.size() + suffix.size()); free(buf); } // Return false when there is no full OSC 52 support, even though we always @@ -835,28 +835,28 @@ static bool setOsc52Clipboard(StdioCtl &io, TStringView text, InputState &state) return state.hasFullOsc52; } -static bool requestOsc52Clipboard(StdioCtl &io, InputState &state) noexcept +static bool requestOsc52Clipboard(ConsoleCtl &con, InputState &state) noexcept { if (state.hasFullOsc52) { TStringView seq = "\x1B]52;;?\x07"; - io.write(seq.data(), seq.size()); + con.write(seq.data(), seq.size()); return true; } return false; } -bool TermIO::setClipboardText(StdioCtl &io, TStringView text, InputState &state) noexcept +bool TermIO::setClipboardText(ConsoleCtl &con, TStringView text, InputState &state) noexcept { - return setFar2lClipboard(io, text, state) - || setOsc52Clipboard(io, text, state); + return setFar2lClipboard(con, text, state) + || setOsc52Clipboard(con, text, state); } -bool TermIO::requestClipboardText(StdioCtl &io, void (&accept)(TStringView), InputState &state) noexcept +bool TermIO::requestClipboardText(ConsoleCtl &con, void (&accept)(TStringView), InputState &state) noexcept { state.putPaste = &accept; - return requestFar2lClipboard(io, state) - || requestOsc52Clipboard(io, state); + return requestFar2lClipboard(con, state) + || requestOsc52Clipboard(con, state); } char *TermIO::readUntilBelOrSt(GetChBuf &buf) noexcept @@ -895,7 +895,7 @@ char *TermIO::readUntilBelOrSt(GetChBuf &buf) noexcept return {}; } -void TermIO::consumeUnprocessedInput(StdioCtl &io, InputGetter &in, InputState &state) noexcept +void TermIO::consumeUnprocessedInput(ConsoleCtl &con, InputGetter &in, InputState &state) noexcept // The terminal might have kept sending us events while the application is // exiting. This is especially likely to happen when the application is running // remotely accross a slow connection and terminal extensions are in place @@ -908,7 +908,7 @@ void TermIO::consumeUnprocessedInput(StdioCtl &io, InputGetter &in, InputState & auto timeout = milliseconds(200); TStringView seq = "\x1B[6n"; // Device Status Report. - io.write(seq.data(), seq.size()); + con.write(seq.data(), seq.size()); TEvent ev {}; state.gotDsrResponse = false; diff --git a/source/platform/unixcon.cpp b/source/platform/unixcon.cpp index b295d6fe..1d423e02 100644 --- a/source/platform/unixcon.cpp +++ b/source/platform/unixcon.cpp @@ -12,26 +12,26 @@ namespace tvision inline UnixConsoleStrategy::UnixConsoleStrategy( DisplayStrategy &aDisplay, InputStrategy &aInput, - StdioCtl &aIo, + ConsoleCtl &aCon, DisplayBuffer &aDisplayBuf, InputState &aInputState, SigwinchHandler *aSigwinch ) noexcept : ConsoleStrategy(aDisplay, aInput, {&aInput, aSigwinch}), - io(aIo), + con(aCon), displayBuf(aDisplayBuf), inputState(aInputState), sigwinch(aSigwinch) { } -UnixConsoleStrategy &UnixConsoleStrategy::create( StdioCtl &io, +UnixConsoleStrategy &UnixConsoleStrategy::create( ConsoleCtl &con, DisplayBuffer &displayBuf, InputState &inputState, DisplayStrategy &display, InputStrategy &input ) noexcept { auto *sigwinch = SigwinchHandler::create(); - return *new UnixConsoleStrategy(display, input, io, displayBuf, inputState, sigwinch); + return *new UnixConsoleStrategy(display, input, con, displayBuf, inputState, sigwinch); } UnixConsoleStrategy::~UnixConsoleStrategy() @@ -46,7 +46,7 @@ bool UnixConsoleStrategy::setClipboardText(TStringView text) noexcept { if (UnixClipboard::setClipboardText(text)) return true; - if (TermIO::setClipboardText(io, text, inputState)) + if (TermIO::setClipboardText(con, text, inputState)) return true; // On non-success, 'setClipboardText' prints an OSC sequence not all // terminals can handle; redraw the screen in case it has been messed up. @@ -58,7 +58,7 @@ bool UnixConsoleStrategy::requestClipboardText(void (&accept)(TStringView)) noex { if (UnixClipboard::requestClipboardText(accept)) return true; - if (TermIO::requestClipboardText(io, accept, inputState)) + if (TermIO::requestClipboardText(con, accept, inputState)) return true; return false; } diff --git a/source/platform/win32con.cpp b/source/platform/win32con.cpp index 3a6781b5..1bcc0fd1 100644 --- a/source/platform/win32con.cpp +++ b/source/platform/win32con.cpp @@ -3,7 +3,7 @@ #define Uses_THardwareInfo #include #include -#include +#include #include #include #include @@ -22,24 +22,24 @@ static bool isWine() noexcept Win32ConsoleStrategy &Win32ConsoleStrategy::create() noexcept { - auto &io = StdioCtl::getInstance(); + auto &con = ConsoleCtl::getInstance(); // Set the input mode. { DWORD consoleMode = 0; - GetConsoleMode(io.in(), &consoleMode); + GetConsoleMode(con.in(), &consoleMode); consoleMode |= ENABLE_WINDOW_INPUT; // Report changes in buffer size consoleMode &= ~ENABLE_PROCESSED_INPUT; // Report CTRL+C and SHIFT+Arrow events. consoleMode |= ENABLE_EXTENDED_FLAGS; /* Disable the Quick Edit mode, */ consoleMode &= ~ENABLE_QUICK_EDIT_MODE; /* which inhibits the mouse. */ - SetConsoleMode(io.in(), consoleMode); + SetConsoleMode(con.in(), consoleMode); } // Set the output mode. bool supportsVT; { DWORD consoleMode = 0; - GetConsoleMode(io.out(), &consoleMode); + GetConsoleMode(con.out(), &consoleMode); consoleMode &= ~ENABLE_WRAP_AT_EOL_OUTPUT; // Avoid scrolling when reaching end of line. - SetConsoleMode(io.out(), consoleMode); + SetConsoleMode(con.out(), consoleMode); // Try enabling VT sequences. if (isWine()) // Wine does not support them, but unlike the legacy console, @@ -50,8 +50,8 @@ Win32ConsoleStrategy &Win32ConsoleStrategy::create() noexcept { consoleMode |= DISABLE_NEWLINE_AUTO_RETURN; // Do not do CR on LF. consoleMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; // Allow ANSI escape sequences. - SetConsoleMode(io.out(), consoleMode); - GetConsoleMode(io.out(), &consoleMode); + SetConsoleMode(con.out(), consoleMode); + GetConsoleMode(con.out(), &consoleMode); supportsVT = consoleMode & ENABLE_VIRTUAL_TERMINAL_PROCESSING; } } @@ -77,7 +77,7 @@ Win32ConsoleStrategy &Win32ConsoleStrategy::create() noexcept // "A monospace bitmap font has all of these low-order bits clear". return !(family & (TMPF_FIXED_PITCH | TMPF_VECTOR | TMPF_TRUETYPE | TMPF_DEVICE)); }; - if ( GetCurrentConsoleFontEx(io.out(), FALSE, &fontInfo) + if ( GetCurrentConsoleFontEx(con.out(), FALSE, &fontInfo) && isBitmap(fontInfo.FontFamily) ) { // Compute the new font height based on the bitmap font size. @@ -91,17 +91,17 @@ Win32ConsoleStrategy &Win32ConsoleStrategy::create() noexcept wcscpy(fontInfo.FaceName, name); // SetCurrentConsoleFontEx succeeds even if the font is not available. // We need to check whether the font has actually been set. - SetCurrentConsoleFontEx(io.out(), FALSE, &fontInfo); - GetCurrentConsoleFontEx(io.out(), FALSE, &fontInfo); + SetCurrentConsoleFontEx(con.out(), FALSE, &fontInfo); + GetCurrentConsoleFontEx(con.out(), FALSE, &fontInfo); if (wcscmp(fontInfo.FaceName, name) == 0) break; } } } WinWidth::reset(); - auto &display = *new Win32Display(io, supportsVT); - auto &input = *new Win32Input(io); - return *new Win32ConsoleStrategy(io, cpInput, cpOutput, display, input); + auto &display = *new Win32Display(con, supportsVT); + auto &input = *new Win32Input(con); + return *new Win32ConsoleStrategy(con, cpInput, cpOutput, display, input); } Win32ConsoleStrategy::~Win32ConsoleStrategy() @@ -110,13 +110,13 @@ Win32ConsoleStrategy::~Win32ConsoleStrategy() delete &input; SetConsoleCP(cpInput); SetConsoleOutputCP(cpOutput); - StdioCtl::destroyInstance(); + ConsoleCtl::destroyInstance(); } bool Win32ConsoleStrategy::isAlive() noexcept { DWORD events = 0; - return GetNumberOfConsoleInputEvents(io.in(), &events); + return GetNumberOfConsoleInputEvents(con.in(), &events); } static bool openClipboard() noexcept @@ -183,6 +183,12 @@ bool Win32ConsoleStrategy::requestClipboardText(void (&accept)(TStringView)) noe ///////////////////////////////////////////////////////////////////////// // Win32Input +Win32Input::Win32Input(ConsoleCtl &aCon) noexcept : + InputStrategy(aCon.in()), + con(aCon) +{ +} + int Win32Input::getButtonCount() noexcept { DWORD num; @@ -193,15 +199,15 @@ int Win32Input::getButtonCount() noexcept void Win32Input::cursorOn() noexcept { DWORD consoleMode = 0; - GetConsoleMode(io.in(), &consoleMode); - SetConsoleMode(io.in(), consoleMode | ENABLE_MOUSE_INPUT); + GetConsoleMode(con.in(), &consoleMode); + SetConsoleMode(con.in(), consoleMode | ENABLE_MOUSE_INPUT); } void Win32Input::cursorOff() noexcept { DWORD consoleMode = 0; - GetConsoleMode(io.in(), &consoleMode); - SetConsoleMode(io.in(), consoleMode & ~ENABLE_MOUSE_INPUT); + GetConsoleMode(con.in(), &consoleMode); + SetConsoleMode(con.in(), consoleMode & ~ENABLE_MOUSE_INPUT); } bool Win32Input::getEvent(TEvent &ev) noexcept @@ -209,7 +215,7 @@ bool Win32Input::getEvent(TEvent &ev) noexcept // ReadConsoleInput can sleep the process, so we first check the number // of available input events. DWORD events; - while (GetNumberOfConsoleInputEvents(io.in(), &events) && events) + while (GetNumberOfConsoleInputEvents(con.in(), &events) && events) { // getEvent(ir, ev) often returns false due to discarded events. But this // function should not return false if there are pending events, as that @@ -218,7 +224,7 @@ bool Win32Input::getEvent(TEvent &ev) noexcept { INPUT_RECORD ir; DWORD ok; - if (!ReadConsoleInputW(io.in(), &ir, 1, &ok) || !ok) + if (!ReadConsoleInputW(con.in(), &ir, 1, &ok) || !ok) return false; if (getEvent(ir, ev)) return true; @@ -252,9 +258,9 @@ bool Win32Input::getEvent(const INPUT_RECORD &ir, TEvent &ev) noexcept ///////////////////////////////////////////////////////////////////////// // Win32Display -Win32Display::Win32Display(StdioCtl &aIo, bool useAnsi) noexcept : - TerminalDisplay(aIo), - ansiScreenWriter(useAnsi ? new AnsiScreenWriter(aIo) : nullptr) +Win32Display::Win32Display(ConsoleCtl &aCon, bool useAnsi) noexcept : + TerminalDisplay(aCon), + ansiScreenWriter(useAnsi ? new AnsiScreenWriter(aCon) : nullptr) { initCapabilities(); } @@ -266,18 +272,18 @@ Win32Display::~Win32Display() void Win32Display::reloadScreenInfo() noexcept { - size = io.getSize(); + size = con.getSize(); CONSOLE_SCREEN_BUFFER_INFO sbInfo {}; - GetConsoleScreenBufferInfo(io.out(), &sbInfo); + GetConsoleScreenBufferInfo(con.out(), &sbInfo); // Set the cursor temporally to (0, 0) to prevent the console from crashing // due to https://github.com/microsoft/terminal/issues/7511. auto curPos = sbInfo.dwCursorPosition; - SetConsoleCursorPosition(io.out(), {0, 0}); + SetConsoleCursorPosition(con.out(), {0, 0}); // Make sure the buffer size matches the viewport size so that the // scrollbars are not shown. - SetConsoleScreenBufferSize(io.out(), {(short) size.x, (short) size.y}); + SetConsoleScreenBufferSize(con.out(), {(short) size.x, (short) size.y}); // Restore the cursor position (it does not matter if it is out of bounds). - SetConsoleCursorPosition(io.out(), curPos); + SetConsoleCursorPosition(con.out(), curPos); if (ansiScreenWriter) ansiScreenWriter->resetAttributes(); @@ -287,7 +293,7 @@ bool Win32Display::screenChanged() noexcept { bool changed = TerminalDisplay::screenChanged(); CONSOLE_FONT_INFO fontInfo; - if ( GetCurrentConsoleFont(io.out(), FALSE, &fontInfo) + if ( GetCurrentConsoleFont(con.out(), FALSE, &fontInfo) && memcmp(&fontInfo, &lastFontInfo, sizeof(fontInfo)) != 0 ) { changed = true; @@ -305,7 +311,7 @@ TPoint Win32Display::getScreenSize() noexcept int Win32Display::getCaretSize() noexcept { CONSOLE_CURSOR_INFO crInfo {}; - GetConsoleCursorInfo(io.out(), &crInfo); + GetConsoleCursorInfo(con.out(), &crInfo); return crInfo.bVisible ? crInfo.dwSize : 0; } @@ -314,7 +320,7 @@ int Win32Display::getColorCount() noexcept // Conhost has had high color support for some time: // https://devblogs.microsoft.com/commandline/24-bit-color-in-the-windows-console/ DWORD consoleMode = 0; - GetConsoleMode(io.out(), &consoleMode); + GetConsoleMode(con.out(), &consoleMode); if (consoleMode & ENABLE_VIRTUAL_TERMINAL_PROCESSING) return 256*256*256; return 16; @@ -330,7 +336,7 @@ void Win32Display::lowlevelCursorSize(int size) noexcept crInfo.bVisible = FALSE; crInfo.dwSize = 1; } - SetConsoleCursorInfo(io.out(), &crInfo); + SetConsoleCursorInfo(con.out(), &crInfo); } void Win32Display::clearScreen() noexcept @@ -343,8 +349,8 @@ void Win32Display::clearScreen() noexcept DWORD length = size.x * size.y; BYTE attr = 0x07; DWORD read; - FillConsoleOutputAttribute(io.out(), attr, length, coord, &read); - FillConsoleOutputCharacterA(io.out(), ' ', length, coord, &read); + FillConsoleOutputAttribute(con.out(), attr, length, coord, &read); + FillConsoleOutputCharacterA(con.out(), ' ', length, coord, &read); lastAttr = attr; } } @@ -359,7 +365,7 @@ void Win32Display::lowlevelWriteChars(TStringView chars, TColorAttr attr) noexce if (bios != lastAttr) { lowlevelFlush(); - SetConsoleTextAttribute(io.out(), bios); + SetConsoleTextAttribute(con.out(), bios); lastAttr = bios; } buf.insert(buf.end(), chars.begin(), chars.end()); @@ -373,7 +379,7 @@ void Win32Display::lowlevelMoveCursor(uint x, uint y) noexcept else { lowlevelFlush(); - SetConsoleCursorPosition(io.out(), {(short) x, (short) y}); + SetConsoleCursorPosition(con.out(), {(short) x, (short) y}); } } @@ -391,7 +397,7 @@ void Win32Display::lowlevelFlush() noexcept ansiScreenWriter->lowlevelFlush(); else { - io.write(buf.data(), buf.size()); + con.write(buf.data(), buf.size()); buf.resize(0); } }