libpayload: Add PDCurses and ncurses' libform/libmenu
[coreboot.git] / payloads / libpayload / curses / PDCurses-3.4 / pdcurses / refresh.c
1 /* Public Domain Curses */
2
3 #include <curspriv.h>
4
5 RCSID("$Id: refresh.c,v 1.56 2008/07/13 16:08:18 wmcbrine Exp $")
6
7 /*man-start**************************************************************
8
9   Name:                                                         refresh
10
11   Synopsis:
12         int refresh(void);
13         int wrefresh(WINDOW *win);
14         int wnoutrefresh(WINDOW *win);
15         int doupdate(void);
16         int redrawwin(WINDOW *win);
17         int wredrawln(WINDOW *win, int beg_line, int num_lines);
18
19   Description:
20         wrefresh() copies the named window to the physical terminal 
21         screen, taking into account what is already there in order to 
22         optimize cursor movement. refresh() does the same, using stdscr. 
23         These routines must be called to get any output on the terminal, 
24         as other routines only manipulate data structures. Unless 
25         leaveok() has been enabled, the physical cursor of the terminal 
26         is left at the location of the window's cursor.
27
28         wnoutrefresh() and doupdate() allow multiple updates with more 
29         efficiency than wrefresh() alone. wrefresh() works by first 
30         calling wnoutrefresh(), which copies the named window to the 
31         virtual screen.  It then calls doupdate(), which compares the 
32         virtual screen to the physical screen and does the actual 
33         update. A series of calls to wrefresh() will result in 
34         alternating calls to wnoutrefresh() and doupdate(), causing 
35         several bursts of output to the screen.  By first calling 
36         wnoutrefresh() for each window, it is then possible to call 
37         doupdate() only once.
38
39         In PDCurses, redrawwin() is equivalent to touchwin(), and 
40         wredrawln() is the same as touchline(). In some other curses 
41         implementations, there's a subtle distinction, but it has no 
42         meaning in PDCurses.
43
44   Return Value:
45         All functions return OK on success and ERR on error.
46
47   Portability                                X/Open    BSD    SYS V
48         refresh                                 Y       Y       Y
49         wrefresh                                Y       Y       Y
50         wnoutrefresh                            Y       Y       Y
51         doupdate                                Y       Y       Y
52         redrawwin                               Y       -      4.0
53         wredrawln                               Y       -      4.0
54
55 **man-end****************************************************************/
56
57 #include <string.h>
58
59 int wnoutrefresh(WINDOW *win)
60 {
61     int begy, begx;     /* window's place on screen   */
62     int i, j;
63
64     PDC_LOG(("wnoutrefresh() - called: win=%p\n", win));
65
66     if ( !win || (win->_flags & (_PAD|_SUBPAD)) )
67         return ERR;
68
69     begy = win->_begy;
70     begx = win->_begx;
71
72     for (i = 0, j = begy; i < win->_maxy; i++, j++)
73     {
74         if (win->_firstch[i] != _NO_CHANGE)
75         {
76             chtype *src = win->_y[i];
77             chtype *dest = curscr->_y[j] + begx;
78
79             int first = win->_firstch[i]; /* first changed */
80             int last = win->_lastch[i];   /* last changed */
81
82             /* ignore areas on the outside that are marked as changed, 
83                but really aren't */
84
85             while (first <= last && src[first] == dest[first])
86                 first++;
87
88             while (last >= first && src[last] == dest[last])
89                 last--;
90
91             /* if any have really changed... */
92
93             if (first <= last)
94             {
95                 memcpy(dest + first, src + first,
96                        (last - first + 1) * sizeof(chtype));
97
98                 first += begx; 
99                 last += begx;
100
101                 if (first < curscr->_firstch[j] ||
102                     curscr->_firstch[j] == _NO_CHANGE)
103                     curscr->_firstch[j] = first;
104
105                 if (last > curscr->_lastch[j])
106                     curscr->_lastch[j] = last;
107             }
108
109             win->_firstch[i] = _NO_CHANGE;  /* updated now */
110         }
111
112         win->_lastch[i] = _NO_CHANGE;       /* updated now */
113     }
114
115     if (win->_clear)
116         win->_clear = FALSE;
117
118     if (!win->_leaveit)
119     {
120         curscr->_cury = win->_cury + begy;
121         curscr->_curx = win->_curx + begx;
122     }
123
124     return OK;
125 }
126
127 int doupdate(void)
128 {
129     int y;
130     bool clearall;
131
132     PDC_LOG(("doupdate() - called\n"));
133
134     if (!curscr)
135         return ERR;
136
137     if (isendwin())         /* coming back after endwin() called */
138     {
139         reset_prog_mode();
140         clearall = TRUE;
141         SP->alive = TRUE;   /* so isendwin() result is correct */
142     }
143     else
144         clearall = curscr->_clear;
145
146     for (y = 0; y < SP->lines; y++)
147     {
148         PDC_LOG(("doupdate() - Transforming line %d of %d: %s\n",
149                  y, SP->lines, (curscr->_firstch[y] != _NO_CHANGE) ?
150                  "Yes" : "No"));
151
152         if (clearall || curscr->_firstch[y] != _NO_CHANGE)
153         {
154             int first, last;
155
156             chtype *src = curscr->_y[y];
157             chtype *dest = pdc_lastscr->_y[y];
158
159             if (clearall)
160             {
161                 first = 0;
162                 last = COLS - 1;
163             }
164             else
165             {
166                 first = curscr->_firstch[y];
167                 last = curscr->_lastch[y];
168             }
169
170             while (first <= last)
171             {
172                 int len = 0;
173
174                 /* build up a run of changed cells; if two runs are
175                    separated by a single unchanged cell, ignore the
176                    break */
177
178                 if (clearall)
179                     len = last - first + 1;
180                 else
181                     while (first + len <= last &&
182                            (src[first + len] != dest[first + len] ||
183                             (len && first + len < last &&
184                              src[first + len + 1] != dest[first + len + 1])
185                            )
186                           )
187                         len++;
188
189                 /* update the screen, and pdc_lastscr */
190
191                 if (len)
192                 {
193                     PDC_transform_line(y, first, len, src + first);
194                     memcpy(dest + first, src + first, len * sizeof(chtype));
195                     first += len;
196                 }
197
198                 /* skip over runs of unchanged cells */
199
200                 while (first <= last && src[first] == dest[first])
201                     first++;
202             }
203
204             curscr->_firstch[y] = _NO_CHANGE;
205             curscr->_lastch[y] = _NO_CHANGE;
206         }
207     }
208
209     curscr->_clear = FALSE;
210
211     if (SP->visibility)
212         PDC_gotoyx(curscr->_cury, curscr->_curx);
213
214     SP->cursrow = curscr->_cury;
215     SP->curscol = curscr->_curx;
216
217     return OK;
218 }
219
220 int wrefresh(WINDOW *win)
221 {
222     bool save_clear;
223
224     PDC_LOG(("wrefresh() - called\n"));
225
226     if ( !win || (win->_flags & (_PAD|_SUBPAD)) )
227         return ERR;
228
229     save_clear = win->_clear;
230
231     if (win == curscr)
232         curscr->_clear = TRUE;
233     else
234         wnoutrefresh(win);
235
236     if (save_clear && win->_maxy == SP->lines && win->_maxx == SP->cols)
237         curscr->_clear = TRUE;
238
239     return doupdate();
240 }
241
242 int refresh(void)
243 {
244     PDC_LOG(("refresh() - called\n"));
245
246     return wrefresh(stdscr);
247 }
248
249 int wredrawln(WINDOW *win, int start, int num)
250 {
251     int i;
252
253     PDC_LOG(("wredrawln() - called: win=%p start=%d num=%d\n",
254         win, start, num));
255
256     if (!win || start > win->_maxy || start + num > win->_maxy)
257         return ERR;
258
259     for (i = start; i < start + num; i++)
260     {
261         win->_firstch[i] = 0;
262         win->_lastch[i] = win->_maxx - 1;
263     }
264
265     return OK;
266 }
267
268 int redrawwin(WINDOW *win)
269 {
270     PDC_LOG(("redrawwin() - called: win=%p\n", win));
271
272     if (!win)
273         return ERR;
274
275     return wredrawln(win, 0, win->_maxy);
276 }