| |
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 |