Suppress macro expansion
[rofl0r-conpix.git] / ConsoleWindow.cpp
blobfc48a8f74300844d8d907f29b5b2026b262db997
1 /*
2 * ConsoleWindow.cpp
4 * Created on: 29.11.2010
5 * Author: rofl
6 */
7 #include <assert.h>
9 #include "ConsoleWindow.h"
10 #include "Format.h"
12 using std::string;
14 ConsoleWindow::ConsoleWindow(ILogger* _logger) {
15 logger = _logger;
16 lastattr = 0;
17 inittables();
18 ncurses::initscr();
19 ncurses::noecho();
20 ncurses::cbreak();
21 ncurses::keypad(ncurses::stdscr, TRUE);
22 hasColors = ncurses::has_colors();
23 canChangeColors = hasColors ? ncurses::can_change_color() : false;
24 if (hasColors) ncurses::start_color();
25 if (canChangeColors) saveColors();
26 maxcol = 0;
27 log(format("hascolors: %d" , hasColors));
28 log(format("canchangecolors: %d" , canChangeColors));
32 ConsoleWindow::~ConsoleWindow() {
33 clear();
34 refresh();
35 if (canChangeColors) restoreColors();
36 ncurses::endwin();
39 void ConsoleWindow::saveColors() {
40 for (short int i = 0; i < colorpaircount; i++) {
41 short int r,g,b;
42 ncurses::color_content(i, &r, &g, &b);
43 org_colors[i] = rgb(fromThousand(r), fromThousand(g), fromThousand(b));
45 for (short int i = 1; i < colorpaircount; i++) {
46 short int f, b;
47 ncurses::pair_content(i, &f, &b);
48 assert(f < colorpaircount && b < colorpaircount);
49 org_fgcolors[i] = f;
50 org_bgcolors[i] = b;
54 void ConsoleWindow::restoreColors() {
55 for (short int i = 0; i < colorpaircount; i++) {
56 setCursesColor((int)i-1, org_colors[i]);
58 for (short int i = 1; i < colorpaircount; i++) {
59 ncurses::init_pair(i, org_fgcolors[i], org_fgcolors[i]);
63 void ConsoleWindow::log(string s) {
64 if (logger != NULL) logger->logln(s);
67 void ConsoleWindow::inittables() {
68 for (int i = 0; i < colorpaircount; i++) colors[i]=-1;
69 actfgcol = -1;
70 actbgcol = -1;
73 bool ConsoleWindow::setColor(RGB mycolor, bool fg) {
74 log(format("setcolor %d, %d, %d", mycolor.r, mycolor.g, mycolor.b));
75 // see if it's the actual color...
76 if (fg) {
77 if (actfgcol >= 0) {
78 if (colors[actfgcol] == (int32_t) mycolor.asInt) return true;
80 } else {
81 if (actbgcol >= 0) {
82 if (colors[actbgcol] == (int32_t) mycolor.asInt) return true;
86 // this (c|sh)ould be optimized by using a not-yet-existing-in-c++-hashmap
87 for (int i = 0; i < colorpaircount; i++) {
88 if (colors[i] == -1) {
89 colors[i] = mycolor.asInt;
90 setCursesColor(i, mycolor);
92 if (colors[i] == -1 || colors[i] == (int32_t) mycolor.asInt ) {
93 if(fg) actfgcol = i; else actbgcol = i;
94 return true;
97 assert (false); // "could not set color");
98 return false;
101 void ConsoleWindow::initoutput() {
102 if (actfgcol == -1) setColor(rgb(0xFF, 0xFF, 0xFF),true);
103 if (actbgcol == -1) setColor(rgb(0, 0, 0),false);
104 int32_t* ptrfg = &colors[actfgcol];
105 int32_t* ptrbg = &colors[actbgcol];
106 for(int i=0;i<colorpaircount;i++) {
107 if(fgcolors[i] == ptrfg) {
108 if (bgcolors[i]!=ptrbg) continue;
109 else {
110 useColorPair(i);
111 return;
113 } else if (fgcolors[i] == NULL) {
114 fgcolors[i]=ptrfg;
115 bgcolors[i]=ptrbg;
116 setColorPair(i, actfgcol, actbgcol);
117 useColorPair(i);
118 return;
121 assert(false); // "colorpair not found");
124 int ConsoleWindow::fromThousand(int in) {
125 return in == 0 ? 0 : in == 1000 ? 255 : (in * 1000 * 1000) / 3921568;
129 int ConsoleWindow::toThousand(int in) {
130 // i dont like floats...
131 return in == 0 ? 0 : in == 255 ? 1000 : (in * 3921568) / (1000 * 1000);
134 bool ConsoleWindow::setCursesColor(int colornumber, RGB color) {
135 log(format("setCursesColor %d: %d %d %d",colornumber, color.r, color.g, color.b));
136 assert(colornumber < colorpaircount);
137 // we use rgb values in the range 0-0xFF, while ncurses max is 1000
138 if(!canChangeColors) return false;
140 int nr = toThousand(color.r);
141 int ng = toThousand(color.g);
142 int nb = toThousand(color.b);
143 return ncurses::init_color(colornumber+1, nr, ng, nb) != FALSE;
146 bool ConsoleWindow::setColorPair(int pair, int fgcol, int bgcol) {
147 log(format("setColorPair %d, fg: %d bg: %d", pair, fgcol, bgcol));
148 assert(fgcol < colorpaircount && bgcol < colorpaircount); // "color pair is out of index");
149 if (!hasColors) return false;
150 fgcolors[pair] = &colors[fgcol];
151 bgcolors[pair] = &colors[bgcol];
152 return ncurses::init_pair(pair+1, fgcol+1, bgcol+1) != FALSE;
155 bool ConsoleWindow::useColorPair(int pair) {
156 log(format("useColorPair %d", pair));
157 assert(pair < colorpaircount);
158 if (!hasColors) return false;
159 if (lastattr) ncurses::wattr_off(ncurses::stdscr,lastattr,NULL);
160 lastattr = COLOR_PAIR(pair+1);
161 ncurses::wattr_on(ncurses::stdscr, lastattr, NULL);
162 return true;
165 void ConsoleWindow::getSize(int& x, int& y){
166 if(ncurses::stdscr) {
167 x = (ncurses::getmaxx)(ncurses::stdscr);
168 y = (ncurses::getmaxy)(ncurses::stdscr);
169 } else { y = -1; x = -1; }
172 void ConsoleWindow::gotoxy(int x, int y) {
173 ncurses::move(y, x);
176 void ConsoleWindow::addchar(int c, unsigned int attributes) {
177 initoutput();
178 ncurses::waddch(ncurses::stdscr, c | attributes);
182 void ConsoleWindow::printfxy (int x, int y, char* text) {
183 initoutput();
184 ncurses::mvprintw(x, y, "%s", text);
187 char ConsoleWindow::getKey() {
188 return ncurses::wgetch(ncurses::stdscr);
191 void ConsoleWindow::sleep(int ms) {
192 ncurses::napms(ms);
195 void ConsoleWindow::refresh() {
196 ncurses::refresh();
199 void ConsoleWindow::clear() {
200 ncurses::clear();