fixed building issues on APPLE systems
[rofl0r-conpix.git] / ConsoleWindow.cpp
blobec326f1b005903e8d1b601d2fafbc1f4bbc1e623
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");
100 void ConsoleWindow::initoutput() {
101 if (actfgcol == -1) setColor(rgb(0xFF, 0xFF, 0xFF),true);
102 if (actbgcol == -1) setColor(rgb(0, 0, 0),false);
103 int32_t* ptrfg = &colors[actfgcol];
104 int32_t* ptrbg = &colors[actbgcol];
105 for(int i=0;i<colorpaircount;i++) {
106 if(fgcolors[i] == ptrfg) {
107 if (bgcolors[i]!=ptrbg) continue;
108 else {
109 useColorPair(i);
110 return;
112 } else if (fgcolors[i] == NULL) {
113 fgcolors[i]=ptrfg;
114 bgcolors[i]=ptrbg;
115 setColorPair(i, actfgcol, actbgcol);
116 useColorPair(i);
117 return;
120 assert(false); // "colorpair not found");
123 int ConsoleWindow::fromThousand(int in) {
124 return in == 0 ? 0 : in == 1000 ? 255 : (in * 1000 * 1000) / 3921568;
128 int ConsoleWindow::toThousand(int in) {
129 // i dont like floats...
130 return in == 0 ? 0 : in == 255 ? 1000 : (in * 3921568) / (1000 * 1000);
133 bool ConsoleWindow::setCursesColor(int colornumber, RGB color) {
134 log(format("setCursesColor %d: %d %d %d",colornumber, color.r, color.g, color.b));
135 assert(colornumber < colorpaircount);
136 // we use rgb values in the range 0-0xFF, while ncurses max is 1000
137 if(!canChangeColors) return false;
139 int nr = toThousand(color.r);
140 int ng = toThousand(color.g);
141 int nb = toThousand(color.b);
142 return ncurses::init_color(colornumber+1, nr, ng, nb) != FALSE;
145 bool ConsoleWindow::setColorPair(int pair, int fgcol, int bgcol) {
146 log(format("setColorPair %d, fg: %d bg: %d", pair, fgcol, bgcol));
147 assert(fgcol < colorpaircount && bgcol < colorpaircount); // "color pair is out of index");
148 if (!hasColors) return false;
149 fgcolors[pair] = &colors[fgcol];
150 bgcolors[pair] = &colors[bgcol];
151 return ncurses::init_pair(pair+1, fgcol+1, bgcol+1) != FALSE;
154 bool ConsoleWindow::useColorPair(int pair) {
155 log(format("useColorPair %d", pair));
156 assert(pair < colorpaircount);
157 if (!hasColors) return false;
158 if (lastattr) ncurses::wattr_off(ncurses::stdscr,lastattr,NULL);
159 lastattr = COLOR_PAIR(pair+1);
160 ncurses::wattr_on(ncurses::stdscr, lastattr, NULL);
161 return true;
164 void ConsoleWindow::getSize(int& x, int& y){
165 if(ncurses::stdscr) {
166 x = ncurses::stdscr->_maxx;
167 y = ncurses::stdscr->_maxy;
168 } else { y = -1; x = -1; }
171 void ConsoleWindow::gotoxy(int x, int y) {
172 ncurses::move(y, x);
175 void ConsoleWindow::addchar(int c, unsigned int attributes) {
176 initoutput();
177 ncurses::waddch(ncurses::stdscr, c | attributes);
181 void ConsoleWindow::printfxy (int x, int y, char* text) {
182 initoutput();
183 ncurses::mvprintw(x, y, "%s", text, 0);
186 char ConsoleWindow::getKey() {
187 return ncurses::wgetch(ncurses::stdscr);
190 void ConsoleWindow::sleep(int ms) {
191 ncurses::napms(ms);
194 void ConsoleWindow::refresh() {
195 ncurses::refresh();
198 void ConsoleWindow::clear() {
199 ncurses::clear();