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