xref: /aosp_15_r20/external/coreboot/payloads/libpayload/curses/PDCurses/pdcurses/pad.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
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 
newpad(int nlines,int ncols)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 
subpad(WINDOW * orig,int nlines,int ncols,int begy,int begx)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 
prefresh(WINDOW * win,int py,int px,int sy1,int sx1,int sy2,int sx2)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 
pnoutrefresh(WINDOW * w,int py,int px,int sy1,int sx1,int sy2,int sx2)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 
pechochar(WINDOW * pad,chtype ch)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
pecho_wchar(WINDOW * pad,const cchar_t * wch)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
260