Path: blob/master/Utilities/cmpdcurses/pdcurses/refresh.c
3153 views
/* PDCurses */12#include <curspriv.h>34/*man-start**************************************************************56refresh7-------89### Synopsis1011int refresh(void);12int wrefresh(WINDOW *win);13int wnoutrefresh(WINDOW *win);14int doupdate(void);15int redrawwin(WINDOW *win);16int wredrawln(WINDOW *win, int beg_line, int num_lines);1718### Description1920wrefresh() copies the named window to the physical terminal screen,21taking into account what is already there in order to optimize cursor22movement. refresh() does the same, using stdscr. These routines must23be called to get any output on the terminal, as other routines only24manipulate data structures. Unless leaveok() has been enabled, the25physical cursor of the terminal is left at the location of the26window's cursor.2728wnoutrefresh() and doupdate() allow multiple updates with more29efficiency than wrefresh() alone. wrefresh() works by first calling30wnoutrefresh(), which copies the named window to the virtual screen.31It then calls doupdate(), which compares the virtual screen to the32physical screen and does the actual update. A series of calls to33wrefresh() will result in alternating calls to wnoutrefresh() and34doupdate(), causing several bursts of output to the screen. By first35calling wnoutrefresh() for each window, it is then possible to call36doupdate() only once.3738In PDCurses, redrawwin() is equivalent to touchwin(), and wredrawln()39is the same as touchline(). In some other curses implementations,40there's a subtle distinction, but it has no meaning in PDCurses.4142### Return Value4344All functions return OK on success and ERR on error.4546### Portability47X/Open ncurses NetBSD48refresh Y Y Y49wrefresh Y Y Y50wnoutrefresh Y Y Y51doupdate Y Y Y52redrawwin Y Y Y53wredrawln Y Y Y5455**man-end****************************************************************/5657#include <string.h>5859int wnoutrefresh(WINDOW *win)60{61int begy, begx; /* window's place on screen */62int i, j;6364PDC_LOG(("wnoutrefresh() - called: win=%p\n", win));6566if ( !win || (win->_flags & (_PAD|_SUBPAD)) )67return ERR;6869begy = win->_begy;70begx = win->_begx;7172for (i = 0, j = begy; i < win->_maxy; i++, j++)73{74if (win->_firstch[i] != _NO_CHANGE)75{76chtype *src = win->_y[i];77chtype *dest = curscr->_y[j] + begx;7879int first = win->_firstch[i]; /* first changed */80int last = win->_lastch[i]; /* last changed */8182/* ignore areas on the outside that are marked as changed,83but really aren't */8485while (first <= last && src[first] == dest[first])86first++;8788while (last >= first && src[last] == dest[last])89last--;9091/* if any have really changed... */9293if (first <= last)94{95memcpy(dest + first, src + first,96(last - first + 1) * sizeof(chtype));9798first += begx;99last += begx;100101if (first < curscr->_firstch[j] ||102curscr->_firstch[j] == _NO_CHANGE)103curscr->_firstch[j] = first;104105if (last > curscr->_lastch[j])106curscr->_lastch[j] = last;107}108109win->_firstch[i] = _NO_CHANGE; /* updated now */110}111112win->_lastch[i] = _NO_CHANGE; /* updated now */113}114115if (win->_clear)116win->_clear = FALSE;117118if (!win->_leaveit)119{120curscr->_cury = win->_cury + begy;121curscr->_curx = win->_curx + begx;122}123124return OK;125}126127int doupdate(void)128{129int y;130bool clearall;131132PDC_LOG(("doupdate() - called\n"));133134if (!SP || !curscr)135return ERR;136137if (isendwin()) /* coming back after endwin() called */138{139reset_prog_mode();140clearall = TRUE;141SP->alive = TRUE; /* so isendwin() result is correct */142}143else144clearall = curscr->_clear;145146for (y = 0; y < SP->lines; y++)147{148PDC_LOG(("doupdate() - Transforming line %d of %d: %s\n",149y, SP->lines, (curscr->_firstch[y] != _NO_CHANGE) ?150"Yes" : "No"));151152if (clearall || curscr->_firstch[y] != _NO_CHANGE)153{154int first, last;155156chtype *src = curscr->_y[y];157chtype *dest = SP->lastscr->_y[y];158159if (clearall)160{161first = 0;162last = COLS - 1;163}164else165{166first = curscr->_firstch[y];167last = curscr->_lastch[y];168}169170while (first <= last)171{172int len = 0;173174/* build up a run of changed cells; if two runs are175separated by a single unchanged cell, ignore the176break */177178if (clearall)179len = last - first + 1;180else181while (first + len <= last &&182(src[first + len] != dest[first + len] ||183(len && first + len < last &&184src[first + len + 1] != dest[first + len + 1])185)186)187len++;188189/* update the screen, and SP->lastscr */190191if (len)192{193PDC_transform_line(y, first, len, src + first);194memcpy(dest + first, src + first, len * sizeof(chtype));195first += len;196}197198/* skip over runs of unchanged cells */199200while (first <= last && src[first] == dest[first])201first++;202}203204curscr->_firstch[y] = _NO_CHANGE;205curscr->_lastch[y] = _NO_CHANGE;206}207}208209curscr->_clear = FALSE;210211if (SP->visibility)212PDC_gotoyx(curscr->_cury, curscr->_curx);213214SP->cursrow = curscr->_cury;215SP->curscol = curscr->_curx;216217PDC_doupdate();218219return OK;220}221222int wrefresh(WINDOW *win)223{224bool save_clear;225226PDC_LOG(("wrefresh() - called\n"));227228if ( !win || (win->_flags & (_PAD|_SUBPAD)) )229return ERR;230231save_clear = win->_clear;232233if (win == curscr)234curscr->_clear = TRUE;235else236wnoutrefresh(win);237238if (save_clear && win->_maxy == SP->lines && win->_maxx == SP->cols)239curscr->_clear = TRUE;240241return doupdate();242}243244int refresh(void)245{246PDC_LOG(("refresh() - called\n"));247248return wrefresh(stdscr);249}250251int wredrawln(WINDOW *win, int start, int num)252{253int i;254255PDC_LOG(("wredrawln() - called: win=%p start=%d num=%d\n",256win, start, num));257258if (!win || start > win->_maxy || start + num > win->_maxy)259return ERR;260261for (i = start; i < start + num; i++)262{263win->_firstch[i] = 0;264win->_lastch[i] = win->_maxx - 1;265}266267return OK;268}269270int redrawwin(WINDOW *win)271{272PDC_LOG(("redrawwin() - called: win=%p\n", win));273274if (!win)275return ERR;276277return wredrawln(win, 0, win->_maxy);278}279280281