From 560b0e18684058ca458e84df393993895a012711 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Wed, 2 Jul 2008 20:59:52 +0000 Subject: fixes ncurses console resize crash --- src/server/console.cc | 230 ++++++++++++++++++++++++++++++++++++++++++++++---- src/server/console.h | 7 +- 2 files changed, 218 insertions(+), 19 deletions(-) diff --git a/src/server/console.cc b/src/server/console.cc index ea82dff..6b24c0c 100644 --- a/src/server/console.cc +++ b/src/server/console.cc @@ -5,10 +5,12 @@ */ #include +#include #include "server/console.h" #include "core/core.h" #include "sys/consoleinterface.h" +#include "auxiliary/functions.h" #ifdef HAVE_CURSES #include @@ -38,10 +40,24 @@ void Console::init() noecho(); // don't show typed characters keypad(stdwin, TRUE); // enable special keys nodelay(stdwin, TRUE); // non-blocking input - curs_set(0); // disable cursor - + curs_set(1); // disable cursor + + if (has_colors() == TRUE) { + start_color(); + // this is ncurses-specific + use_default_colors(); + // COLOR_PAIR(0) is terminal default + init_pair(1, COLOR_RED, -1); + init_pair(2, COLOR_GREEN, -1); + init_pair(3, COLOR_YELLOW, -1); + init_pair(4, COLOR_BLUE, -1); + init_pair(5, COLOR_CYAN, -1); + init_pair(6, COLOR_MAGENTA, -1); + init_pair(7, -1, -1); + } console_initialized = true; console_updated = true; + #endif // HAVE_CURSES con_print << "Initializing console..." << std::endl; @@ -72,7 +88,13 @@ void Console::resize() endwin(); refresh(); - console_updated = true; + draw_background(); + draw_text(); + draw_input(); + wrefresh(stdwin); + + console_updated = false; + console_lastrefresh = 0; } void Console::flush() @@ -91,15 +113,74 @@ void Console::flush() consoleinterface_buffer.clear(); } +void Console::set_color(const char *color_code) +{ + if (!has_colors()) + return; + + int color = 0; + bool bold = false; + + if (aux::is_base_color_code(color_code)) { + // base colors + // Black=0, Red=1, Green=2, Yellow=3, Blue=4, Cyan=5, Magenta=6, White=7 + + color = *(color_code+1) - '0'; + if (color == 3 || color == 0) + bold = true; + else + bold = false; + + } else if (aux::is_core_color_code(color_code)) { + + switch (*(color_code+1)) { + case 'N': // normal color + case 'D': // debug color + color = 0; + break; + case 'B': // bold color + color = 0; + bold = true; + break; + case 'W': // warning color + color = 3; + bold = true; + break; + case 'R': // error color + color = 1; + bold = true; + break; + case 'F': // fancy color + color = 2; + bold = true; + break; + } + } + + color_set(color, NULL); + if (bold) + attron(A_BOLD); + else + attroff(A_BOLD); + +} + void Console::draw_background() { + color_set(0, NULL); + attroff(A_BOLD); + bkgdset(' '); clear(); // draw version string + color_set(2, NULL); std::string versionstr("The Osirion Project "); versionstr.append(core::version()); - mvaddstr(0, stdwin->_maxx - 1 - versionstr.size(), versionstr.c_str()); + int y = stdwin->_maxx - 1 - versionstr.size(); + if (y < 0) + y = 0; + mvaddnstr(0, y, versionstr.c_str(), stdwin->_maxx - 1); } void Console::draw_text() @@ -110,17 +191,130 @@ void Console::draw_text() if ((w < 3) || (h < 3)) return; - int y = h-1; + std::deque lines; + + int console_scroll = 0; + int height = stdwin->_maxy - 2; + int width = stdwin->_maxx - 1; + int bottom = (int) consoleinterface_text.size() - console_scroll; + int current_line = 0; + + // parse cons0ole text, wrap long lines + for (std::deque::iterator it = consoleinterface_text.begin(); it != consoleinterface_text.end() && current_line < bottom; it++) { + if (current_line >= bottom - height) { + std::string linedata(*it); + linedata += '\n'; + + std::string word; + int word_length = 0; + + std::string line; + int line_length = 0; + + const char *c = linedata.c_str(); + char pen = 'N'; + char wordpen = 'N'; + + while (*c) { + + // color code + if (aux::is_color_code(c)) { + c++; + pen = *c; + word += '^'; + word += pen; + } + + // new word, wrap if necessary + else if ((*c == '\n' ) || ( *c == ' ')) { + + if (line_length + word_length > width) { + if (line.size()) { + lines.push_back(line); + line.clear(); + line += '^'; + line += wordpen; + line_length = 0; + } + } + + line.append(word); + line_length += word_length; + + word.clear(); + word_length = 0; + wordpen = pen; + + // new line + if (*c == '\n' ) { + lines.push_back(line); + line.clear(); + line_length = 0; + // new word + } else if (*c == ' ' ) { + line += ' '; + line_length++; + } + } + + // new character + else { + word += *c; + word_length++; + + if (word_length == width) { + if (line.size()) { + lines.push_back(line); + line.clear(); + line += '^'; + line += wordpen; + line_length = 0; + } + + line.append(word); + line_length = word_length; + + word.clear(); + word_length = 0; + wordpen = pen; + } + } + + c++; + } + + } + current_line++; + } - // draw console text - std::deque::reverse_iterator rit = consoleinterface_text.rbegin(); - while (rit != consoleinterface_text.rend() && y > 0) { - mvaddnstr(y, 0, (*rit).c_str(), w); - ++rit; + int y = stdwin->_maxy - 1; + color_set(0, NULL); + attroff(A_BOLD); + + for (std::deque::reverse_iterator rit = lines.rbegin(); (y > 0) && (rit != lines.rend()); ++rit) { + + const char *c = (*rit).c_str(); + int x = 0; + + while (*c) { + if (aux::is_color_code(c)) { + set_color(c); + c++; + } else { + mvaddnstr(y, x, c, 1); + x++; + } + c++; + } y--; } } +void Console::draw_input() +{ + wmove(stdwin, stdwin->_maxy, 0); +} + void Console::draw() { flush(); @@ -129,16 +323,16 @@ void Console::draw() return; } - if (console_initialized && console_updated && stdwin->_maxx && stdwin->_maxy) { - - draw_background(); - draw_text(); - wrefresh(stdwin); + if (!(console_initialized && console_updated && stdwin->_maxx && stdwin->_maxy)) + return; - console_updated = false; - console_lastrefresh = 0; - } + draw_background(); + draw_text(); + draw_input(); + wrefresh(stdwin); + console_updated = false; + console_lastrefresh = 0; } void Console::frame(float seconds) diff --git a/src/server/console.h b/src/server/console.h index 6a42ba5..eeee0ca 100644 --- a/src/server/console.h +++ b/src/server/console.h @@ -32,9 +32,14 @@ protected: void draw_background(); /// draw the console text (ncurses) void draw_text(); + /// draw the console input (ncurses) + void draw_input(); private: - float console_lastrefresh; + /// set ncurses drawing color + void set_color(const char *color_code); + float console_lastrefresh; + #endif }; -- cgit v1.2.3