//-------------------------------------------------------------------- // $Id: ConWin.cpp 4617 2005-03-23 23:04:29Z cjm $ //-------------------------------------------------------------------- // // Visual Binary Diff // Copyright 1997-2005 by Christopher J. Madsen // // Support class for curses applications // //-------------------------------------------------------------------- #include #include "ConWin.hpp" void exitMsg(int status, const char* message); // From vbindiff.cpp enum ColorPair { pairWhiteBlue= 1, pairWhiteBlack, pairRedBlue, pairYellowBlue }; static const ColorPair colorStyle[] = { pairWhiteBlue, // cBackground pairWhiteBlue, // cPromptWin pairWhiteBlue, // cPromptKey pairWhiteBlue, // cPromptBdr pairWhiteBlack, // cCurrentMode pairWhiteBlack, // cFileName pairWhiteBlue, // cFileWin pairRedBlue, // cFileDiff pairYellowBlue // cFileEdit }; static const attr_t attribStyle[] = { COLOR_PAIR(colorStyle[ cBackground ]), COLOR_PAIR(colorStyle[ cPromptWin ]), A_BOLD | COLOR_PAIR(colorStyle[ cPromptKey ]), A_BOLD | COLOR_PAIR(colorStyle[ cPromptBdr ]), A_REVERSE | COLOR_PAIR(colorStyle[ cCurrentMode]), A_REVERSE | COLOR_PAIR(colorStyle[ cFileName ]), COLOR_PAIR(colorStyle[ cFileWin ]), A_BOLD | COLOR_PAIR(colorStyle[ cFileDiff ]), A_BOLD | COLOR_PAIR(colorStyle[ cFileEdit ]) }; //==================================================================== // Class ConWindow: //-------------------------------------------------------------------- ////////////////////////////////////////////////////////////////////// // Static Member Functions: //-------------------------------------------------------------------- // Start up the window system: // // Allocates a screen buffer and sets input mode: // // Returns: // true: Everything set up properly // false: Unable to initialize bool ConWindow::startup() { if (!initscr()) return false; // initialize the curses library atexit(ConWindow::shutdown); // just in case keypad(stdscr, true); // enable keyboard mapping nonl(); // tell curses not to do NL->CR/NL on output cbreak(); // take input chars one at a time, no wait for \n noecho(); // do not echo input if (has_colors()) { start_color(); init_pair(pairWhiteBlue, COLOR_WHITE, COLOR_BLUE); init_pair(pairWhiteBlack, COLOR_WHITE, COLOR_BLACK); init_pair(pairRedBlue, COLOR_RED, COLOR_BLUE); init_pair(pairYellowBlue, COLOR_YELLOW, COLOR_BLUE); } // end if terminal has color return true; } // end ConWindow::startup //-------------------------------------------------------------------- // Shut down the window system: // // Deallocate the screen buffer and restore the original input mode. void ConWindow::shutdown() { if (!isendwin()) { showCursor(); endwin(); } } // end ConWindow::shutdown ////////////////////////////////////////////////////////////////////// // Member Functions: //-------------------------------------------------------------------- // Constructor: ConWindow::ConWindow() : pan(NULL), win(NULL) { } // end ConWindow::ConWindow //-------------------------------------------------------------------- // Destructor: ConWindow::~ConWindow() { close(); } // end ConWindow::~ConWindow //-------------------------------------------------------------------- // Initialize the window: // // Must be called only once, before any other functions are called. // Allocates the data structures and clears the window buffer, but // does not display anything. // // Input: // x,y: The position of the window in the screen buffer // width,height: The size of the window // attrib: The default attributes for the window void ConWindow::init(short x, short y, short width, short height, Style attrib) { if ((win = newwin(height, width, y, x)) == 0) exitMsg(99, "Internal error: Failed to create window"); if ((pan = new_panel(win)) == 0) exitMsg(99, "Internal error: Failed to create panel"); wbkgdset(win, attribStyle[attrib] | ' '); keypad(win, TRUE); // enable keyboard mapping clear(); } // end ConWindow::init //-------------------------------------------------------------------- void ConWindow::close() { if (pan) { del_panel(pan); pan = NULL; } if (win) { delwin(win); win = NULL; } } // end ConWindow::close //-------------------------------------------------------------------- // Write a string using the current attributes: // // Input: // x,y: The start of the string in the window // s: The string to write //void ConWindow::put(short x, short y, const char* s) ///void ConWindow::put(short x, short y, const String& s) ///{ /// PCHAR_INFO out = data + x + size.X * y; /// StrConstItr c = s.begin(); /// /// while (c != s.end()) { /// out->Char.AsciiChar = *c; /// out->Attributes = attribs; /// ++out; /// ++c; /// } ///} // end ConWindow::put //-------------------------------------------------------------------- // Change the attributes of characters in the window: // // Input: // x,y: The position in the window to start changing attributes // color: The attribute to set // count: The number of characters to change void ConWindow::putAttribs(short x, short y, Style color, short count) { mvwchgat(win, y, x, count, attribStyle[color], colorStyle[color], NULL); touchwin(win); } // end ConWindow::putAttribs //-------------------------------------------------------------------- // Write a character using the current attributes: // // Input: // x,y: The position in the window to start writing // c: The character to write // count: The number of characters to write void ConWindow::putChar(short x, short y, char c, short count) { wmove(win, y, x); while (count--) { waddch(win, c); } } // end ConWindow::putAttribs //-------------------------------------------------------------------- // Read the next key down event: // // Output: // event: Contains a key down event int ConWindow::readKey() { top_panel(pan); update_panels(); doupdate(); return wgetch(win); } // end ConWindow::readKey //-------------------------------------------------------------------- void ConWindow::resize(short width, short height) { if (wresize(win, height, width) != OK) exitMsg(99, "Internal error: Failed to resize window"); replace_panel(pan, win); clear(); } // end ConWindow::resize //-------------------------------------------------------------------- void ConWindow::setAttribs(Style color) { wattrset(win, attribStyle[color]); } // end ConWindow::setAttribs //-------------------------------------------------------------------- // Position the cursor in the window: // // There is only one cursor, and each window does not maintain its own // cursor position. // // Input: // x,y: The position in the window for the cursor void ConWindow::setCursor(short x, short y) { // ASSERT((x>=0)&&(x=0)&&(y