Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2008-07-02 20:59:52 +0000
committerStijn Buys <ingar@osirion.org>2008-07-02 20:59:52 +0000
commit560b0e18684058ca458e84df393993895a012711 (patch)
tree28921f19ffd7db4658d6c207b4ac20c4bdf10d58
parent1e4986e9135090997da7688026b4b499c582e9e7 (diff)
fixes ncurses console resize crash
-rw-r--r--src/server/console.cc230
-rw-r--r--src/server/console.h7
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 <iostream>
+#include <queue>
#include "server/console.h"
#include "core/core.h"
#include "sys/consoleinterface.h"
+#include "auxiliary/functions.h"
#ifdef HAVE_CURSES
#include <ncurses.h>
@@ -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<std::string> 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<std::string>::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<std::string>::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<std::string>::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
};