pdcurses/pad.c

branch
protocol5
changeset 106
7b156b764d11
parent 97
2d43f05b284c
equal deleted inserted replaced
104:a76af67a3a4b 106:7b156b764d11
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

mercurial