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 (POSIX implementation)
00004  *
00005  *      Copyright (C) 1999-2002 Stefan Weyergraf (stefan@weyergraf.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 "config.h"
00022 #include <unistd.h>
00023 
00024 #include "global.h"
00025 #include "htcurses.h"
00026 #include "htdebug.h"
00027 
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <string.h>
00031 
00032 /* virtual color pairs (fg/bg) */
00033 
00034 void put_vc(drawbufch *dest, int ch, int vc)
00035 {
00036         int fg, bg;
00037         if (VC_GET_BASECOLOR(VCP_BACKGROUND(vc))==VC_TRANSPARENT) {
00038                 bg=dest->c >> 4;
00039         } else if (VC_GET_LIGHT(VCP_BACKGROUND(vc))) {
00040                 bg=VC_GET_BASECOLOR(VCP_BACKGROUND(vc))+8;
00041         } else {
00042                 bg=VC_GET_BASECOLOR(VCP_BACKGROUND(vc));
00043         }
00044         if (VC_GET_BASECOLOR(VCP_FOREGROUND(vc))==VC_TRANSPARENT) {
00045                 fg=dest->c & 0xf;
00046         } else if (VC_GET_LIGHT(VCP_FOREGROUND(vc))) {
00047                 fg=VC_GET_BASECOLOR(VCP_FOREGROUND(vc))+8;
00048         } else {
00049                 fg=VC_GET_BASECOLOR(VCP_FOREGROUND(vc));
00050         }
00051 
00052         dest->ch=ch;
00053         dest->c=(bg<<4) | fg;
00054 }
00055 
00056 /*
00057  *      CLASS screendrawbuf
00058  */
00059  
00060 drawbufch *buf;
00061 WINDOW *win;
00062 int use_colors, use_high_colors;
00063 int is_xterm;
00064 int cursorx, cursory; 
00065 int cursor_visible = 0;
00066 int cursor_overwrite = 0;
00067 
00068 short colormap[64];
00069 
00070 //#define TEST
00071 
00072 screendrawbuf::screendrawbuf(char *title)
00073 {
00074 #ifndef TEST
00075         bounds b;
00076         buf=0;
00077         int colors[8]={ COLOR_BLACK, COLOR_BLUE, COLOR_GREEN, COLOR_CYAN, COLOR_RED, COLOR_MAGENTA, COLOR_YELLOW, COLOR_WHITE };
00078 
00079         cursorx=0;
00080         cursory=0;
00081         win=initscr();
00082         use_colors=0;
00083         use_high_colors=0;
00084         if (has_colors()) {
00085             use_colors=1;
00086             char *term=getenv("TERM");
00087             int bold_support=0;
00088             attr_t attrs;
00089             short cur_color=1;
00090             start_color();
00091 /* FIXME: Does this work ???: test if the WA_BOLD attr can be set */
00092             attr_on(WA_BOLD, 0);
00093             attrs=WA_NORMAL;
00094             attr_get(&attrs, &cur_color, 0);
00095             bold_support=(attrs==WA_BOLD);
00096             attr_off(WA_BOLD, 0);
00097             
00098             is_xterm=(strcmp(term, "linux") && strcmp(term, "console"));
00099             if ( (!is_xterm) && (!bold_support)) {
00100                 HT_WARN("terminal is of type '%s' (non-x-terminal) but bold_test fails !", term);
00101             }
00102             if (bold_support) {
00103                     use_high_colors=1;
00104             } else {
00105                     HT_WARN("terminal only supports 8 foreground colors !");
00106             }
00107             for (int fg=0; fg<8; fg++) {
00108                     for (int bg=0; bg<8; bg++) {
00109                         colormap[fg+bg*8]=fg+bg*8;
00110                         init_pair(fg+bg*8, colors[fg], colors[bg]);
00111                     }
00112             }
00113             colormap[7]=0;
00114             colormap[0]=7;
00115             init_pair(7, COLOR_BLACK, COLOR_BLACK);
00116         } else {
00117             HT_WARN("terminal lacks color support !");
00118         }
00119         wtimeout(win, 1);
00120         meta(win, 1);
00121         keypad(win, 1);
00122         nodelay(win, 1);
00123         noecho();
00124         cbreak();
00125         ESCDELAY=500;
00126         
00127         b.x=0;
00128         b.y=0;
00129         b.w=getmaxx(win);
00130         b.h=getmaxy(win);
00131         b_setbounds(&b);
00132 
00133         show();
00134 #endif  
00135 }
00136 
00137 screendrawbuf::~screendrawbuf()
00138 {
00139         endwin();
00140         delwin(win);
00141         if (buf) free(buf);
00142 }
00143 
00144 void screendrawbuf::b_fill(int x, int y, int w, int h, int c, int chr)
00145 {
00146         for (int i=0; i<h; i++) {
00147                 drawbufch *ch=buf+x+(y+i)*size.w;
00148                 for (int j=0; j<w; j++) {
00149                         put_vc(ch, chr, c);
00150                         ch++;
00151                 }
00152         }
00153 }
00154 
00155 void screendrawbuf::b_printchar(int x, int y, int c, int ch)
00156 {
00157         drawbufch *b=buf+x+y*size.w;
00158         put_vc(b, ch, c);
00159 }
00160 
00161 int screendrawbuf::b_lprint(int x, int y, int c, int l, char *text)
00162 {
00163         int n=0;
00164         drawbufch *ch=buf+x+y*size.w;
00165         while ((*text) && (n<l)) {
00166                 put_vc(ch, *text, c);
00167                 ch++;   
00168                 text++; 
00169                 n++;
00170         }
00171         return n;
00172 }
00173 
00174 int screendrawbuf::b_lprintw(int x, int y, int c, int l, int *text)
00175 {
00176         int n=0;
00177         drawbufch *ch=buf+x+y*size.w;
00178         while ((*text) && (n<l)) {
00179                 put_vc(ch, *text, c);
00180                 ch++;   
00181                 text++; 
00182                 n++;
00183         }
00184         return n;
00185 }
00186 
00187 void screendrawbuf::b_resize(int rx, int ry)
00188 {
00189     /* screens are not resizeable yet */
00190 }
00191 
00192 void screendrawbuf::b_rmove(int rx, int ry)
00193 {
00194     /* screens are not movable */
00195 }
00196 
00197 void screendrawbuf::b_setbounds(bounds *b)
00198 {
00199         genericdrawbuf::b_setbounds(b);
00200         if (buf) delete buf;
00201         buf=(drawbufch *)malloc(sizeof *buf * size.w * size.h);
00202         b_fill(size.x, size.y, size.w, size.h, VCP(VC_BLACK, VC_BLACK), ' ');
00203 }
00204 
00205 void screendrawbuf::drawbuffer(drawbuf *b, int x, int y, bounds *clipping)
00206 {
00207         drawbufch *ch=b->buf;
00208         for (int iy=0; iy<b->size.h; iy++) {
00209                 drawbufch *k=buf+x+(iy+y)*size.w;
00210                 if (y+iy>=clipping->y+clipping->h) break;
00211                 if (y+iy>=clipping->y)
00212                 for (int ix=0; ix<b->size.w; ix++) {
00213                         if ((x+ix<clipping->x+clipping->w) && (x+ix>=clipping->x))
00214                                 put_vc(k, ch->ch, ch->c);
00215                         k++;
00216                         ch++;
00217                 }
00218         }
00219 }
00220 /*void screendrawbuf::drawbuffer(drawbuf *b, int x, int y)
00221 {
00222         for (int iy=0; iy<b->size.h; iy++) {
00223                 drawbufch *src=b->buf+iy*b->size.w;
00224                 drawbufch *dest=buf+x+(y+iy)*size.w;
00225                 memmove(dest, src, b->size.w * sizeof *dest);
00226         }
00227 }*/
00228 
00229 void screendrawbuf::show()
00230 {
00231 #ifndef TEST
00232         drawbufch *ch=buf;
00233         int c=-1;
00234         for (int iy=0; iy<size.h; iy++) {
00235                         move(iy+size.y, size.x);
00236                         for (int ix=0; ix<size.w; ix++) {
00237                                 if ((use_colors) && (ch->c!=c)) {
00238                                         c=ch->c;
00239                                         if (use_high_colors) {
00240                                                 if (is_xterm && (c==8)) {
00241                                         /* some terminals can't display dark grey, so we take light grey instead... */
00242                                                     attrset(A_NORMAL);
00243                                                     c=7;
00244                                                 } else {
00245                                                     if (c&8) attrset(A_BOLD); else attrset(A_NORMAL);
00246                                                 }
00247                                         }
00248                                         color_set( colormap[(c&7) | ((c&(7<<4))>>1)], 0);
00249                                 }
00250                                 if ((((unsigned char)ch->ch>=0x20) && ((unsigned char)ch->ch<=0x7e)) || ((unsigned int)ch->ch>0xff)) addch(ch->ch); else addch(32);
00251                                 ch++;
00252                         }
00253         }
00254         curs_set(0);
00255         refresh();
00256         move(cursory, cursorx);
00257         if (cursor_visible) {
00258                 if (cursor_overwrite) curs_set(2); else curs_set(1);
00259         }
00260 #endif  
00261 }
00262 
00263 void screendrawbuf::getcursor(int *x, int *y)
00264 {
00265         *x=cursorx;
00266         *y=cursory;
00267 }
00268 
00269 void screendrawbuf::hidecursor()
00270 {
00271         cursor_visible=0;
00272 }
00273 
00274 void screendrawbuf::setcursormode(bool o)
00275 {
00276         cursor_overwrite = o;
00277 }
00278 
00279 void screendrawbuf::setcursor(int x, int y)
00280 {
00281         cursorx=x;
00282         cursory=y;
00283         cursor_visible=1;
00284 }
00285 
00286 void screendrawbuf::showcursor()
00287 {
00288         cursor_visible=1;
00289 }

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