ccc5db20d354ec4ca9ee05a993040c18ecc5ba58
[coreboot.git] / payloads / libpayload / curses / PDCurses-3.4 / pdcurses / pad.c
1 /* Public Domain Curses */
2
3 #include <curspriv.h>
4
5 RCSID("$Id: pad.c,v 1.50 2008/07/14 12:22:13 wmcbrine Exp $")
6
7 /*man-start**************************************************************
8
9   Name:                                                         pad
10
11   Synopsis:
12         WINDOW *newpad(int nlines, int ncols);
13         WINDOW *subpad(WINDOW *orig, int nlines, int ncols,
14                        int begy, int begx);
15         int prefresh(WINDOW *win, int py, int px, int sy1, int sx1,
16                      int sy2, int sx2);
17         int pnoutrefresh(WINDOW *w, int py, int px, int sy1, int sx1,
18                          int sy2, int sx2);
19         int pechochar(WINDOW *pad, chtype ch);
20         int pecho_wchar(WINDOW *pad, const cchar_t *wch);
21
22   Description:
23         A pad is a special kind of window, which is not restricted by
24         the screen size, and is not necessarily associated with a
25         particular part of the screen.  You can use a pad when you need
26         a large window, and only a part of the window will be on the
27         screen at one time.  Pads are not refreshed automatically (e.g.,
28         from scrolling or echoing of input).  You can't call wrefresh()
29         with a pad as an argument; use prefresh() or pnoutrefresh()
30         instead.  Note that these routines require additional parameters
31         to specify the part of the pad to be displayed, and the location
32         to use on the screen.
33
34         newpad() creates a new pad data structure.  
35
36         subpad() creates a new sub-pad within a pad, at position (begy,
37         begx), with dimensions of nlines lines and ncols columns. This 
38         position is relative to the pad, and not to the screen as with 
39         subwin.  Changes to either the parent pad or sub-pad will affect 
40         both.  When using sub-pads, you may need to call touchwin() 
41         before calling prefresh().
42
43         pnoutrefresh() copies the specified pad to the virtual screen.
44
45         prefresh() calls pnoutrefresh(), followed by doupdate().
46
47         These routines are analogous to wnoutrefresh() and wrefresh().
48         (py, px) specifies the upper left corner of the part of the pad
49         to be displayed; (sy1, sx1) and (sy2, sx2) describe the screen 
50         rectangle that will contain the selected part of the pad.
51
52         pechochar() is functionally equivalent to addch() followed by
53         a call to prefresh(), with the last-used coordinates and
54         dimensions. pecho_wchar() is the wide-character version.
55
56   Return Value:
57         All functions return OK on success and ERR on error.
58
59   Portability                                X/Open    BSD    SYS V
60         newpad                                  Y       -       Y
61         subpad                                  Y       -       Y
62         prefresh                                Y       -       Y
63         pnoutrefresh                            Y       -       Y
64         pechochar                               Y       -      3.0
65         pecho_wchar                             Y
66
67 **man-end****************************************************************/
68
69 #include <string.h>
70
71 /* save values for pechochar() */
72
73 static int save_pminrow, save_pmincol;
74 static int save_sminrow, save_smincol, save_smaxrow, save_smaxcol;
75
76 WINDOW *newpad(int nlines, int ncols)
77 {
78     WINDOW *win;
79
80     PDC_LOG(("newpad() - called: lines=%d cols=%d\n", nlines, ncols));
81
82     if ( !(win = PDC_makenew(nlines, ncols, -1, -1))
83         || !(win = PDC_makelines(win)) )
84         return (WINDOW *)NULL;
85
86     werase(win);
87
88     win->_flags = _PAD;
89
90     /* save default values in case pechochar() is the first call to 
91        prefresh(). */
92
93     save_pminrow = 0;
94     save_pmincol = 0;
95     save_sminrow = 0;
96     save_smincol = 0;
97     save_smaxrow = min(LINES, nlines) - 1;
98     save_smaxcol = min(COLS, ncols) - 1;
99
100     return win;
101 }
102
103 WINDOW *subpad(WINDOW *orig, int nlines, int ncols, int begy, int begx)
104 {
105     WINDOW *win;
106     int i;
107     int j = begy;
108     int k = begx;
109
110     PDC_LOG(("subpad() - called: lines=%d cols=%d begy=%d begx=%d\n",
111              nlines, ncols, begy, begx));
112
113     if (!orig || !(orig->_flags & _PAD))
114         return (WINDOW *)NULL;
115
116     /* make sure window fits inside the original one */
117
118     if ((begy < orig->_begy) || (begx < orig->_begx) ||
119         (begy + nlines) > (orig->_begy + orig->_maxy) ||
120         (begx + ncols)  > (orig->_begx + orig->_maxx))
121         return (WINDOW *)NULL;
122
123     if (!nlines) 
124         nlines = orig->_maxy - 1 - j;
125
126     if (!ncols) 
127         ncols = orig->_maxx - 1 - k;
128
129     if ( !(win = PDC_makenew(nlines, ncols, begy, begx)) )
130         return (WINDOW *)NULL;
131
132     /* initialize window variables */
133
134     win->_attrs = orig->_attrs;
135     win->_leaveit = orig->_leaveit;
136     win->_scroll = orig->_scroll;
137     win->_nodelay = orig->_nodelay;
138     win->_use_keypad = orig->_use_keypad;
139     win->_parent = orig;
140
141     for (i = 0; i < nlines; i++)
142         win->_y[i] = (orig->_y[j++]) + k;
143
144     win->_flags = _SUBPAD;
145
146     /* save default values in case pechochar() is the first call
147        to prefresh(). */
148
149     save_pminrow = 0;
150     save_pmincol = 0;
151     save_sminrow = 0;
152     save_smincol = 0;
153     save_smaxrow = min(LINES, nlines) - 1;
154     save_smaxcol = min(COLS, ncols) - 1;
155
156     return win;
157 }
158
159 int prefresh(WINDOW *win, int py, int px, int sy1, int sx1, int sy2, int sx2)
160 {
161     PDC_LOG(("prefresh() - called\n"));
162
163     if (pnoutrefresh(win, py, px, sy1, sx1, sy2, sx2) == ERR)
164         return ERR;
165
166     doupdate();
167     return OK;
168 }
169
170 int pnoutrefresh(WINDOW *w, int py, int px, int sy1, int sx1, int sy2, int sx2)
171 {
172     int num_cols;
173     int sline = sy1;
174     int pline = py;
175
176     PDC_LOG(("pnoutrefresh() - called\n"));
177
178     if (!w || !(w->_flags & (_PAD|_SUBPAD)) || (sy2 >= LINES) || (sy2 >= COLS))
179         return ERR;
180
181     if (py < 0)
182         py = 0;
183     if (px < 0)
184         px = 0;
185     if (sy1 < 0)
186         sy1 = 0;
187     if (sx1 < 0)
188         sx1 = 0;
189
190     if (sy2 < sy1 || sx2 < sx1)
191         return ERR;
192
193     num_cols = min((sx2 - sx1 + 1), (w->_maxx - px));
194
195     while (sline <= sy2)
196     {
197         if (pline < w->_maxy)
198         {
199             memcpy(curscr->_y[sline] + sx1, w->_y[pline] + px,
200                    num_cols * sizeof(chtype));
201
202             if ((curscr->_firstch[sline] == _NO_CHANGE) 
203                 || (curscr->_firstch[sline] > sx1))
204                 curscr->_firstch[sline] = sx1;
205
206             if (sx2 > curscr->_lastch[sline])
207                 curscr->_lastch[sline] = sx2;
208
209             w->_firstch[pline] = _NO_CHANGE; /* updated now */
210             w->_lastch[pline] = _NO_CHANGE;  /* updated now */
211         }
212
213         sline++;
214         pline++;
215     }
216
217     if (w->_clear)
218     {
219         w->_clear = FALSE;
220         curscr->_clear = TRUE;
221     }
222
223     /* position the cursor to the pad's current position if possible -- 
224        is the pad current position going to end up displayed? if not, 
225        then don't move the cursor; if so, move it to the correct place */
226
227     if (!w->_leaveit && w->_cury >= py && w->_curx >= px &&
228          w->_cury <= py + (sy2 - sy1) && w->_curx <= px + (sx2 - sx1))
229     {
230         curscr->_cury = (w->_cury - py) + sy1;
231         curscr->_curx = (w->_curx - px) + sx1;
232     }
233
234     return OK;
235 }
236
237 int pechochar(WINDOW *pad, chtype ch)
238 {
239     PDC_LOG(("pechochar() - called\n"));
240
241     if (waddch(pad, ch) == ERR)
242         return ERR;
243
244     return prefresh(pad, save_pminrow, save_pmincol, save_sminrow, 
245                     save_smincol, save_smaxrow, save_smaxcol);
246 }
247
248 #ifdef PDC_WIDE
249 int pecho_wchar(WINDOW *pad, const cchar_t *wch)
250 {
251     PDC_LOG(("pecho_wchar() - called\n"));
252
253     if (!wch || (waddch(pad, *wch) == ERR))
254         return ERR;
255
256     return prefresh(pad, save_pminrow, save_pmincol, save_sminrow, 
257                     save_smincol, save_smaxrow, save_smaxcol);
258 }
259 #endif