diff options
author | in2 <in2@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2002-03-07 23:13:44 +0800 |
---|---|---|
committer | in2 <in2@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2002-03-07 23:13:44 +0800 |
commit | ae31e19f92e717919ac8e3db9039eb38d2b89aae (patch) | |
tree | c70164d6a1852344f44b04a653ae2815043512af /mbbsd/screen.c | |
download | pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.gz pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.bz2 pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.lz pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.xz pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.zst pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.zip |
Initial revision
git-svn-id: http://opensvn.csie.org/pttbbs/pttbbs/trunk/pttbbs@1 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'mbbsd/screen.c')
-rw-r--r-- | mbbsd/screen.c | 559 |
1 files changed, 559 insertions, 0 deletions
diff --git a/mbbsd/screen.c b/mbbsd/screen.c new file mode 100644 index 00000000..46ad5b38 --- /dev/null +++ b/mbbsd/screen.c @@ -0,0 +1,559 @@ +/* $Id: screen.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <stdarg.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "proto.h" + +extern int t_lines, t_columns; /* Screen size / width */ +extern int b_lines; /* Screen bottom line number: t_lines-1 */ +extern int p_lines; /* a Page of Screen line numbers: tlines-4 */ +extern int showansi; + +extern char *clearbuf; +extern char *cleolbuf; +extern char *scrollrev; +extern char *strtstandout; +extern char *endstandout; +extern int clearbuflen; +extern int cleolbuflen; +extern int scrollrevlen; +extern int strtstandoutlen; +extern int endstandoutlen; +extern int automargins; +#ifdef SUPPORT_GB +static int current_font_type=TYPE_BIG5; +static int gbinited=0; +#endif +#define SCR_WIDTH 80 +#define o_clear() output(clearbuf,clearbuflen) +#define o_cleol() output(cleolbuf,cleolbuflen) +#define o_scrollrev() output(scrollrev,scrollrevlen) +#define o_standup() output(strtstandout,strtstandoutlen) +#define o_standdown() output(endstandout,endstandoutlen) + +unsigned char scr_lns, scr_cols; +static unsigned char cur_ln = 0, cur_col = 0; +static unsigned char docls, downfrom = 0; +static unsigned char standing = NA; +static char roll = 0; +static int scrollcnt, tc_col, tc_line; + +screenline_t *big_picture = NULL; + +#define MODIFIED (1) /* if line has been modifed, screen output */ +#define STANDOUT (2) /* if this line has a standout region */ + +int tputs(const char *str, int affcnt, int (*putc)(int)); + +void initscr() { + if(!big_picture) { + scr_lns = t_lines; + scr_cols = t_columns = ANSILINELEN; + /* scr_cols = MIN(t_columns, ANSILINELEN); */ + big_picture = (screenline_t *) calloc(scr_lns, sizeof(screenline_t)); + docls = YEA; + } +} + +void move(int y, int x) { + cur_col = x; + cur_ln = y; +} + +void getyx(int *y, int *x) { + *y = cur_ln; + *x = cur_col; +} + +static void rel_move(int was_col, int was_ln, int new_col, int new_ln) { + if(new_ln >= t_lines || new_col >= t_columns) + return; + + tc_col = new_col; + tc_line = new_ln; + if(new_col == 0) { + if(new_ln == was_ln) { + if(was_col) + ochar('\r'); + return; + } else if(new_ln == was_ln + 1) { + ochar('\n'); + if(was_col) + ochar('\r'); + return; + } + } + + if(new_ln == was_ln) { + if(was_col == new_col) + return; + + if(new_col == was_col - 1) { + ochar(Ctrl('H')); + return; + } + } + do_move(new_col, new_ln); +} + +static void standoutput(char *buf, int ds, int de, int sso, int eso) { + int st_start, st_end; + + if(eso <= ds || sso >= de) { + output(buf + ds, de - ds); + } else { + st_start = MAX(sso, ds); + st_end = MIN(eso, de); + if(sso > ds) + output(buf + ds, sso - ds); + o_standup(); + output(buf + st_start, st_end - st_start); + o_standdown(); + if(de > eso) + output(buf + eso, de - eso); + } +} + +void redoscr() { + register screenline_t *bp; + register int i, j, len; + + o_clear(); + for(tc_col = tc_line = i = 0, j = roll; i < scr_lns; i++, j++) { + if(j >= scr_lns) + j = 0; + bp = &big_picture[j]; + if((len = bp->len)) { + rel_move(tc_col, tc_line, 0, i); + if(bp->mode & STANDOUT) + standoutput(bp->data, 0, len, bp->sso, bp->eso); + else + output(bp->data, len); + tc_col += len; + if(tc_col >= t_columns) { + if (automargins) + tc_col = t_columns - 1; + else { + tc_col -= t_columns; + tc_line++; + if(tc_line >= t_lines) + tc_line = b_lines; + } + } + bp->mode &= ~(MODIFIED); + bp->oldlen = len; + } + } + rel_move(tc_col, tc_line, cur_col, cur_ln); + docls = scrollcnt = 0; + oflush(); +} + +void refresh() { + register screenline_t *bp = big_picture; + register int i, j, len; + extern int automargins; + extern int scrollrevlen; + if(num_in_buf()) + return; + + if((docls) || (abs(scrollcnt) >= (scr_lns - 3))) { + redoscr(); + return; + } + + if(scrollcnt < 0) { + if(!scrollrevlen) { + redoscr(); + return; + } + rel_move(tc_col, tc_line, 0, 0); + do { + o_scrollrev(); + } while(++scrollcnt); + } else if (scrollcnt > 0) { + rel_move(tc_col, tc_line, 0, b_lines); + do { + ochar('\n'); + } while(--scrollcnt); + } + + for(i = 0, j = roll; i < scr_lns; i++, j++) { + if(j >= scr_lns) + j = 0; + bp = &big_picture[j]; + len = bp->len; + if(bp->mode & MODIFIED && bp->smod < len) { + bp->mode &= ~(MODIFIED); + if(bp->emod >= len) + bp->emod = len - 1; + rel_move(tc_col, tc_line, bp->smod, i); + + if(bp->mode & STANDOUT) + standoutput(bp->data, bp->smod, bp->emod + 1, + bp->sso, bp->eso); + else + output(&bp->data[bp->smod], bp->emod - bp->smod + 1); + tc_col = bp->emod + 1; + if(tc_col >= t_columns) { + if(automargins) { + tc_col -= t_columns; + if(++tc_line >= t_lines) + tc_line = b_lines; + } else + tc_col = t_columns - 1; + } + } + + if(bp->oldlen > len) { + rel_move(tc_col, tc_line, len, i); + o_cleol(); + } + bp->oldlen = len; + + } + + rel_move(tc_col, tc_line, cur_col, cur_ln); + + oflush(); +} + +void clear() { + register screenline_t *slp; + + register int i; + + docls = YEA; + cur_col = cur_ln = roll = downfrom = i = 0; + do { + slp = &big_picture[i]; + slp->mode = slp->len = slp->oldlen = 0; + } while(++i < scr_lns); +} + +void clrtoeol() { + register screenline_t *slp; + register int ln; + + standing = NA; + if((ln = cur_ln + roll) >= scr_lns) + ln -= scr_lns; + slp = &big_picture[ln]; + if(cur_col <= slp->sso) + slp->mode &= ~STANDOUT; + + if(cur_col > slp->oldlen) { + for(ln = slp->len; ln <= cur_col; ln++) + slp->data[ln] = ' '; + } + + if(cur_col < slp->oldlen) { + for(ln = slp->len; ln >= cur_col; ln--) + slp->data[ln] = ' '; + } + + slp->len = cur_col; +} + +void clrtoline(int line) { + register screenline_t *slp; + register int i, j; + + for(i = cur_ln, j = i + roll; i < line; i++, j++) { + if(j >= scr_lns) + j -= scr_lns; + slp = &big_picture[j]; + slp->mode = slp->len = 0; + if(slp->oldlen) + slp->oldlen = 255; + } +} + +void clrtobot() { + clrtoline(scr_lns); +} + +void outch(unsigned char c) { + register screenline_t *slp; + register int i; + + if((i = cur_ln + roll) >= scr_lns) + i -= scr_lns; + slp = &big_picture[i]; + + if(c == '\n' || c == '\r') { + if(standing) { + slp->eso = MAX(slp->eso, cur_col); + standing = NA; + } + if((i = cur_col - slp->len) > 0) + memset(&slp->data[slp->len], ' ', i + 1); + slp->len = cur_col; + cur_col = 0; + if(cur_ln < scr_lns) + cur_ln++; + return; + } +/* + else if(c != '\033' && !isprint2(c)) + { + c = '*'; //substitute a '*' for non-printable + } +*/ + if(cur_col >= slp->len) { + for(i = slp->len; i < cur_col; i++) + slp->data[i] = ' '; + slp->data[cur_col] = '\0'; + slp->len = cur_col + 1; + } + + if(slp->data[cur_col] != c) { + slp->data[cur_col] = c; + if((slp->mode & MODIFIED) != MODIFIED) + slp->smod = slp->emod = cur_col; + slp->mode |= MODIFIED; + if(cur_col > slp->emod) + slp->emod = cur_col; + if(cur_col < slp->smod) + slp->smod = cur_col; + } + + if (++cur_col >= scr_cols) + { + if (standing && (slp->mode & STANDOUT)) + { + standing = 0; + slp->eso = MAX(slp->eso, cur_col); + } + cur_col = 0; + if (cur_ln < scr_lns) + cur_ln++; + } + +} + +static void parsecolor(char *buf) { + char *val; + char data[24]; + + data[0] = '\0'; + val = (char *)strtok(buf, ";"); + + while(val) { + if(atoi(val) < 30) { + if(data[0]) + strcat(data, ";"); + strcat(data, val); + } + val = (char *) strtok(NULL, ";"); + } + strcpy(buf, data); +} + +#define NORMAL (00) +#define ESCAPE (01) +#define VTKEYS (02) + +void outc(unsigned char ch) { + if(showansi) + outch(ch); + else { + static char buf[24]; + static int p = 0; + static int mode = NORMAL; + int i; + + switch(mode) { + case NORMAL: + if(ch == '\033') + mode = ESCAPE; + else + outch(ch); + return; + case ESCAPE: + if(ch == '[') + mode = VTKEYS; + else { + mode = NORMAL; + outch(''); + outch(ch); + } + return; + case VTKEYS: + if(ch == 'm') { + buf[p++] = '\0'; + parsecolor(buf); + } else if((p < 24) && (not_alpha(ch))) { + buf[p++] = ch; + return; + } + if(buf[0]) { + outch(''); + outch('['); + + for(i = 0; (p = buf[i]); i++) + outch(p); + outch(ch); + } + p = 0; + mode = NORMAL; + } + } +} + +static void do_outs(char *str) { + while(*str) + { + outc(*str++); + } +} +#ifdef SUPPORT_GB +static void gb_init() +{ + if(current_font_type == TYPE_GB) + { + hc_readtab(BBSHOME"/etc/hc.tab"); + } + gbinited = 1; +} + +static void gb_outs(char *str) +{ + do_outs(hc_convert_str(str, HC_BIGtoGB, HC_DO_SINGLE)); +} +#endif +int edit_outs(char *text) { + register int column = 0; + register char ch; +#ifdef SUPPORT_GB + if(current_font_type == TYPE_GB) + text = hc_convert_str(text, HC_BIGtoGB, HC_DO_SINGLE); +#endif + while((ch = *text++) && (++column < SCR_WIDTH)) + outch(ch == 27 ? '*' : ch); + + return 0; +} + +void outs(char *str) { +#ifdef SUPPORT_GB + if(current_font_type == TYPE_BIG5) +#endif + do_outs(str); +#ifdef SUPPORT_GB + else + { + if(!gbinited) gb_init(); + gb_outs(str); + } +#endif +} + + +/* Jaky */ +void Jaky_outs(char *str, int line) { +#ifdef SUPPORT_GB + if(current_font_type == TYPE_GB) + str = hc_convert_str(str, HC_BIGtoGB, HC_DO_SINGLE); +#endif + while(*str && line) { + outc(*str); + if(*str=='\n') + line--; + str++; + } +} + +void outmsg(char *msg) { + move(b_lines, 0); + clrtoeol(); +#ifdef SUPPORT_GB + if(current_font_type == TYPE_GB) + msg = hc_convert_str(msg, HC_BIGtoGB, HC_DO_SINGLE); +#endif + while(*msg) + outc(*msg++); +} + +void prints(char *fmt, ...) { + va_list args; + char buff[1024]; + + va_start(args, fmt); + vsprintf(buff, fmt, args); + va_end(args); + outs(buff); +} + +void mprints(int y, int x, char *str) { + move(y, x); + clrtoeol(); + prints(str); +} + +void scroll() { + scrollcnt++; + if(++roll >= scr_lns) + roll = 0; + move(b_lines, 0); + clrtoeol(); +} + +void rscroll() { + scrollcnt--; + if(--roll < 0) + roll = b_lines; + move(0, 0); + clrtoeol(); +} + +void region_scroll_up(int top, int bottom) { + int i; + + if(top > bottom) { + i = top; + top = bottom; + bottom = i; + } + + if(top < 0 || bottom >= scr_lns) + return; + + for(i = top; i < bottom; i++) + big_picture[i] = big_picture[i + 1]; + memset(big_picture + i, 0, sizeof(*big_picture)); + memset(big_picture[i].data, ' ', scr_cols); + save_cursor(); + change_scroll_range(top, bottom); + do_move(0, bottom); + scroll_forward(); + change_scroll_range(0, scr_lns - 1); + restore_cursor(); + refresh(); +} + +void standout() { + if(!standing && strtstandoutlen) { + register screenline_t *slp; + + slp = &big_picture[((cur_ln + roll) % scr_lns)]; + standing = YEA; + slp->sso = slp->eso = cur_col; + slp->mode |= STANDOUT; + } +} + +void standend() { + if(standing && strtstandoutlen) { + register screenline_t *slp; + + slp = &big_picture[((cur_ln + roll) % scr_lns)]; + standing = NA; + slp->eso = MAX(slp->eso, cur_col); + } +} |