Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!husc6!hao!ames!lll-tis!mordor!sri-spam!rutgers!gatech!mcdchg!usenet From: mb@ttidca.UUCP (Michael Bloom) Newsgroups: comp.unix Subject: Re: curses "untouch"? Message-ID: <2137@mcdchg.UUCP> Date: Fri, 23-Oct-87 11:07:11 EST Article-I.D.: mcdchg.2137 Posted: Fri Oct 23 11:07:11 1987 Date-Received: Sun, 25-Oct-87 22:45:39 EST References: <2059@mcdchg.UUCP> Sender: usenet@mcdchg.UUCP Reply-To: mb@psivax.UUCP (Michael Bloom) Organization: Citicorp/TTI, Santa Monica Lines: 235 Approved: usenet@mcdchg.UUCP > The problem is thus: I want to scroll a portion of my screen, and curses > does this very slowly be rewriting the whole portion. I want to do a > hardware scroll by sending the proper code directly to my terminal, doing > a scroll(win), and then having curses be happy with the way things are > and do nothing on the next wrefresh(win). However, since curses thinks > the whole window has to be refreshed due to the scroll(), it rewrites... I did this once a while back. You can't use scroll() itself, however. What you do instead is to use a combination if winsertln() and wdeleteln() calls, doing the same operations that you did on stdscr again on curscr AT THE SAME TIME as you handle the hardware scroll. After which, it is safe to call refresh. (System V curses is smarter; for portability to system V, you can just ifdef out all the klugery). With just the above, you need to do a lot of extra hardware operations. It's better to put a wrapper around winsertln() and wdeleteln() to leave an audit of the operations you've performed on stdscr. Then you can have a redisplay() routine that looks like redisplay() { if (optimize_scrollinfo(audit_info) < THRESHOLD) do_hardware_scroll(audit_info); (*application_specific_pre_work)(); /* optional */ refresh(); (*application_specific_post_work)(); /* also optional */ clear_audit(); } My original application was fairly simple and always scrolled the same sub-portion of the window, so my do_hardware_scroll used a global scroll count instead of a more elaborate audit trail and looked like: do_hardware_scroll() { int cnt = ins_del_cnt; int abscnt = (ins_del_cnt >=0 ) ?ins_del_cnt : -ins_del_cnt; int i; if (!abscnt || abscnt > SCROLLBOT-2) /* let curses do its own thing */ return; if (ins_del_cnt <0) /* scroll up */ { for (i = 0;i=0;i--) { wmove(win,i,0); wclrtoeol(win); } if (win == curscr) scgoto(0,0); } clear_txt() { wclear_txt(stdscr); } ins_line(scr) WINDOW *scr; { winsertln(scr); if (scr == curscr) return; ins_del_cnt++; if (ins_cnt < ins_del_cnt) ins_cnt++; } del_line(scr) WINDOW * scr; { wdeleteln(scr); if (scr == curscr) return; ins_del_cnt--; if (del_cnt > ins_del_cnt) del_cnt--; } scrollup() { wscr_up(stdscr); } wscr_up(scr) WINDOW *scr; { wmove(scr,0,0); del_line(scr); wmove(scr,SCROLLBOT,0); winsertln(scr); } scrolldown() { wscr_down(stdscr); } wscr_down(scr) WINDOW *scr; { wmove(scr,SCROLLBOT,0); wdeleteln(scr); wmove(scr,0,0); ins_line(scr); } clr_cnt() { ins_del_cnt = del_cnt = ins_cnt = 0; } clr_lowest_line() { move(ECHOLINE,0); clrtoeol(); } invalidate_screen() { werase(curscr); clearok(curscr,1); } /* flush: called by routines that dont include curses.h */ flush() { refresh(); } to_scroll_bot() { move(SCROLLBOT,0); } /* called from routines that dont include either curses.h or stdio.h */ std_flush() { fflush(stdout); }