| @@ -44,6 +44,8 @@ using namespace lol; | |||
| Pty::Pty(ivec2 size) | |||
| : m_fd(-1), | |||
| m_pid(-1), | |||
| m_unread_data(0), | |||
| m_unread_len(0), | |||
| m_size(size) | |||
| { | |||
| ; | |||
| @@ -51,6 +53,8 @@ Pty::Pty(ivec2 size) | |||
| Pty::~Pty() | |||
| { | |||
| delete m_unread_data; | |||
| if (m_fd >= 0) | |||
| { | |||
| close((int)m_fd); | |||
| @@ -101,6 +105,20 @@ void Pty::Run(char const *command) | |||
| size_t Pty::ReadData(char *data, size_t maxlen) | |||
| { | |||
| /* Do we have data from previous call? */ | |||
| if (m_unread_len) | |||
| { | |||
| /* FIXME: check that m_unread_len < maxlen */ | |||
| memcpy(data, m_unread_data, m_unread_len); | |||
| data += m_unread_len; | |||
| maxlen -= m_unread_len; | |||
| delete[] m_unread_data; | |||
| m_unread_data = 0; | |||
| m_unread_len = 0; | |||
| } | |||
| fd_set fdset; | |||
| int maxfd = -1; | |||
| @@ -138,6 +156,25 @@ size_t Pty::ReadData(char *data, size_t maxlen) | |||
| return 0; | |||
| } | |||
| void Pty::UnreadData(char *data, size_t len) | |||
| { | |||
| char *new_data; | |||
| if (m_unread_data) | |||
| { | |||
| new_data = new char[m_unread_len + len]; | |||
| memcpy(new_data + len, m_unread_data, m_unread_len); | |||
| delete[] m_unread_data; | |||
| } | |||
| else | |||
| { | |||
| new_data = new char[len]; | |||
| } | |||
| memcpy(new_data, data, len); | |||
| m_unread_data = new_data; | |||
| } | |||
| void Pty::SetWindowSize(ivec2 size) | |||
| { | |||
| #if defined HAVE_PTY_H || defined HAVE_UTIL_H || defined HAVE_LIBUTIL_H | |||
| @@ -13,12 +13,15 @@ public: | |||
| void Run(char const *command); | |||
| size_t ReadData(char *data, size_t maxlen); | |||
| void UnreadData(char *data, size_t len); | |||
| void SetWindowSize(ivec2 size); | |||
| private: | |||
| int64_t m_fd; | |||
| int64_t m_pid; | |||
| char const *m_argv[2]; | |||
| char *m_unread_data; | |||
| size_t m_unread_len; | |||
| ivec2 m_size; | |||
| }; | |||
| @@ -24,6 +24,9 @@ Term::Term(ivec2 size) | |||
| char const *shell = getenv("SHELL"); | |||
| if (!shell) | |||
| shell = "/bin/sh"; | |||
| shell = "cacaclock"; | |||
| shell = "cacademo"; | |||
| shell = "cacafire"; | |||
| m_pty->Run(shell); | |||
| #endif | |||
| } | |||
| @@ -37,13 +40,21 @@ void Term::TickGame(float seconds) | |||
| /* XXX: for now we draw fancy shit */ | |||
| m_time += seconds; | |||
| size_t total = 0; | |||
| for (;;) | |||
| { | |||
| char buf[BUFSIZ]; | |||
| size_t bytes = m_pty->ReadData(buf, BUFSIZ); | |||
| if (bytes <= 0) | |||
| size_t current = m_pty->ReadData(buf, BUFSIZ); | |||
| if (current <= 0) | |||
| break; | |||
| ReadAnsi(buf, bytes); | |||
| total += current; | |||
| size_t processed = ReadAnsi(buf, current); | |||
| if (processed < current) | |||
| m_pty->UnreadData(buf + processed, current - processed); | |||
| if (current < BUFSIZ) | |||
| break; | |||
| // if (total > 10000) | |||
| // break; | |||
| } | |||
| #else | |||
| /* Unsupported platform - draw some fancy shit instead */ | |||
| @@ -158,4 +169,4 @@ void Term::DrawFancyShit() | |||
| caca_put_str(m_caca, 0, 2, "root@lol:~/ echo LOL"); | |||
| caca_put_str(m_caca, 0, 3, "LOL"); | |||
| caca_put_str(m_caca, 0, 4, "root@lol:~/"); | |||
| } | |||
| } | |||