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