00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
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
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
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
00190 }
00191
00192 void screendrawbuf::b_rmove(int rx, int ry)
00193 {
00194
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
00221
00222
00223
00224
00225
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
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 }