/* Terminality - a portable terminal handling library * Copyright (C) 1998-2002, Emil Mikulic. * This is LGPL - look at COPYING.LIB */ /* Project: Terminality * File: tn_c_w32.h * Author: Emil Mikulic * Description: Provide the Win32 implementation */ /* Special note to people using the MSVC IDE (Developer Studio): * Set your tab stops to 8 or I will hunt you down and beat you * in the head with my rubber piggy. * -- Emil */ /* Terminality - Win32 backend * Intended for Windows 95/98/ME/NT/2K/XP. Usually works with: * - Microsoft Visual C++ 5.0, 6.0 * - Cygnus CygWin32 B19 * - Borland C++ 5.1.1 (compiles but has some glitches) */ #define TN_C_IMPLEMENTED static char tn_w32_rcsid[] = "$Id: tn_c_w32.h,v 1.1 2002/07/26 08:18:14 darkmoon Exp $"; #include #ifdef __BORLANDC__ #define _inline __inline #endif /* Console function error reporting */ void conserr(char *f, int l) { char buf[2048]; sprintf(buf, "Console error in file %s, line %d", f, l); MessageBox(NULL, buf, "Console error", MB_OK); PostQuitMessage(1); } /* Current currattr */ unsigned char currattr; /* Console handles */ HANDLE consout, consin; CHAR_INFO *doublebuf; int CON_COLS, CON_ROWS, curs_x, curs_y; /* initcons() Must call this before you start using Terminality */ void initcons(void) { CONSOLE_SCREEN_BUFFER_INFO csbi; /* to get buffer info */ /* Get standard input/output handles */ consout = GetStdHandle(STD_OUTPUT_HANDLE); PERR(consout != INVALID_HANDLE_VALUE); consin = GetStdHandle(STD_INPUT_HANDLE); PERR(consin != INVALID_HANDLE_VALUE); /* get the number of character cells in the current buffer */ PERR( GetConsoleScreenBufferInfo(consout, &csbi) ); CON_COLS = csbi.dwSize.X; /* fix Win2K/XP scrolling consoles */ CON_ROWS = csbi.dwSize.Y = csbi.srWindow.Bottom + 1; PERR( SetConsoleScreenBufferSize(consout, csbi.dwSize) ); /* Init double buffer */ doublebuf = (CHAR_INFO*)xmalloc(sizeof(CHAR_INFO)*CON_ROWS*CON_COLS); currattr = 7; clrscr(); } /* Cleanup after using terminal */ void donecons(void) { /* Reset */ setcolor(7,0); set_cursor(line); /* Go to bottom of screen like ncurses */ gotoxy(1, CON_ROWS); update(); /* Kill copy buffer */ free(doublebuf); } /* Update screen */ void update(void) { COORD bufsize, coord = {0, 0}; SMALL_RECT bufrect; /* Copy double buffer to consout */ bufsize.X = CON_COLS; bufsize.Y = CON_ROWS; bufrect.Top = 0; bufrect.Left = 0; bufrect.Bottom = CON_ROWS-1; bufrect.Right = CON_COLS-1; PERR( WriteConsoleOutput( consout, doublebuf, bufsize, coord, &bufrect) ); /* update cursor pos */ coord.X = curs_x; coord.Y = curs_y; PERR( SetConsoleCursorPosition(consout, coord) ); } /* (helper function) */ _inline void directprint(const char *str) { int ofs, i; for (i=0; str[i]; i++) { /* scroll buffer if at bottom of screen */ if (curs_y == CON_ROWS) { memmove(doublebuf, doublebuf+sizeof(CHAR_INFO)*CON_COLS, sizeof(CHAR_INFO)*CON_COLS); curs_y--; clreol(); } ofs = curs_y * CON_COLS + curs_x; /* write to buffer */ switch (str[i]) { case '\n': curs_x = 0; curs_y++; break; case '\t': curs_x += 8; curs_x -= (curs_x & 7); break; case '\r': curs_x = 0; break; default: doublebuf[ofs].Attributes = currattr; doublebuf[ofs].Char.AsciiChar = str[i]; /* advance cursor */ ofs++; curs_x++; }; /* wrap at EOL */ if (curs_x >= CON_COLS) { curs_x -= CON_COLS; curs_y++; } } } /* Print to window */ int printw(const char *format, ...) { char s[2048]; va_list argl; int ret; va_start(argl,format); ret = _vsnprintf(s, 2048, format, argl); va_end(argl); PERR( ret != -1); /* buffer overflow */ /* write the formatted string to the console */ directprint(s); return ret; } /* set attribute to attr */ void setattr(unsigned char attr) { /* set attributes for new writes to the console */ PERR( SetConsoleTextAttribute(consout, attr) ); } /* set text color */ void textcolor(color fg) { currattr = (currattr & FG_MASK) | (fg & BG_MASK); } /* set text background */ void textbackground(color bg) { currattr = (currattr & BG_MASK) | ((bg << BG_BITS) & FG_MASK); } /* set color */ void setcolor(color f, color b) { currattr = (f & BG_MASK) | ((b << BG_BITS) & FG_MASK); } color getbgcolor(void) { return (currattr & FG_MASK) >> BG_BITS; } color getfgcolor(void) { return currattr & BG_MASK; } /* write char */ void writech(chtype c) { char ch[2]; ch[0] = c; ch[1] = 0; directprint(ch); } /* Clear screen and home cursor */ void clrscr(void) { int i; for (i=0; i