summaryrefslogtreecommitdiffstats
path: root/mbbsd/screen.c
diff options
context:
space:
mode:
authorin2 <in2@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2002-03-07 23:13:44 +0800
committerin2 <in2@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2002-03-07 23:13:44 +0800
commitae31e19f92e717919ac8e3db9039eb38d2b89aae (patch)
treec70164d6a1852344f44b04a653ae2815043512af /mbbsd/screen.c
downloadpttbbs-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.c559
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);
+ }
+}