From 7c7adbd6aefd1498cd84ee947c52269ce099d347 Mon Sep 17 00:00:00 2001 From: scw Date: Wed, 17 Aug 2005 05:28:53 +0000 Subject: screen_backup() & screen_restore() update: * automatic allocate memory, save cursor location and backup * automatic restore screen, cursor location and free memory * works on screen lessening * no more crash on screen enlarged git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@3051 63ad8ddf-47c3-0310-b6dd-a9e9d9715204 --- include/proto.h | 5 ++-- include/pttstruct.h | 1 + mbbsd/chat.c | 7 ++---- mbbsd/go.c | 9 ++----- mbbsd/io.c | 33 +++++++------------------ mbbsd/mbbsd.c | 7 ++---- mbbsd/screen.c | 69 +++++++++++++++++++++++++++++------------------------ mbbsd/talk.c | 10 ++------ 8 files changed, 58 insertions(+), 83 deletions(-) diff --git a/include/proto.h b/include/proto.h index f3579619..87efad8c 100644 --- a/include/proto.h +++ b/include/proto.h @@ -554,9 +554,8 @@ void scroll(void); void getyx(int *y, int *x); void initscr(void); void out_lines(const char *str, int line); -void screen_backup(int len, const screenline_t *bp, screen_backup_t *buf); -size_t screen_backupsize(int len, const screenline_t *bp); -void screen_restore(int len, screenline_t *bp, const screen_backup_t *buf); +void screen_backup(screen_backup_t *buf); +void screen_restore(const screen_backup_t *buf); /* stuff */ #define isprint2(ch) ((ch & 0x80) || isprint(ch)) diff --git a/include/pttstruct.h b/include/pttstruct.h index 9866b679..6794d38b 100644 --- a/include/pttstruct.h +++ b/include/pttstruct.h @@ -427,6 +427,7 @@ typedef struct water_t { typedef struct { int row, col; + int y, x; void *raw_memory; } screen_backup_t; diff --git a/mbbsd/chat.c b/mbbsd/chat.c index 0caa88f5..bd0a381e 100644 --- a/mbbsd/chat.c +++ b/mbbsd/chat.c @@ -529,13 +529,10 @@ t_chat(void) } else if (ch == Ctrl('I')) { screen_backup_t old_screen; - old_screen.raw_memory = malloc(screen_backupsize(t_lines, big_picture)); - screen_backup(t_lines, big_picture, &old_screen); + screen_backup(&old_screen); add_io(0, 0); t_idle(); - screen_restore(t_lines, big_picture, &old_screen); - free(old_screen.raw_memory); - redoscr(); + screen_restore(&old_screen); add_io(cfd, 0); } else if (ch == Ctrl('Q')) { print_chatid(chatid); diff --git a/mbbsd/go.c b/mbbsd/go.c index 2e29c80b..4f43ec09 100644 --- a/mbbsd/go.c +++ b/mbbsd/go.c @@ -865,12 +865,9 @@ gochess(int fd) if (ch == 'v') { screen_backup_t old_screen; - int y, x; - old_screen.raw_memory = malloc(screen_backupsize(t_lines, big_picture)); - screen_backup(t_lines, big_picture, &old_screen); + screen_backup(&old_screen); add_io(0, 0); - getyx(&y, &x); if (ch == 'v') { //extern char watermode; @@ -886,9 +883,7 @@ gochess(int fd) my_write(currutmp->msgs[0].last_pid, "水球丟回去:"); } */ - move(y, x); - screen_restore(t_lines, big_picture, &old_screen); - free(old_screen.raw_memory); + screen_restore(&old_screen); add_io(fd, 0); scr_need_redraw = 1; continue; diff --git a/mbbsd/io.c b/mbbsd/io.c index bea4d207..89f03a0b 100644 --- a/mbbsd/io.c +++ b/mbbsd/io.c @@ -427,22 +427,17 @@ igetch(void) screen_backup_t old_screen; int oldroll = roll; - int y, x, my_newfd; + int my_newfd; - getyx(&y, &x); - old_screen.raw_memory = malloc(screen_backupsize(t_lines, big_picture)); - screen_backup(t_lines, big_picture, &old_screen); + screen_backup(&old_screen); my_newfd = i_newfd; i_newfd = 0; t_users(); i_newfd = my_newfd; - screen_restore(t_lines, big_picture, &old_screen); - free(old_screen.raw_memory); roll = oldroll; - move(y, x); - redoscr(); + screen_restore(&old_screen); continue; } return ch; @@ -462,21 +457,16 @@ igetch(void) if (currutmp->msgs[0].pid && WATERMODE(WATER_OFO) && wmofo == NOTREPLYING) { - int y, x, my_newfd; + int my_newfd; screen_backup_t old_screen; - old_screen.raw_memory = malloc(screen_backupsize(t_lines, big_picture)); - screen_backup(t_lines, big_picture, &old_screen); - getyx(&y, &x); + screen_backup(&old_screen); my_newfd = i_newfd; i_newfd = 0; my_write2(); - screen_restore(t_lines, big_picture, &old_screen); - free(old_screen.raw_memory); + screen_restore(&old_screen); i_newfd = my_newfd; - move(y, x); - redoscr(); continue; } else if (!WATERMODE(WATER_OFO)) { if (watermode > 0) { @@ -494,10 +484,8 @@ igetch(void) } else if (watermode == -1 && currutmp->msgs[0].pid) { /* 第一次按 Ctrl-R (必須先被丟過水球) */ screen_backup_t old_screen; - int y, x, my_newfd; - getyx(&y, &x); - old_screen.raw_memory = malloc(screen_backupsize(t_lines, big_picture)); - screen_backup(t_lines, big_picture, &old_screen); + int my_newfd; + screen_backup(&old_screen); /* 如果正在talk的話先不處理對方送過來的封包 (不去select) */ my_newfd = i_newfd; @@ -527,10 +515,7 @@ igetch(void) i_newfd = my_newfd; /* 還原螢幕 */ - screen_restore(t_lines, big_picture, &old_screen); - free(old_screen.raw_memory); - move(y, x); - redoscr(); + screen_restore(&old_screen); continue; } } diff --git a/mbbsd/mbbsd.c b/mbbsd/mbbsd.c index adc2dedf..6d928719 100644 --- a/mbbsd/mbbsd.c +++ b/mbbsd/mbbsd.c @@ -272,14 +272,11 @@ talk_request(int sig) currutmp->mode = 0; currutmp->chatid[0] = 1; - old_screen.raw_memory = malloc(screen_backupsize(t_lines, big_picture)); - screen_backup(t_lines, big_picture, &old_screen); + screen_backup(&old_screen); talkreply(); currutmp->mode = mode0; currutmp->chatid[0] = c0; - screen_restore(t_lines, big_picture, &old_screen); - free(old_screen.raw_memory); - redoscr(); + screen_restore(&old_screen); } } diff --git a/mbbsd/screen.c b/mbbsd/screen.c index b7bde5ff..c0a389f2 100644 --- a/mbbsd/screen.c +++ b/mbbsd/screen.c @@ -521,53 +521,60 @@ standend(void) } } -void screen_backup(int len, const screenline_t *bp, screen_backup_t *old) +static size_t screen_backupsize(int len, const screenline_t *bp) { int i; - size_t offset=0; - void *buf = old->raw_memory; + size_t sum = 0; + for(i = 0; i < len; i++) + sum += ((char*)&bp[i].data - (char*)&bp[i]) + bp[i].len; + return sum; +} + +void screen_backup(screen_backup_t *old) +{ + int i; + size_t offset = 0; + void *buf; + screenline_t* bp = big_picture; + + buf = old->raw_memory = malloc(screen_backupsize(t_lines, big_picture)); old->col = t_columns; old->row = t_lines; + getyx(&old->y, &old->x); - for(i=0;iraw_memory; + screenline_t* bp = big_picture; + const int len = MIN(old->row, t_lines); - // TODO try to be more user friendly. - if (old->col > t_columns || old->row > t_lines) { - move(1, 0); - clrtobot(); - move(2, 2); - outs("偵測到視窗改變大小,畫面繪製將會暫時失效"); - return; - } + for(i = 0; i < len; i++) { + /* restore header */ + memcpy(&bp[i], (char*)buf + offset, ((char*)&bp[i].data - (char*)&bp[i])); + offset += ((char*)&bp[i].data - (char*)&bp[i]); - for(i=0;iraw_memory); + move(old->y, old->x); + redoscr(); } /* vim:sw=4 diff --git a/mbbsd/talk.c b/mbbsd/talk.c index fb8cffc7..dff22558 100644 --- a/mbbsd/talk.c +++ b/mbbsd/talk.c @@ -3269,22 +3269,16 @@ void CallAngel(){ static int entered = 0; screen_backup_t old_screen; - int x, y; if (!HasUserPerm(PERM_LOGINOK) || entered) return; entered = 1; - getyx(&y, &x); - old_screen.raw_memory = malloc(screen_backupsize(t_lines, big_picture)); - screen_backup(t_lines, big_picture, &old_screen); + screen_backup(&old_screen); TalkToAngel(); - screen_restore(t_lines, big_picture, &old_screen); - free(old_screen.raw_memory); - move(y, x); - redoscr(); + screen_restore(&old_screen); entered = 0; } -- cgit v1.2.3