#include "piconsole.h" PIConsole::PIConsole(bool startNow, KeyFunc slot): PIThread() { setPriority(piLow); needLockRun(true); ret_func = slot; num_format = 0; cur_tab = width = height = my = 0; #ifdef WINDOWS ulcoord.X = ulcoord.Y = 0; hOut = GetStdHandle(STD_OUTPUT_HANDLE); GetConsoleScreenBufferInfo(hOut, &sbi); dattr = sbi.wAttributes; width = sbi.srWindow.Right - sbi.srWindow.Left; height = sbi.srWindow.Bottom - sbi.srWindow.Top; GetConsoleMode(hOut, &smode); GetConsoleCursorInfo(hOut, &curinfo); #endif addTab(PIString("main")); listener = new PIKbdListener(key_event, this); if (startNow) start(40); } PIConsole::~PIConsole() { if (isRunning()) { stop(); waitForFinish(); moveTo(0, my + 4); showCursor(); } delete listener; clearTabs(false); #ifdef WINDOWS SetConsoleMode(hOut, smode); SetConsoleTextAttribute(hOut, dattr); #endif } int PIConsole::addTab(PIString name, char bind_key) { tabs.push_back(Tab(name, bind_key)); cur_tab = tabs.size() - 1; return tabs.size(); } void PIConsole::removeTab(uint index) { if (index >= tabs.size()) return; tabs.erase(vector::iterator(&tabs[index])); if (cur_tab >= tabs.size()) cur_tab = tabs.size() - 1; } void PIConsole::removeTab(PIString name) { uint index = tabs.size() + 1; for (uint i = 0; i < tabs.size(); ++i) { if (tabs[i].name == name) { index = i; break; } } removeTab(index); } bool PIConsole::setTab(uint index) { if (index >= tabs.size() || index < 0) return false; cur_tab = index; if (!isRunning()) return true; lock(); clearScreen(); fillLabels(); unlock(); return true; } bool PIConsole::setTab(PIString name) { uint index = tabs.size() + 1; for (uint i = 0; i < tabs.size(); ++i) { if (tabs[i].name == name) { index = i; break; } } return setTab(index); } bool PIConsole::setTabBindKey(uint index, char bind_key) { if (index < 0 || index >= tabs.size()) return false; tabs[index].key = bind_key; return true; } bool PIConsole::setTabBindKey(PIString name, char bind_key) { uint index =tabs.size() + 1; for (uint i = 0; i < tabs.size(); ++i) { if (tabs[i].name == name) { index = i; break; } } return setTabBindKey(index, bind_key); } void PIConsole::key_event(void * t, char key) { PIConsole * p = (PIConsole * )t; for (uint i = 0; i < p->tabsCount(); ++i) { if (p->tabs[i].key == key) { p->setTab(i); return; } } if (p->ret_func != 0) p->ret_func(t, key); } PIString PIConsole::fstr(Flags f) { if (f[PIConsole::Dec]) num_format = 0; if (f[PIConsole::Hex]) num_format = 1; if (f[PIConsole::Oct]) num_format = 2; if (f[PIConsole::Scientific]) num_format = 3; #ifdef WINDOWS WORD attr = dattr; if (f[PIConsole::Inverse]) { if (f[PIConsole::Red]) attr |= BACKGROUND_RED; if (f[PIConsole::Green]) attr |= BACKGROUND_GREEN; if (f[PIConsole::Blue]) attr |= BACKGROUND_BLUE; if (f[PIConsole::Yellow]) attr |= (BACKGROUND_RED | BACKGROUND_GREEN); if (f[PIConsole::Magenta]) attr |= (BACKGROUND_RED | BACKGROUND_BLUE); if (f[PIConsole::Cyan]) attr |= (BACKGROUND_GREEN | BACKGROUND_BLUE); if (f[PIConsole::White]) attr |= (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE); attr |= (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); } else { if (f[PIConsole::Red]) attr |= FOREGROUND_RED; if (f[PIConsole::Green]) attr |= FOREGROUND_GREEN; if (f[PIConsole::Blue]) attr |= FOREGROUND_BLUE; if (f[PIConsole::Yellow]) attr |= (FOREGROUND_RED | FOREGROUND_GREEN); if (f[PIConsole::Magenta]) attr |= (FOREGROUND_RED | FOREGROUND_BLUE); if (f[PIConsole::Cyan]) attr |= (FOREGROUND_GREEN | FOREGROUND_BLUE); if (f[PIConsole::White]) attr |= (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); } if (f[PIConsole::Bold]) attr |= FOREGROUND_INTENSITY; SetConsoleTextAttribute(hOut, attr); return PIString(); #else PIString ts("\e[0"); if (f[PIConsole::Bold]) ts += ";1"; if (f[PIConsole::Faint]) ts += ";2"; if (f[PIConsole::Italic]) ts += ";3"; if (f[PIConsole::Underline]) ts += ";4"; if (f[PIConsole::Blink]) ts += ";5"; if (f[PIConsole::Inverse]) ts += ";7"; if (f[PIConsole::Black]) ts += ";30"; if (f[PIConsole::Red]) ts += ";31"; if (f[PIConsole::Green]) ts += ";32"; if (f[PIConsole::Yellow]) ts += ";33"; if (f[PIConsole::Blue]) ts += ";34"; if (f[PIConsole::Magenta]) ts += ";35"; if (f[PIConsole::Cyan]) ts += ";36"; if (f[PIConsole::White]) ts += ";37"; return ts + "m"; #endif } #define siprint(x) switch (num_format) {case (1): return printf("0x%.4hX", x); break; case (2): return printf("%o", x); break; default: return printf("%hd", x); break;} #define iprint(x) switch (num_format) {case (1): return printf("0x%.8X", x); break; case (2): return printf("%o", x); break; default: return printf("%d", x); break;} #define liprint(x) switch (num_format) {case (1): return printf("0x%.16lX", x); break; case (2): return printf("%lo", x); break; default: return printf("%ld", x); break;} #define lliprint(x) switch (num_format) {case (1): return printf("0x%.16LX", x); break; case (2): return printf("%Lo", x); break; default: return printf("%Ld", x); break;} #define suprint(x) switch (num_format) {case (1): return printf("0x%.4hX", x); break; case (2): return printf("%o", x); break; default: return printf("%hd", x); break;} #define uprint(x) switch (num_format) {case (1): return printf("0x%.8X", x); break; case (2): return printf("%o", x); break; default: return printf("%u", x); break;} #define luprint(x) switch (num_format) {case (1): return printf("0x%.16lX", x); break; case (2): return printf("%lo", x); break; default: return printf("%lu", x); break;} #define lluprint(x) switch (num_format) {case (1): return printf("0x%.16LX", x); break; case (2): return printf("%Lo", x); break; default: return printf("%Lu", x); break;} #define fprint(x) switch (num_format) {case (3): return printf("%e", x); break; default: return printf("%.5g", x); break;} #define dprint(x) switch (num_format) {case (3): return printf("%le", x); break; default: return printf("%.5lg", x); break;} inline int PIConsole::couts(const string v) {return printf("%s", v.c_str());} inline int PIConsole::couts(const char * v) {return printf("%s", v);} inline int PIConsole::couts(const bool v) {return (v ? printf("true") : printf("false"));} inline int PIConsole::couts(const char v) {return printf("%c", v);} inline int PIConsole::couts(const short v) {siprint(v);} inline int PIConsole::couts(const int v) {iprint(v);} inline int PIConsole::couts(const long v) {liprint(v);} inline int PIConsole::couts(const llong v) {lliprint(v);} inline int PIConsole::couts(const uchar v) {uprint(v);} inline int PIConsole::couts(const ushort v) {suprint(v);} inline int PIConsole::couts(const uint v) {uprint(v);} inline int PIConsole::couts(const ulong v) {luprint(v);} inline int PIConsole::couts(const ullong v) {lluprint(v);} inline int PIConsole::couts(const float v) {fprint(v);} inline int PIConsole::couts(const double v) {dprint(v);} void PIConsole::begin() { #ifdef WINDOWS SetConsoleMode(hOut, ENABLE_WRAP_AT_EOL_OUTPUT); #endif clearScreen(); hideCursor(); fillLabels(); } void PIConsole::run() { uint cx, clen = 0; #ifdef WINDOWS GetConsoleScreenBufferInfo(hOut, &sbi); width = sbi.srWindow.Right - sbi.srWindow.Left; height = sbi.srWindow.Bottom - sbi.srWindow.Top; #else winsize ws; ioctl(0, TIOCGWINSZ, &ws); width = ws.ws_col; height = ws.ws_row; #endif col_cnt = vars().size(); col_wid = (col_cnt > 0) ? width / col_cnt : width; for (uint i = 0; i < col_cnt; ++i) { cx = col_wid * i; toUpperLeft(); for (uint j = 0; j < vars()[i].size(); ++j) { if (my < j) my = j; tv = vars()[i][j]; moveRight(cx); if (tv.name.size() == 0) { newLine(); continue; } if (tv.type == 0 && tv.s == 0) { newLine(); continue; } moveRight(tv.offset); switch (tv.type) { case 0: clen = printValue(*tv.s, tv.format); break; case 1: clen = printValue(*tv.b, tv.format); break; case 2: clen = printValue(*tv.i, tv.format); break; case 3: clen = printValue(*tv.l, tv.format); break; case 4: clen = printValue(*tv.c, tv.format); break; case 5: clen = printValue(*tv.f, tv.format); break; case 6: clen = printValue(*tv.d, tv.format); break; case 7: clen = printValue(*tv.sh, tv.format); break; case 8: clen = printValue(*tv.ui, tv.format); break; case 9: clen = printValue(*tv.ul, tv.format); break; case 10: clen = printValue(*tv.ush, tv.format); break; case 11: clen = printValue(*tv.uc, tv.format); break; case 12: clen = printValue(*tv.ll, tv.format); break; case 13: clen = printValue(*tv.ull, tv.format); break; case 14: clen = printValue(bitsValue(tv.uc, tv.bitFrom, tv.bitCount), tv.format); break; } if (clen + tv.offset < (uint)col_wid) printf("%s", PIString(col_wid - clen - tv.offset, ' ').data()); newLine(); } } fflush(0); } void PIConsole::fillLabels() { uint cx, my = 0; #ifdef WINDOWS GetConsoleScreenBufferInfo(hOut, &sbi); width = sbi.srWindow.Right - sbi.srWindow.Left; height = sbi.srWindow.Bottom - sbi.srWindow.Top; #else winsize ws; ioctl(0, TIOCGWINSZ, &ws); width = ws.ws_col; height = ws.ws_row; #endif col_cnt = vars().size(); col_wid = (col_cnt > 0) ? width / col_cnt : width; for (uint i = 0; i < col_cnt; ++i) { cx = col_wid * i; toUpperLeft(); for (uint j = 0; j < vars()[i].size(); ++j) { if (my < j) my = j; moveRight(cx); tv = vars()[i][j]; if (tv.name.size() == 0) { newLine(); continue; } clearLine(); if (tv.type == 0 && tv.s == 0) { printLine(tv.name, cx, tv.format); newLine(); continue; } vars()[i][j].offset = printValue(tv.name + ": ", tv.format); newLine(); } } moveTo(0, my + 2); if (tabs[cur_tab].status.length() > 0) { printValue(tabs[cur_tab].status); newLine(); } status(); //fflush(0); } void PIConsole::status() { Tab * ctab; //clearLine(); for (uint i = 0; i < tabsCount(); ++i) { ctab = &tabs[i]; if (ctab->key == 0) continue; printValue(ctab->key, PIConsole::Bold); printValue(ctab->name + " ", PIConsole::Cyan | PIConsole::Inverse); printValue(PIString(" "), PIConsole::Normal); } newLine(); } int PIConsole::bitsValue(unsigned char * src, int offset, int count) { int ret = 0, stbyte = offset / 8, cbit = offset - stbyte * 8; char cbyte = src[stbyte]; for (int i = 0; i < count; i++) { ret |= ((cbyte >> cbit & 1) << i); cbit++; if (cbit == 8) { cbit = 0; stbyte++; cbyte = src[stbyte]; } } return ret; } #define ADD_VAR_BODY tv.name = name; tv.bitFrom = tv.bitCount = 0; tv.format = format; checkColumn(column); void PIConsole::addString(PIString name, int column, Flags format) { ADD_VAR_BODY tv.type = 0; tv.s = 0; vars()[column - 1].push_back(tv);} void PIConsole::addVariable(PIString name, PIString* ptr, int column, Flags format) { ADD_VAR_BODY tv.type = 0; tv.s = ptr; vars()[column - 1].push_back(tv);} void PIConsole::addVariable(PIString name, bool * ptr, int column, Flags format) { ADD_VAR_BODY tv.type = 1; tv.b = ptr; vars()[column - 1].push_back(tv);} void PIConsole::addVariable(PIString name, int * ptr, int column, Flags format) { ADD_VAR_BODY tv.type = 2; tv.i = ptr; vars()[column - 1].push_back(tv);} void PIConsole::addVariable(PIString name, long * ptr, int column, Flags format) { ADD_VAR_BODY tv.type = 3; tv.l = ptr; vars()[column - 1].push_back(tv);} void PIConsole::addVariable(PIString name, char * ptr, int column, Flags format) { ADD_VAR_BODY tv.type = 4; tv.c = ptr; vars()[column - 1].push_back(tv);} void PIConsole::addVariable(PIString name, float * ptr, int column, Flags format) { ADD_VAR_BODY tv.type = 5; tv.f = ptr; vars()[column - 1].push_back(tv);} void PIConsole::addVariable(PIString name, double * ptr, int column, Flags format) { ADD_VAR_BODY tv.type = 6; tv.d = ptr; vars()[column - 1].push_back(tv);} void PIConsole::addVariable(PIString name, short * ptr, int column, Flags format) { ADD_VAR_BODY tv.type = 7; tv.sh = ptr; vars()[column - 1].push_back(tv);} void PIConsole::addVariable(PIString name, uint * ptr, int column, Flags format) { ADD_VAR_BODY tv.type = 8; tv.ui = ptr; vars()[column - 1].push_back(tv);} void PIConsole::addVariable(PIString name, ulong * ptr, int column, Flags format) { ADD_VAR_BODY tv.type = 9; tv.ul = ptr; vars()[column - 1].push_back(tv);} void PIConsole::addVariable(PIString name, ushort * ptr, int column, Flags format) { ADD_VAR_BODY tv.type = 10; tv.ush = ptr; vars()[column - 1].push_back(tv);} void PIConsole::addVariable(PIString name, uchar * ptr, int column, Flags format) { ADD_VAR_BODY tv.type = 11; tv.uc = ptr; vars()[column - 1].push_back(tv);} void PIConsole::addVariable(PIString name, llong * ptr, int column, Flags format) { ADD_VAR_BODY tv.type = 12; tv.ll = ptr; vars()[column - 1].push_back(tv);} void PIConsole::addVariable(PIString name, ullong * ptr, int column, Flags format) { ADD_VAR_BODY tv.type = 13; tv.ull = ptr; vars()[column - 1].push_back(tv);} void PIConsole::addBitVariable(PIString name, uchar * ptr, int fromBit, int bitCount, int column, Flags format) { tv.name = name; tv.bitFrom = fromBit; tv.bitCount = bitCount; tv.type = 14; tv.uc = ptr; tv.format = format; checkColumn(column); vars()[column - 1].push_back(tv);} void PIConsole::addEmptyLine(int column) { tv.name = ""; tv.type = 0; tv.d = 0; tv.format = Normal; checkColumn(column); vars()[column - 1].push_back(tv);} #define PRINT_VAR_BODY couts(fstr(format).stdString()); int ret = couts(value); fstr(PIConsole::Dec); return ret; inline void PIConsole::printLine(const PIString & value, int dx, Flags format) { int i = width - value.length() - dx; #ifdef QNX --i; #endif couts(fstr(format).stdString()); if (i >= 0) couts((value + PIString(i, ' ')).stdString()); else couts(value.left(value.size() + i).stdString()); couts(fstr(Dec).stdString()); } inline int PIConsole::printValue(const PIString & value, Flags format) { couts(fstr(format).stdString()); int ret = couts(value.stdString()); fstr(PIConsole::Dec); return ret; } inline int PIConsole::printValue(const char * value, Flags format) {PRINT_VAR_BODY} inline int PIConsole::printValue(const bool value, Flags format) {PRINT_VAR_BODY} inline int PIConsole::printValue(const int value, Flags format) {PRINT_VAR_BODY} inline int PIConsole::printValue(const long value, Flags format) {PRINT_VAR_BODY} inline int PIConsole::printValue(const llong value, Flags format) {PRINT_VAR_BODY} inline int PIConsole::printValue(const float value, Flags format) {PRINT_VAR_BODY} inline int PIConsole::printValue(const double value, Flags format) {PRINT_VAR_BODY} inline int PIConsole::printValue(const char value, Flags format) {PRINT_VAR_BODY} inline int PIConsole::printValue(const short value, Flags format) {PRINT_VAR_BODY} inline int PIConsole::printValue(const uchar value, Flags format) {PRINT_VAR_BODY} inline int PIConsole::printValue(const ushort value, Flags format) {PRINT_VAR_BODY} inline int PIConsole::printValue(const uint value, Flags format) {PRINT_VAR_BODY} inline int PIConsole::printValue(const ulong value, Flags format) {PRINT_VAR_BODY} inline int PIConsole::printValue(const ullong value, Flags format) {PRINT_VAR_BODY}