#include "terminal.h" #include "base/dbus.h" #include "base/file.h" #include "base/logging.h" #include "base/strings.h" #include #include #include #include #include using namespace cutefish; namespace dm { static int openVt(int vt) { return ::open(("/dev/tty" + std::to_string(vt)).c_str(), O_RDWR | O_NOCTTY | O_CLOEXEC); } bool setGraphicsMode(int vt) { const int fd = openVt(vt); if (fd < 0) return false; const bool set = ioctl(fd, KDSETMODE, KD_GRAPHICS) == 0; ::close(fd); return set; } void restoreTextMode(int vt) { const int fd = openVt(vt); if (fd < 0) return; vt_mode mode {}; int kdMode = KD_TEXT; if (ioctl(fd, VT_GETMODE, &mode) == 0 && mode.mode == VT_AUTO && ioctl(fd, KDGETMODE, &kdMode) == 0 && kdMode == KD_GRAPHICS) ioctl(fd, KDSETMODE, KD_TEXT); ::close(fd); } bool isControlled(int vt) { const int fd = openVt(vt); if (fd < 0) return false; vt_mode mode {}; const bool controlled = ioctl(fd, VT_GETMODE, &mode) == 0 && mode.mode == VT_PROCESS; ::close(fd); return controlled; } int activeVt() { const std::optional active = base::file::read("/sys/class/tty/tty0/active"); if (!active) return 0; const std::string_view name = base::strings::trimmed(*active); return name.size() > 3 ? base::strings::toNumber(name.substr(3)).value_or(0) : 0; } bool activateSession(const std::string &sessionId) { const base::dbus::Proxy manager(base::dbus::Connection::system(), "org.freedesktop.login1", "/org/freedesktop/login1", "org.freedesktop.login1.Manager"); const base::dbus::Reply reply = manager.call("ActivateSession", sessionId); if (reply.isError()) CF_WARNING(base::LogCategory::defaultCategory()) << "Cannot activate session" << sessionId << reply.error().message; return !reply.isError(); } } // namespace dm