Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

htcurses.cc

Go to the documentation of this file.
00001 /* 
00002  *      HT Editor
00003  *      htcurses.cc (WIN32 implementation)
00004  *
00005  *      Copyright (C) 1999-2002 Sebastian Biallas (sb@web-productions.de)
00006  *
00007  *      This program is free software; you can redistribute it and/or modify
00008  *      it under the terms of the GNU General Public License version 2 as
00009  *      published by the Free Software Foundation.
00010  *
00011  *      This program is distributed in the hope that it will be useful,
00012  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *      GNU General Public License for more details.
00015  *
00016  *      You should have received a copy of the GNU General Public License
00017  *      along with this program; if not, write to the Free Software
00018  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  */
00020 
00021 #include "global.h"
00022 #include "htcurses.h"
00023 
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <string.h>
00027 
00028 #define WIN32_LEAN_AND_MEAN
00029 #include <windows.h>
00030 
00031 /* stupid rsxntdj hack */
00032 #ifdef __RSXNT__
00033 extern "C" {
00034         int __dj_stderr;
00035 }
00036 #endif
00037 
00038 HANDLE output;
00039 
00040 /*
00041  *      CLASS screendrawbuf
00042  */
00043 screendrawbuf::screendrawbuf(char *title)
00044 {
00045         bounds b;
00046         CONSOLE_SCREEN_BUFFER_INFO screen_info;
00047 
00048         buf = NULL;
00049         cursorx = 0;
00050         cursory = 0;
00051 
00052         init_console();
00053 
00054         GetConsoleScreenBufferInfo(output, &screen_info);
00055 
00056         SetConsoleTitleA(title);
00057 
00058         b.x = 0;
00059         b.y = 0;
00060 /*      b.w = screen_info.dwSize.X;
00061         b.h = screen_info.dwSize.Y;*/
00062         b.w = screen_info.srWindow.Right - screen_info.srWindow.Left + 1;
00063         b.h = screen_info.srWindow.Bottom - screen_info.srWindow.Top + 1;
00064         b_setbounds(&b);
00065 
00066         cursor_visible = true;
00067         cursor_redraw = true;
00068         hidecursor();
00069         show();
00070 }
00071 
00072 screendrawbuf::~screendrawbuf()
00073 {
00074         /* hack to keep prompt color white on black */
00075         b_printchar(size.w-1, size.h-1, VCP(VC_WHITE, VC_BLACK), ' ');
00076 
00077         setcursor(0, size.h-1);
00078         show();
00079         if (buf) free(buf);
00080 }
00081 
00082 bool screendrawbuf::init_console()
00083 {
00084         CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
00085         SMALL_RECT windowRect;
00086 
00087         output = GetStdHandle(STD_OUTPUT_HANDLE);
00088 
00089         if (output == INVALID_HANDLE_VALUE) return false;
00090         if (SetConsoleActiveScreenBuffer(output) == FALSE) return false;
00091         if (!GetConsoleScreenBufferInfo(output, &csbiInfo)) return false;
00092         windowRect.Left = 0;
00093         windowRect.Top = 0;
00094         windowRect.Right = csbiInfo.dwSize.X - 1;
00095         windowRect.Bottom = csbiInfo.dwSize.Y - 1;
00096         if (!SetConsoleWindowInfo(output, TRUE, &windowRect)) return false;
00097         if (SetConsoleMode(output, 0) == FALSE) return false;
00098         return true;
00099 }
00100 
00101 void screendrawbuf::drawbuffer(drawbuf *b, int x, int y, bounds *clipping)
00102 {
00103         drawbufch *ch=b->buf;
00104         for (int iy=0; iy<b->size.h; iy++) {
00105                 int dest = x+(iy+y)*size.w;
00106                 if (y+iy>=clipping->y+clipping->h) break;
00107                 if (y+iy>=clipping->y)
00108                 for (int ix=0; ix<b->size.w; ix++) {
00109                         if ((x+ix<clipping->x+clipping->w) && (x+ix>=clipping->x)) {
00110                                 put_vc(dest, ch->ch, ch->c);
00111                         }
00112                         dest++;
00113                         ch++;
00114                 }
00115         }
00116 }
00117 
00118 void screendrawbuf::b_fill(int x, int y, int w, int h, int c, int ch)
00119 {
00120         for (int i=0; i<h; i++) {
00121                 int dest = x+(i+y)*size.w;
00122                 if (y+i>=size.h) break;
00123                 if (y+i>=0)
00124                 for (int j=0; j<w; j++) {
00125                         if (x+j>=0) put_vc(dest, ch, c);
00126                         if (x+j>=size.w-1) break;
00127                         dest++;
00128                 }
00129         }
00130 }
00131 
00132 void screendrawbuf::b_printchar(int x, int y, int c, int ch)
00133 {
00134         int dest = x+y*size.w;
00135         put_vc(dest, ch, c);
00136 }
00137 
00138 int screendrawbuf::b_lprint(int x, int y, int c, int l, char *text)
00139 {
00140         int n=0;
00141         int dest = x+y*size.w;
00142         while ((*text) && (n<l)) {
00143                 put_vc(dest, (unsigned char)*text, c);
00144                 dest++;
00145                 text++;
00146                 n++;
00147         }
00148         return n;
00149 }
00150 
00151 int screendrawbuf::b_lprintw(int x, int y, int c, int l, int *text)
00152 {
00153         int n=0;
00154         int dest = x+y*size.w;
00155         while ((*text) && (n<l)) {
00156                 put_vc(dest, (unsigned char)*text, c);
00157                 dest++;
00158                 text++;
00159                 n++;
00160         }
00161         return n;
00162 }
00163 
00164 void screendrawbuf::b_resize(int rw, int rh)
00165 {
00166         /* screens are not sizeable (?) */
00167 }
00168 
00169 void screendrawbuf::b_rmove(int rx, int ry)
00170 {
00171         /* screens are not movable */
00172 }
00173 
00174 void screendrawbuf::b_setbounds(bounds *b)
00175 {
00176         genericdrawbuf::b_setbounds(b);
00177         if (buf) free(buf);
00178         buf = (CHAR_INFO *)malloc(size.w * size.h * sizeof(CHAR_INFO));
00179         b_fill(size.x, size.y, size.w, size.h, VCP(VC_WHITE, VC_BLACK), ' ');
00180 }
00181 
00182 void screendrawbuf::show()
00183 {
00184         COORD xy, xy2;
00185         if (cursor_redraw) {
00186                 xy.X=cursorx;
00187                 xy.Y=cursory;
00188                 SetConsoleCursorPosition(output, xy);
00189                 cursor_redraw = false;
00190         }
00191         xy.X = 0;
00192         xy.Y  = 0;
00193         xy2.X = size.w;
00194         xy2.Y = size.h;
00195         SMALL_RECT sr;
00196         sr.Left = 0;
00197         sr.Top = 0;
00198         sr.Right = size.w-1;
00199         sr.Bottom = size.h-1;
00200         WriteConsoleOutput(output, (CHAR_INFO *)buf, xy2, xy, &sr);
00201 }
00202 
00203 void screendrawbuf::getcursor(int *x, int *y)
00204 {
00205         *x=cursorx;
00206         *y=cursory;
00207 }
00208 
00209 void screendrawbuf::hidecursor()
00210 {
00211         if (cursor_visible) {
00212                 COORD xy;
00213                 xy.X=size.w-1;
00214                 xy.Y=size.h-1;
00215                 SetConsoleCursorPosition(output, xy);
00216                 CONSOLE_CURSOR_INFO ci;
00217                 ci.dwSize = 0xd;
00218                 ci.bVisible = false;
00219                 if (!SetConsoleCursorInfo(output, &ci)) {
00220                 }
00221                 cursor_visible = false;
00222         }
00223 }
00224 
00225 void screendrawbuf::setcursor(int x, int y)
00226 {
00227         showcursor();
00228         cursorx=x;
00229         cursory=y;
00230         cursor_redraw = true;
00231 }
00232 
00233 void screendrawbuf::setcursormode(bool override)
00234 {
00235 }
00236 
00237 void screendrawbuf::showcursor()
00238 {
00239         if (!cursor_visible) {
00240                 CONSOLE_CURSOR_INFO ci;
00241                 ci.dwSize = 0xd;
00242                 ci.bVisible = true;
00243                 SetConsoleCursorInfo(output, &ci);
00244                 cursor_visible = true;
00245         }
00246 }
00247 
00248 /* virtual color pairs (fg/bg) */
00249 
00250 void screendrawbuf::put_vc(int dest, char ch, int vc)
00251 {
00252         int fg, bg;
00253         if (VC_GET_BASECOLOR(VCP_BACKGROUND(vc))==VC_TRANSPARENT) {
00254                 bg=((byte)((CHAR_INFO *)buf)[dest].Attributes)>>4;
00255         } else if (VC_GET_LIGHT(VCP_BACKGROUND(vc))) {
00256                 bg=VC_GET_BASECOLOR(VCP_BACKGROUND(vc))+8;
00257         } else {
00258                 bg=VC_GET_BASECOLOR(VCP_BACKGROUND(vc));
00259         }
00260         if (VC_GET_BASECOLOR(VCP_FOREGROUND(vc))==VC_TRANSPARENT) {
00261                 fg=(byte)(((CHAR_INFO *)buf)[dest].Attributes&0xf);
00262         } else if (VC_GET_LIGHT(VCP_FOREGROUND(vc))) {
00263                 fg=VC_GET_BASECOLOR(VCP_FOREGROUND(vc))+8;
00264         } else {
00265                 fg=VC_GET_BASECOLOR(VCP_FOREGROUND(vc));
00266         }
00267         if (ch) ((CHAR_INFO *)buf)[dest].Char.AsciiChar = ch;
00268         ((CHAR_INFO *)buf)[dest].Attributes = (unsigned char)((bg<<4)|fg);
00269 }

Generated on Fri May 7 21:15:32 2004 by doxygen 1.3.5