home *** CD-ROM | disk | FTP | other *** search
- // ------------------------------- //
- // -------- Start of File -------- //
- // ------------------------------- //
- // ----------------------------------------------------------- //
- // C++ Source Code File Name: terminal.cpp
- // Compiler Used: MSVC40, DJGPP 2.7.2.1, GCC 2.7.2.1, HP CPP 10.24
- // Produced By: Doug Gaer
- // File Creation Date: 03/21/1997
- // Date Last Modified: 03/15/1999
- // Copyright (c) 1997 Douglas M. Gaer
- // ----------------------------------------------------------- //
- // ------------- Program Description and Details ------------- //
- // ----------------------------------------------------------- //
- /*
- The VBD C++ classes are copyright (c) 1997, by Douglas M. Gaer.
- All those who put this code or its derivatives in a commercial
- product MUST mention this copyright in their documentation for
- users of the products in which this code or its derivative
- classes are used. Otherwise, you have the freedom to redistribute
- verbatim copies of this source code, adapt it to your specific
- needs, or improve the code and release your improvements to the
- public provided that the modified files carry prominent notices
- stating that you changed the files and the date of any change.
-
- THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
- THE ENTIRE RISK OF THE QUALITY AND PERFORMANCE OF THIS SOFTWARE
- IS WITH YOU. SHOULD ANY ELEMENT OF THIS SOFTWARE PROVE DEFECTIVE,
- YOU WILL ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR
- CORRECTION.
-
- This is a terminal interface designed to be portable between
- DOS and UNIX systems. On UNIX systems the "curses" library is
- used to create terminal independent code. On MSDOS/Windows95
- systems the ANSI.SYS driver is used to simulate the basic
- functions of the "curses" library.
- */
- // ----------------------------------------------------------- //
- #include <ctype.h>
- #include <string.h>
- #include "terminal.h"
-
- #ifdef __DOS__
- #include <iostream.h>
- #include <iomanip.h>
- #endif
-
- #ifdef __UNIX__
- #include <sys/time.h>
- #include <termio.h>
- #endif
-
- Terminal I_TERM; // Independent Teminal type object
- Terminal *terminal = &I_TERM; // Global terminal pointer
-
- void Terminal::GetString (char *string, int x, int y)
- // This function allows the user to enter a single string.
- // It was added to echo each character without having to
- // to turn the echo on. This will allow the uesr to edit
- // the entry using the backspace or other defined keys.
- {
- char ch;
- int charcount = 0;
-
- if (x != -1) move (y, x);
-
- while (1) {
- ch = getch();
- if (ch == '\n' || ch == '\r' || ch == CONTROL('c')) {
- *string = 0;
- return;
- }
-
- if (ch == '\b' || ch == CONTROL('d')) { // Delete keys
- if (charcount > 0) {
- string--;
- charcount--;
- Write('\b');
- Write(' ');
- Write('\b');
- }
- }
- else {
- *string++ = ch;
- charcount++;
- Write(ch);
- }
- refresh();
- }
- }
-
- void Terminal::GetPassword (char *string, int x, int y)
- // This function allows the user to enter a password
- // and echo an asterisk for each character typed.
- {
- char ch;
- int charcount = 0;
-
- if (x != -1) move (y, x);
-
- while (1) {
- ch = getch();
- if (ch == '\n' || ch == '\r' || ch == CONTROL('c')) {
- *string = 0;
- return;
- }
-
- if (ch == '\b' || ch == CONTROL('d')) { // Delete keys
- if (charcount > 0) {
- string--;
- charcount--;
- Write('\b');
- Write(' ');
- Write('\b');
- }
- }
- else {
- *string++ = ch;
- charcount++;
- Write('*');
- }
- refresh();
- }
- }
-
- int Terminal::GetInt(int x, int y)
- // Get a signed int value.
- {
- char buf[100];
- GetString(buf, x, y);
- return atoi(buf);
- }
-
- long Terminal::GetLong(int x, int y)
- // Get a signed long value.
- {
- char buf[100];
- GetString(buf, x, y);
- return atol(buf);
- }
-
- double Terminal::GetFloat(int x, int y)
- // Get a floating point value
- {
- char buf[100];
- GetString(buf, x, y);
- return atof(buf);
- }
-
- int Terminal::YesNo(int x, int y)
- {
- if(x == -1)
- Write(" <Do you wish to continue (y/n)> "); // Same line message
- else
- Write("Do you wish to continue (y/n)...", x, y);
-
- char c = ' ';
- while (c != 'y' && c != 'n') {
- c = GetChar();
- c = tolower(c);
- }
- return c == 'y' ? 1: 0; // return true if users answers yes
- }
-
- int Terminal::YesNo(const char *s, int x, int y)
- {
- if(x == -1)
- Write(s); // Same line message
- else
- Write(s, x, y);
-
- char c = ' ';
- while (c != 'y' && c != 'n') {
- c = GetChar();
- c = tolower(c);
- }
- return c == 'y' ? 1: 0; // return true if users answers yes
- }
-
- int Terminal::GetYesNo()
- // Wait for y/n reply with no prompt.
- {
- char c = ' ';
- while (c != 'y' && c != 'n') {
- c = GetChar();
- c = tolower(c);
- }
- return c == 'y' ? 1: 0; // return true if users answers yes
- }
-
- void Terminal::PutBack(char c)
- // Put back a keyboard character
- {
- putback = c;
- }
-
- int Terminal::Center(const char *s) const
- // Returns the center coordinate for a string.
- {
- int len = strlen(s);
- if(len > MaxCols()-1) len = MaxCols()-1;
- int mid = MaxCols()/2 - 1;
- int half = len/2;
- return mid - half;
- }
-
- int Terminal::Center(char *s)
- // Returns the center coordinate for a string.
- {
- int len = strlen(s);
- if(len > MaxCols()-1) len = MaxCols()-1;
- int mid = MaxCols()/2 - 1;
- int half = len/2;
- return mid - half;
- }
-
- int Terminal::ScreenCenter(const int offset) const
- // Returns the center coordinate for the screen.
- {
- int buf = offset;
- if(buf > MaxLines()-1) buf = MaxLines()-1;
- int mid = MaxLines()/2 - 1;
- int half = buf/2;
- return mid - half;
- }
-
- int Terminal::ScreenCenter(int offset)
- // Returns the center coordinate for the screen.
- {
- if(offset > MaxLines()-1) offset = MaxLines()-1;
- int mid = MaxLines()/2 - 1;
- int half = offset/2;
- return mid - half;
- }
-
- int Terminal::Right(const char *s) const
- // Returns the right justifed coordinate for a string.
- {
- int len = strlen(s);
- if(len > MaxCols()-1) len = MaxCols()-1;
- int end = MaxCols()-1;
- return end - len;
- }
-
- int Terminal::Right(char *s)
- // Returns the right justifed coordinate for a string.
- {
- int len = strlen(s);
- if(len > MaxCols()-1) len = MaxCols()-1;
- int end = MaxCols()-1;
- return end - len;
- }
-
- void Terminal::StatusLine(const char *s) const
- // Display a status line in normal text mode.
- {
- Write(s, 0, MaxLines()-1);
- int len = strlen(s);
- while (len++ < MaxCols()-1) Write(' ');
- }
-
- void Terminal::StatusLine(char *s)
- // Display a status line in normal text mode.
- {
- Write(s, 0, MaxLines()-1);
- int len = strlen(s);
- while (len++ < MaxCols()-1) Write(' ');
- }
-
- void Terminal::ClearLine(int x, int y) const
- {
- int i = 0;
- if(x == -1)
- while (i++ < MaxCols()-1) Write(' ');
- else {
- MoveCursor(x, y);
- while (i++ < MaxCols()-1) Write(' ');
- }
- }
-
- void Terminal::ClearLine(int x, int y)
- {
- int i = 0;
- if(x == -1)
- while (i++ < MaxCols()-1) Write(' ');
- else {
- MoveCursor(x, y);
- while (i++ < MaxCols()-1) Write(' ');
- }
- }
-
- void Terminal::MoveCursor(int x, int y) const
- {
- move(y, x);
- refresh();
- }
-
- void Terminal::MoveCursor(int x, int y)
- {
- move(y, x);
- refresh();
- }
-
- void Terminal::ClearScreen() const
- {
- clear();
- }
-
- void Terminal::ClearScreen()
- {
- clear();
- }
-
- void Terminal::AnyKey(int x, int y)
- // Prompt the user for any key to continue
- {
- if(x == -1) {
- Write(" <Press any key to continue> "); // Same line message
- GetChar();
- return;
- }
- Write("Press any key to continue...", x, y);
- GetChar();
- }
-
- void Terminal::AnyKey(const char *s, int x, int y)
- // Prompt the user for any key to continue
- {
- if(x == -1) {
- Write(s); // Same line message
- GetChar();
- return;
- }
- Write(s, x, y);
- GetChar();
- }
-
- void Terminal::Write(const unsigned char c, int x, int y) const
- // Write a unsigned character to the screen.
- {
- if (x != -1) move (y, x);
- char s[1];
- s[0] = c; // Copy char into a string buffer
- s[1] = '\0'; // Null terminate the string
- addstr(s);
- refresh();
- }
-
- void Terminal::Write(unsigned char c, int x, int y)
- // Write a unsigned character to the screen.
- {
- if (x != -1) move (y, x);
- char s[1];
- s[0] = c; // Copy char into a string buffer
- s[1] = '\0'; // Null terminate the string
- addstr(s);
- refresh();
- }
-
- void Terminal::Write(const char c, int x, int y) const
- // Write a signed character to the screen.
- {
- if (x != -1) move (y, x);
- char s[1];
- s[0] = c; // Copy char into a string buffer
- s[1] = '\0'; // Null terminate the string
- addstr(s);
- refresh();
- }
-
- void Terminal::Write(char c, int x, int y)
- // Write a signed character to the screen.
- {
- if (x != -1) move (y, x);
- char s[1];
- s[0] = c; // Copy char into a string buffer
- s[1] = '\0'; // Null terminate the string
- addstr(s);
- refresh();
- }
-
- void Terminal::Write(const char *s, int x, int y) const
- // Write a single string to the screen.
- {
- if (x != -1) move (y, x);
- addstr(s);
- refresh();
- }
-
- void Terminal::Write(char *s, int x, int y)
- // Write a single string to the screen.
- {
- if (x != -1) move (y, x);
- addstr(s);
- refresh();
- }
-
- void Terminal::Write(const long val, int x, int y) const
- // Write a signed long int to the screen.
- {
- char buf[100];
- sprintf(buf, "%d", val);
- Write(buf, x, y);
- }
-
- void Terminal::Write(long val, int x, int y)
- // Write a signed long int to the screen.
- {
- char buf[100];
- sprintf(buf, "%d", val);
- Write(buf, x, y);
- }
-
- void Terminal::Write(const int val, int x, int y) const
- // Write a signed int to the screen.
- {
- char buf[100];
- sprintf(buf, "%d", val);
- Write(buf, x, y);
- }
-
- void Terminal::Write(int val, int x, int y)
- // Write a signed int to the screen.
- {
- char buf[100];
- sprintf(buf, "%d", val);
- Write(buf, x, y);
- }
-
- void Terminal::Write(const double val, int x, int y) const
- // Write a floating point value to the screen.
- {
- char buf[100];
- sprintf(buf, "%.2f", val);
- Write(buf, x, y);
- }
-
- void Terminal::Write(double val, int x, int y)
- // Write a floating point value to the screen.
- {
- char buf[100];
- sprintf(buf, "%.2f", val);
- Write(buf, x, y);
- }
-
- void Terminal::Write(const float val, int x, int y) const
- // Write a floating point value to the screen.
- {
- char buf[100];
- sprintf(buf, "%.2f", val);
- Write(buf, x, y);
- }
-
- void Terminal::Write(float val, int x, int y)
- // Write a floating point value to the screen.
- {
- char buf[100];
- sprintf(buf, "%.2f", val);
- Write(buf, x, y);
- }
-
- void Terminal::StandOut(const char *s, int x, int y) const
- // Write text in stand out mode.
- {
- if (x != -1) move (y, x);
- standout();
- addstr(s);
- standend();
- refresh();
- }
-
- void Terminal::StandOut(char *s, int x, int y)
- // Write text in stand out mode.
- {
- if (x != -1) move (y, x);
- standout();
- addstr(s);
- standend();
- refresh();
- }
-
- unsigned char Terminal::GetChar()
- // Input a keyboard charater (unbuffered) with out waiting
- // for the RETURN key.
- {
- int c;
- if(putback) {
- c = putback;
- putback = 0;
- }
- else {
- c = getch();
- if (c == 0) // Convert function key
- c = getch() | 0x80;
- else // Strip scan code
- c &= 0xff;
- }
- return (unsigned char)(c);
- }
-
- int Terminal::KBWait() const
- // Test for a keyboard character waiting. Continue processing until
- // the user interrupts by hitting a key.
- {
- #ifdef __DOS__
- return kbhit();
- #endif
-
- #ifdef __UNIX__
- fd_set readfds, writefds, exceptfds;
- struct timeval timeout;
- static struct termio otty, ntty;
- int ret;
-
- // Create proper environment for select()
- FD_ZERO( &readfds );
- FD_ZERO( &writefds );
- FD_ZERO( &exceptfds );
- FD_SET( fileno(stdin), &readfds );
-
- // We shall specify 0.5 sec as the waiting time
- timeout.tv_sec = 0; // 0 seconds
- timeout.tv_usec = 500; // 500 microseconds
-
- int fd = 0;
-
- // Put tty in raw mode
- ioctl(fd, TCGETA, &otty);
- ntty = otty;
- ntty.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL);
- ntty.c_lflag &= ~ICANON;
- ntty.c_lflag |= ISIG;
- ntty.c_cflag &= ~(CSIZE|PARENB);
- ntty.c_cflag |= CS8;
- ntty.c_iflag &= (ICRNL|ISTRIP);
- ntty.c_cc[VMIN] = 1;
- ntty.c_cc[VTIME] = 1;
- ioctl(fd, TCSETAW, &ntty);
-
- // Do a select
- ret = select( 1, &readfds, &writefds, &exceptfds, &timeout );
-
- // Reset the tty back to its original mode
- ioctl(fd, TCSETAW, &otty);
-
- return( ret );
- #endif
- }
-
- void Terminal::init()
- {
- #ifdef __UNIX__
-
- // Removed: causes core dump if term varible is set incorrectly (ie: dec-vt320)
- // newterm(getenv("TERM"), stdout, stdin);
-
- initscr(); // initialize the curses library
- keypad(stdscr, TRUE); // enable keyboard mapping
- idlok(stdscr, TRUE); // enable terminal insert and delete line features
- nonl(); // tell curses not to do NL->CR/NL on output
- noecho(); // don't echo input
- raw(); // Allows the program to mask Ctrl-C
-
- // Curses input modes
- // cbreak(); // Send all characters to program except Ctrl-C,S,Q, and Z
- // nocbreak(); // Nothing is sent to the program until the users hits return
- // raw(); // All charaters are sent immediately to the program
- // noraw(); // Turn off raw mode
-
- maxcols = COLS;
- maxlines = LINES;
-
- #endif
-
- #ifdef __DOS__
- // Simulate an initscr() call
- cout << "\033[m"; // Normal text attributes
- cout.flush();
- clear();
- maxcols = COLS;
- maxlines = LINES;
- move(0, 0);
- refresh();
- #endif
- }
-
- void Terminal::finish()
- {
- clear();
- endwin();
- }
-
- void Terminal::SetMaxLines(int lines)
- {
- if(lines > LINES)
- maxlines = LINES;
- else
- maxlines = lines;
- }
-
- void Terminal::SetMaxCols(int cols)
- {
- if(cols > COLS)
- maxcols = COLS;
- else
- maxcols = cols;
- }
-
- #ifdef __DOS__
- // ===============================================================
- // Stand alone functions used to port this code from UNIX to DOS,
- // Windows 3.11, and Windows 95. These functions are used to
- // simulate the basic functionality of the vast CURSES library.
- // All of these functions rely on the ANSI.SYS driver installed
- // in the "config.sys" file: DEVICEHIGH=C:\WINDOWS\COMMAND\ANSI.SYS
- // in Windows 95 or DEVICEHIGH=C:\DOS\ANSI.SYS in DOS/Windows 3.11.
- // ===============================================================
- int LINES = 25; // PC terminal the maximum screen height
- int COLS = 80; // PC terminal the maximum screen width
-
- int addch(const chtype c)
- {
- cout << (unsigned char)c;
- cout.flush();
- return OK;
- }
-
- int addstr(const char *s)
- {
- if(s) cout << s;
- cout.flush();
- return OK;
- }
-
- int beep()
- {
- cout << '\a';
- return OK;
- }
-
- int clear()
- {
- cout << "\033[2J";
- cout.flush();
- return OK;
- }
-
- int endwin()
- {
- cout << "\033[m"; // Normal text attributes
- cout.flush();
- clear();
- move(0, 0);
- return OK;
- }
-
- int move(int y, int x)
- {
- cout << "\033[" << (y+1) << ';' << (x+1) << 'H';
- cout.flush();
- return OK;
- }
-
- int refresh()
- {
- return OK;
- }
-
- int standend()
- {
- cout << "\033[m"; // Normal text attributes
- cout.flush();
- return OK;
- }
-
- int standout()
- {
- cout << "\033[7m"; // Reverse video text attribute
- cout.flush();
- return OK;
- }
- // ===============================================================
- // The folling code is used for PC enhancements, used to emulate
- // the effect of the video attribute functions in the curses library.
- // All of the escape codes are compatible with vt100 terminals.
-
- void UnderlineText()
- {
- cout << "\033[4m";
- cout.flush();
- }
-
- void BoldText()
- {
- cout << "\033[1m";
- cout.flush();
- }
-
- void ReverseVideo()
- {
- cout << "\033[7m";
- cout.flush();
- }
-
- void NormalText()
- {
- cout << "\033[m"; // Normal text attributes
- cout.flush();
- }
- // ===============================================================
- #endif // __DOS__
-
- // ----------------------------------------------------------- //
- // ------------------------------- //
- // --------- End of File --------- //
- // ------------------------------- //
-