Skip to content

Commit

Permalink
#393 Application scripting runtime (console mode init)
Browse files Browse the repository at this point in the history
  • Loading branch information
o-sdn-o committed Jun 7, 2023
1 parent ec2f32d commit cb639cb
Show file tree
Hide file tree
Showing 3 changed files with 192 additions and 43 deletions.
8 changes: 7 additions & 1 deletion src/netxs/desktopio/ansivt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,11 @@ namespace netxs::ansi
return add(other);
}

auto& shellmouse(bool b) // esc: Mouse shell integration on/off.
{
return add(b ? "\033[?1000;1006h"
: "\033[?1000;1006l");
}
auto& vmouse(bool b) // esc: Focus and Mouse position reporting/tracking.
{
return add(b ? "\033[?1002;1003;1004;1006;10060h"
Expand Down Expand Up @@ -1009,7 +1014,8 @@ namespace netxs::ansi
static auto wrp_or(wrap n) { return esc{}.wrp_or(n); } // ansi: Set text wrapping if it is not set.
static auto rtl_or(rtol n) { return esc{}.rtl_or(n); } // ansi: Set text right-to-left if it is not set.
static auto rlf_or(feed n) { return esc{}.rlf_or(n); } // ansi: Set reverse line feed if it is not set.
static auto show_mouse (bool b) { return esc{}.show_mouse(b); } // ansi: Should the mouse poiner to be drawn.
static auto show_mouse(bool b) { return esc{}.show_mouse(b); } // ansi: Should the mouse poiner to be drawn.
static auto shellmouse(bool b) { return esc{}.shellmouse(b); } // ansi: Mouse shell integration on/off.
static auto vmouse(bool b) { return esc{}.vmouse(b); } // ansi: Mouse position reporting/tracking.
static auto locate(twod const& n) { return esc{}.locate(n); } // ansi: 1-Based caret position.
static auto locate_wipe() { return esc{}.locate_wipe(); } // ansi: Enable scrolling for entire display (clear screen).
Expand Down
217 changes: 179 additions & 38 deletions src/netxs/desktopio/system.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3560,8 +3560,6 @@ namespace netxs::os
| nt::console::inmode::preprocess
| nt::console::inmode::extended
| nt::console::inmode::winsize
//todo intro spec mode / emit ^[[?1000;1006h
//| nt::console::inmode::mouse
};
ok(::SetConsoleMode(os::stdin_fd, inpmode), "::SetConsoleMode(os::stdin_fd)", os::unexpected_msg);
auto outmode = DWORD{ 0
Expand Down Expand Up @@ -4456,51 +4454,194 @@ namespace netxs::os
io::send(os::stdout_fd, vtend);
std::this_thread::sleep_for(200ms); // Pause to complete consuming/receiving buffered input (e.g. mouse tracking) that has just been canceled.
}
auto stopread()
{
auto& alarm = globals().alarm;
alarm.bell();
}
auto readkey(text& buff)
{

}
auto readline(text& buff)
namespace readline
{
#if not defined(_WIN32)
auto resize()
{
static constexpr auto winsz_fallback = twod{ 132, 60 };
auto& g = globals();
auto& winsz = g.winsz;
//auto& wired = g.wired;

//auto state = conmode{};
//if (ok(::tcgetattr(os::stdin_fd, &state), "::tcgetattr(os::stdin_fd)", os::unexpected_msg))
//{
// auto raw_mode = state;
// ::cfmakeraw(&raw_mode);
// ok(::tcsetattr(os::stdin_fd, TCSANOW, &raw_mode), "::tcsetattr(os::stdin_fd, TCSANOW)", os::unexpected_msg);
//}
//else
//{
// os::fail("Check you are using the proper tty device, try `ssh -tt ...` option");
//}
#if defined(_WIN32)

#endif
auto cinfo = CONSOLE_SCREEN_BUFFER_INFO{};
if (ok(::GetConsoleScreenBufferInfo(os::stdout_fd, &cinfo), "::GetConsoleScreenBufferInfo", os::unexpected_msg))
{
winsz({ cinfo.srWindow.Right - cinfo.srWindow.Left + 1,
cinfo.srWindow.Bottom - cinfo.srWindow.Top + 1 });
}

//todo track double Ctrl+C
#else

auto& alarm = globals().alarm;
if (alarm.fired) return qiew{};
std::this_thread::sleep_for(5s);
//buff = "print(\"Hello World!\")";
buff = "\"Hello World!\""; // pwsh and python test command
auto size = winsize{};
if (ok(::ioctl(os::stdout_fd, TIOCGWINSZ, &size), "::ioctl(os::stdout_fd, TIOCGWINSZ)", os::unexpected_msg))
{
winsz({ size.ws_col, size.ws_row });
}

#endif

#if not defined(_WIN32)
if (winsz == dot_00)
{
log(prompt::tty, "Fallback tty window size ", winsz_fallback, " (consider using 'ssh -tt ...')");
winsz(winsz_fallback);
}
//wired.winsz.send(ipcio, 0, winsz.last);
}
auto signal(sigt what)
{
//todo track double Ctrl+C
#if defined(_WIN32)

auto& g = globals();
switch (what)
{
case CTRL_C_EVENT:
{
/* placed to the input buffer - ENABLE_PROCESSED_INPUT is disabled */
//todo handle SIGINT
return FALSE; // Not handled.
break;
}
case CTRL_BREAK_EVENT:
{
auto dwControlKeyState = g.kbmod;
auto kbState = os::nt::kbstate(g.kbmod, dwControlKeyState);
auto wVirtualKeyCode = ansi::ctrl_break;
auto wVirtualScanCode = ansi::ctrl_break;
auto bKeyDown = faux;
auto wRepeatCount = 1;
auto UnicodeChar = "\x03"s; // ansi::C0_ETX
//g.wired.syskeybd.send(*g.ipcio,
// 0,
// os::nt::kbstate(g.kbmod, dwControlKeyState),
// dwControlKeyState,
// wVirtualKeyCode,
// wVirtualScanCode,
// bKeyDown,
// wRepeatCount,
// UnicodeChar,
// faux);
break;
}
case CTRL_CLOSE_EVENT:
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
//g.ipcio->shut();
std::this_thread::sleep_for(5000ms); // The client will shut down before this timeout expires.
break;
default:
break;
}
return TRUE;

//if (!ok(::tcsetattr(os::stdin_fd, TCSANOW, &state), "::tcsetattr(os::stdin_fd, TCSANOW)", os::unexpected_msg))
//{
// os::fail("Check you are using the proper tty device, try `ssh -tt ...` option");
//}
#else

#endif
return qiew{ buff };
auto shutdown = [](auto what)
{
//globals().ipcio->shut();
::signal(what, SIG_DFL);
::raise(what);
};
switch (what)
{
case SIGWINCH: readline::resize(); return;
case SIGHUP: log(prompt::tty, "SIGHUP"); shutdown(what); break;
case SIGTERM: log(prompt::tty, "SIGTERM"); shutdown(what); break;
case SIGINT: log(prompt::tty, "SIGINT");
::signal(what, SIG_DFL);
::raise(what);
break;
default: log(prompt::tty, "Signal ", what); break;
}

#endif
}
auto ignite()
{
auto& sig_hndl = readline::signal;
#if defined(_WIN32)

auto inpmode = DWORD{ 0
| nt::console::inmode::preprocess
| nt::console::inmode::extended
| nt::console::inmode::winsize
};
ok(::SetConsoleMode(os::stdin_fd, inpmode), "::SetConsoleMode(os::stdin_fd)", os::unexpected_msg);
auto outmode = DWORD{ 0
| nt::console::outmode::preprocess
| nt::console::outmode::vt
};
ok(::SetConsoleMode(os::stdout_fd, outmode), "::SetConsoleMode(os::stdout_fd)", os::unexpected_msg);
ok(::SetConsoleCtrlHandler(reinterpret_cast<PHANDLER_ROUTINE>(sig_hndl), TRUE), "::SetConsoleCtrlHandler()", os::unexpected_msg);

#else

auto state = conmode{};
if (ok(::tcgetattr(os::stdin_fd, &state), "::tcgetattr(os::stdin_fd)", os::unexpected_msg))
{
auto raw_mode = state;
::cfmakeraw(&raw_mode);
raw_mode.c_oflag |= OPOST; // Post-processing output. Convert LF to CRLF.
raw_mode.c_lflag |= ISIG; // Controls whether the INTR, QUIT, and SUSP characters trigger a process signal. (Ctrl+C)
//raw_mode.c_iflag &= ~( 0
// | PARMRK // Erroneous bytes are marker.
// | ISTRIP // 7-bit only input (c & 0x7F).
// | IGNCR // Drop CR.
// | ICRNL // Convert CR to NL(LF).
// | INLCR // Convert NL to CR.
// | IXON // Suspends output on a STOP character until a START character is received.
// | IGNBRK // Ignore break conditions.
// | BRKINT // Raises a SIGINT signal for the foreground process group.
// );
//raw_mode.c_oflag &= ~OPOST; // Deactivates post-processing output.
//raw_mode.c_lflag &= ~(0
// | ECHO // Echoing of input characters.
// | ECHONL // Echoing of NL characters.
// | ICANON // Canonical input processing mode. A-la line input.
// | ISIG // Controls whether the INTR, QUIT, and SUSP characters trigger a process signal.
// | IEXTEN // Enables the LNEXT and DISCARD characters.
// );
//raw_mode.c_cflag &= ~(0 // Control mode.
// | CSIZE // Bit per character mask.
// | PARENB // Generation and detection of a parity bit.
// );
//raw_mode.c_cflag |= CS8; // Eight bits per byte.
ok(::tcsetattr(os::stdin_fd, TCSANOW, &raw_mode), "::tcsetattr(os::stdin_fd, TCSANOW)", os::unexpected_msg);
}
else
{
os::fail("Check you are using the proper tty device, try `ssh -tt ...` option");
}
//ok(::signal(SIGPIPE , SIG_IGN ), "::signal(SIGPIPE)", os::unexpected_msg);
//ok(::signal(SIGWINCH, sig_hndl), "::signal(SIGWINCH)", os::unexpected_msg);
//ok(::signal(SIGTERM , sig_hndl), "::signal(SIGTERM)", os::unexpected_msg);
//ok(::signal(SIGHUP , sig_hndl), "::signal(SIGHUP)", os::unexpected_msg);
ok(::signal(SIGINT, sig_hndl), "::signal(SIGHUP)", os::unexpected_msg);

#endif
//log(ansi::shellmouse(true));
}
auto finish()
{
auto& alarm = globals().alarm;
alarm.bell();
//log(ansi::shellmouse(faux));
}
auto readch(text& buff)
{

}
auto readln(text& buff)
{
auto& alarm = globals().alarm;
if (alarm.fired) return qiew{};
std::this_thread::sleep_for(5s);
buff = "\"Hello World!\""; // pwsh and python test command
return qiew{ buff };
}
}
};
}
}
10 changes: 6 additions & 4 deletions src/vtm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,14 +155,15 @@ int main(int argc, char* argv[])
auto onlylog = vtmode & os::vt::onlylog;
if (!onlylog)
{
os::tty::readline::ignite();
auto buffer = text{};
while (stream->send(os::tty::readline(buffer))) { }
while (stream->send(os::tty::readline::readln(buffer))) { }
stream->shut();
}
}};
while (os::io::send(stream->recv()))
{ }
os::tty::stopread();
os::tty::readline::finish();
readln.join();
return 0;
}
Expand Down Expand Up @@ -300,8 +301,9 @@ int main(int argc, char* argv[])
auto onlylog = vtmode & os::vt::onlylog;
if (!onlylog)
{
os::tty::readline::ignite();
auto buffer = text{};
while (auto line = os::tty::readline(buffer))
while (auto line = os::tty::readline::readln(buffer))
{
domain->SIGNAL(tier::release, e2::conio::readline, line);
}
Expand All @@ -324,7 +326,7 @@ int main(int argc, char* argv[])
});
}
}
os::tty::stopread();
os::tty::readline::finish();
readln.join();
logger->stop(); // Logger must be stopped first to prevent reconnection.
domain->SIGNAL(tier::general, e2::conio::quit, msg, (utf::concat(prompt::main, "Server shutdown")));
Expand Down

0 comments on commit cb639cb

Please sign in to comment.