diff --git a/src/conio/cterm.c b/src/conio/cterm.c index a9f93934b0b66c2acc5551c8de10c6afdecd5399..590b3f03b2dfad2cb0af4e0028660d8e123f794c 100644 --- a/src/conio/cterm.c +++ b/src/conio/cterm.c @@ -1391,6 +1391,33 @@ scrolldown(struct cterminal *cterm) GOTOXY(x, y); } +static void +cterm_line_to_scrollback(struct cterminal *cterm, int row) +{ + if(cterm->scrollback!=NULL) { + int getw; + + cterm->backfilled++; + if (cterm->backfilled > cterm->backlines) { + cterm->backfilled--; + cterm->backstart++; + if (cterm->backstart == cterm->backlines) + cterm->backstart = 0; + } + getw = cterm->backwidth; + if (getw > cterm->width) + getw = cterm->width; + if (getw < cterm->backwidth) { + memset(cterm->scrollback + cterm->backpos * cterm->backwidth, 0, sizeof(*cterm->scrollback) * cterm->backwidth); + } + vmem_gettext(cterm->x, row, cterm->x + getw - 1, row, cterm->scrollback + cterm->backpos * cterm->backwidth); + + cterm->backpos++; + if (cterm->backpos == cterm->backlines) + cterm->backpos = 0; + } +} + void cterm_scrollup(struct cterminal *cterm) { @@ -1399,24 +1426,10 @@ cterm_scrollup(struct cterminal *cterm) int maxx = TERM_MAXX; int maxy = TERM_MAXY; int x,y; - int getw; - cterm->backpos++; coord_conv_xy(cterm, CTERM_COORD_TERM, CTERM_COORD_SCREEN, &minx, &miny); coord_conv_xy(cterm, CTERM_COORD_TERM, CTERM_COORD_SCREEN, &maxx, &maxy); - if(cterm->scrollback!=NULL) { - if(cterm->backpos>cterm->backlines) { - memmove(cterm->scrollback, cterm->scrollback + cterm->backwidth, cterm->backwidth * sizeof(*cterm->scrollback) * (cterm->backlines - 1)); - cterm->backpos--; - } - getw = cterm->backwidth; - if (getw > cterm->width) - getw = cterm->width; - if (getw < cterm->backwidth) { - memset(cterm->scrollback + (cterm->backpos - 1) * cterm->backwidth, 0, sizeof(*cterm->scrollback) * cterm->backwidth); - } - vmem_gettext(cterm->x, miny, cterm->x + getw - 1, miny, cterm->scrollback + (cterm->backpos - 1) * cterm->backwidth); - } + cterm_line_to_scrollback(cterm, miny); MOVETEXT(minx, miny + 1, maxx, maxy, minx, miny); CURR_XY(&x, &y); cterm_clrblk(cterm, minx, maxy, minx + TERM_MAXX - 1, maxy); @@ -1500,26 +1513,15 @@ clear2bol(struct cterminal * cterm) void cterm_clearscreen(struct cterminal *cterm, char attr) { - int getw; - if(!cterm->started) cterm_start(cterm); - if(cterm->scrollback!=NULL) { - cterm->backpos+=cterm->height; - if(cterm->backpos>cterm->backlines) { - memmove(cterm->scrollback, cterm->scrollback + cterm->backwidth * (cterm->backpos - cterm->backlines), cterm->backwidth * sizeof(*cterm->scrollback) * (cterm->backlines - (cterm->backpos - cterm->backlines))); - cterm->backpos=cterm->backlines; - } - getw = cterm->backwidth; - if (getw > cterm->width) - getw = cterm->width; - if (getw < cterm->backwidth) { - memset(cterm->scrollback + (cterm->backpos - cterm->height) * cterm->backwidth, 0, sizeof(*cterm->scrollback) * cterm->backwidth * cterm->height); - } - vmem_gettext(cterm->x, cterm->y, cterm->x + getw - 1, cterm->y + cterm->height - 1, - cterm->scrollback + (cterm->backpos - cterm->height) * cterm->backwidth); - } + int minx = TERM_MINX; + int miny = TERM_MINY; + coord_conv_xy(cterm, CTERM_COORD_TERM, CTERM_COORD_SCREEN, &minx, &miny); + + for (int i = 0; i < cterm->height; i++) + cterm_line_to_scrollback(cterm, miny + i); CLRSCR(); GOTOXY(CURR_MINX, CURR_MINY); } diff --git a/src/conio/cterm.h b/src/conio/cterm.h index fc808d51cb3aa979dd6385a261e0da35dabba8fc..de8bedcbdbbdade2ea2bbcc9805640b5446ac5c6 100644 --- a/src/conio/cterm.h +++ b/src/conio/cterm.h @@ -99,6 +99,7 @@ struct cterminal { int right_margin; int quiet; // No sounds are made struct vmem_cell *scrollback; + int backfilled; // Number of lines copied into scrollback int backlines; // Number of lines in scrollback int backwidth; // Number of columns in scrollback char DA[1024]; // Device Attributes @@ -170,7 +171,8 @@ struct cterminal { link_list_t notes; sem_t playnote_thread_terminated; sem_t note_completed_sem; - int backpos; + int backpos; // Position where new lines will be added + int backstart; // First line of scrollback int xpos; int ypos; cterm_log_t log; diff --git a/src/syncterm/bbslist.c b/src/syncterm/bbslist.c index d36c0d98e92e1116bd2cf3db71e02e0a2702d873..a5ed0a160fe21c0aa765d393e2343d49f736cc66 100644 --- a/src/syncterm/bbslist.c +++ b/src/syncterm/bbslist.c @@ -368,6 +368,7 @@ viewofflinescroll(void) struct text_info txtinfo; struct text_info sbtxtinfo; struct mouse_event mevent; + int scrollback_pos; if (scrollback_buf == NULL) return; @@ -403,10 +404,11 @@ viewofflinescroll(void) setfont(0, false, 4); drawwin(); set_modepalette(palettes[COLOUR_PALETTE]); - top = scrollback_pos; gotoxy(1, 1); textattr(uifc.hclr | (uifc.bclr << 4) | BLINK); gettextinfo(&sbtxtinfo); + scrollback_pos = scrollback_lines - sbtxtinfo.screenheight; + top = scrollback_pos; ciomouse_addevent(CIOLIB_BUTTON_1_DRAG_START); ciomouse_addevent(CIOLIB_BUTTON_1_DRAG_MOVE); ciomouse_addevent(CIOLIB_BUTTON_1_DRAG_END); @@ -415,10 +417,10 @@ viewofflinescroll(void) showmouse(); for (i = 0; !i && !quitting;) { - if (top < 1) - top = 1; - if (top > (int)scrollback_lines) - top = scrollback_lines; + if (top < 0) + top = 0; + if (top > scrollback_pos) + top = scrollback_pos; vmem_puttext(((sbtxtinfo.screenwidth - scrollback_cols) / 2) + 1, 1, (sbtxtinfo.screenwidth - scrollback_cols) / 2 + scrollback_cols, sbtxtinfo.screenheight, diff --git a/src/syncterm/menu.c b/src/syncterm/menu.c index 7a0af78b6181dee128b28f2747e8e8ba1e2e6720..e17c5d2f4cd7047c5b21af508bac67e7ecf948d1 100644 --- a/src/syncterm/menu.c +++ b/src/syncterm/menu.c @@ -35,19 +35,25 @@ viewscroll(void) /* too large for alloca() */ scrollback = malloc((scrollback_buf - == NULL ? 0 : (term.width * sizeof(*scrollback) * settings.backlines)) + == NULL ? 0 : (term.width * sizeof(*scrollback) * cterm->backlines)) + (txtinfo.screenheight * txtinfo.screenwidth * sizeof(*scrollback))); if (scrollback == NULL) return; - memcpy(scrollback, cterm->scrollback, term.width * sizeof(*scrollback) * settings.backlines); - vmem_gettext(1, 1, txtinfo.screenwidth, txtinfo.screenheight, scrollback + (cterm->backpos) * cterm->width); + int lines = 0; + if (cterm->backstart > 0) { + lines = cterm->backlines - cterm->backstart; + memcpy(scrollback, cterm->scrollback + term.width * cterm->backstart, term.width * lines * sizeof(*scrollback)); + } + memcpy(scrollback + term.width * lines, cterm->scrollback, term.width * sizeof(*scrollback) * cterm->backpos); + int sblines = cterm->backpos + lines; + vmem_gettext(1, 1, txtinfo.screenwidth, txtinfo.screenheight, scrollback + sblines * cterm->width); savscrn = savescreen(); setfont(0, false, 1); setfont(0, false, 2); setfont(0, false, 3); setfont(0, false, 4); drawwin(); - top = cterm->backpos; + top = sblines; set_modepalette(palettes[COLOUR_PALETTE]); gotoxy(1, 1); textattr(uifc.hclr | (uifc.bclr << 4) | BLINK); @@ -57,10 +63,10 @@ viewscroll(void) ciomouse_addevent(CIOLIB_BUTTON_4_PRESS); ciomouse_addevent(CIOLIB_BUTTON_5_PRESS); for (i = 0; (!i) && (!quitting);) { - if (top < 1) - top = 1; - if (top > cterm->backpos) - top = cterm->backpos; + if (top < 0) + top = 0; + if (top > sblines) + top = sblines; vmem_puttext(term.x - 1, term.y - 1, term.x + term.width - 2, term.y + term.height - 2, scrollback + (term.width * top)); cputs("Scrollback"); @@ -86,7 +92,7 @@ viewscroll(void) break; case CIOLIB_BUTTON_5_PRESS: top++; - if (top > cterm->backpos) + if (top > sblines) i = 1; break; } diff --git a/src/syncterm/syncterm.c b/src/syncterm/syncterm.c index 3c7142bf2ccb5382b6d9f055dd31f32c4932fa4c..0e4e51902187028b8e2f2ba89bbaf664a8409e7a 100644 --- a/src/syncterm/syncterm.c +++ b/src/syncterm/syncterm.c @@ -143,7 +143,6 @@ struct syncterm_settings settings; char *font_names[sizeof(conio_fontdata) / sizeof(struct conio_font_data_struct)]; struct vmem_cell *scrollback_buf = NULL; unsigned int scrollback_lines = 0; -unsigned int scrollback_pos = 0; unsigned int scrollback_mode = C80; unsigned int scrollback_cols = 80; int safe_mode = 0; diff --git a/src/syncterm/syncterm.h b/src/syncterm/syncterm.h index 5ca4a7565200bfa0d97ab606be1ecb56dc20b412..afb3e271172be667730c5c6c5be6597233abd085 100644 --- a/src/syncterm/syncterm.h +++ b/src/syncterm/syncterm.h @@ -86,10 +86,7 @@ extern char *inpath; extern char *list_override; extern const char *syncterm_version; extern struct vmem_cell *scrollback_buf; -extern uint32_t *scrollback_fbuf; -extern uint32_t *scrollback_bbuf; extern unsigned int scrollback_lines; -extern unsigned int scrollback_pos; extern unsigned int scrollback_mode; extern unsigned int scrollback_cols; extern struct syncterm_settings settings; diff --git a/src/syncterm/term.c b/src/syncterm/term.c index 0264b3b4b624c94ed7d6f0a8b716d06d3e9ab93a..fb49a6c3cbcd068bb5603c0854ada60e4cd9f397 100644 --- a/src/syncterm/term.c +++ b/src/syncterm/term.c @@ -4080,6 +4080,43 @@ normalize_entry(struct bbslist *bbs) } } +static void +finish_scrollback(void) +{ + scrollback_buf = cterm->scrollback; + scrollback_cols = cterm->backwidth; + // TODO: Set scrollback_mode here? + if (cterm->scrollback != NULL) { + cterm_clearscreen(cterm, cterm->attr); /* Clear screen into + * scrollback */ + + // Now make the scrollback a linear buffer instead of a ring buffer + if (cterm->backstart) { + struct vmem_cell *bottom; + int topsz = cterm->backlines - cterm->backstart; + + bottom = malloc(cterm->backwidth * cterm->backstart * sizeof(*bottom)); + if (bottom) { + memcpy(bottom, cterm->scrollback, cterm->backwidth * cterm->backstart * sizeof(*bottom)); + memmove(cterm->scrollback, cterm->scrollback + cterm->backwidth * cterm->backstart, cterm->backwidth * topsz * sizeof(*cterm->scrollback)); + memcpy(cterm->scrollback + cterm->backwidth * topsz, bottom, cterm->backwidth * cterm->backstart * sizeof(*bottom)); + free(bottom); + scrollback_lines = cterm->backlines; + } + else { + memmove(cterm->scrollback, cterm->scrollback + cterm->backwidth * cterm->backstart, cterm->backwidth * topsz * sizeof(*cterm->scrollback)); + scrollback_lines = topsz; + } + } + else { + scrollback_lines = cterm->backpos; + } + } + else { + scrollback_lines = 0; + } +} + bool doterm(struct bbslist *bbs) { @@ -4153,7 +4190,6 @@ doterm(struct bbslist *bbs) else { FREE_AND_NULL(scrollback_buf); } - scrollback_lines = 0; scrollback_mode = txtinfo.currmode; cterm = cterm_init(term.height, term.width, @@ -4173,7 +4209,6 @@ doterm(struct bbslist *bbs) cterm->mouse_state_change_cbdata = &ms; cterm->mouse_state_query = mouse_state_query; cterm->mouse_state_query_cbdata = &ms; - scrollback_cols = term.width; cterm->music_enable = bbs->music; ch[1] = 0; zrqbuf[0] = 0; @@ -4218,10 +4253,7 @@ doterm(struct bbslist *bbs) uifcmsg("Disconnected", "`Disconnected`\n\nRemote host dropped connection"); check_exit(false); - scrollback_pos = cterm->backpos; - cterm_clearscreen(cterm, cterm->attr); /* Clear screen into - * scrollback */ - scrollback_lines = cterm->backpos; + finish_scrollback(); cterm_end(cterm, 0); cterm = NULL; // TODO: Do this before the popup to avoid being rude... @@ -4559,10 +4591,7 @@ doterm(struct bbslist *bbs) "Selecting Yes closes the connection\n")) { freescreen(savscrn); setup_mouse_events(&ms); - scrollback_pos = cterm->backpos; - cterm_clearscreen(cterm, cterm->attr); /* Clear screen into - * scrollback */ - scrollback_lines = cterm->backpos; + finish_scrollback(); cterm_end(cterm, 0); cterm = NULL; conn_close(); @@ -4591,10 +4620,7 @@ doterm(struct bbslist *bbs) j = wherey(); switch (syncmenu(bbs, &speed)) { case -1: - scrollback_pos = cterm->backpos; - cterm_clearscreen(cterm, cterm->attr); /* Clear screen into - * scrollback */ - scrollback_lines = cterm->backpos; + finish_scrollback(); cterm_end(cterm, 0); cterm = NULL; conn_close(); @@ -4640,10 +4666,7 @@ doterm(struct bbslist *bbs) break; case 13: #endif - scrollback_pos = cterm->backpos; - cterm_clearscreen(cterm, cterm->attr); /* Clear screen into - * scrollback */ - scrollback_lines = cterm->backpos; + finish_scrollback(); cterm_end(cterm, 0); cterm = NULL; conn_close(); @@ -5089,5 +5112,6 @@ doterm(struct bbslist *bbs) * hidemouse(); * hold_update=oldmc; */ + finish_scrollback(); return false; }