|
1 /* Public Domain Curses */ |
|
2 |
|
3 #include <curspriv.h> |
|
4 |
|
5 RCSID("$Id: border.c,v 1.53 2008/07/13 16:08:18 wmcbrine Exp $") |
|
6 |
|
7 /*man-start************************************************************** |
|
8 |
|
9 Name: border |
|
10 |
|
11 Synopsis: |
|
12 int border(chtype ls, chtype rs, chtype ts, chtype bs, chtype tl, |
|
13 chtype tr, chtype bl, chtype br); |
|
14 int wborder(WINDOW *win, chtype ls, chtype rs, chtype ts, |
|
15 chtype bs, chtype tl, chtype tr, chtype bl, chtype br); |
|
16 int box(WINDOW *win, chtype verch, chtype horch); |
|
17 int hline(chtype ch, int n); |
|
18 int vline(chtype ch, int n); |
|
19 int whline(WINDOW *win, chtype ch, int n); |
|
20 int wvline(WINDOW *win, chtype ch, int n); |
|
21 int mvhline(int y, int x, chtype ch, int n); |
|
22 int mvvline(int y, int x, chtype ch, int n); |
|
23 int mvwhline(WINDOW *win, int y, int x, chtype ch, int n); |
|
24 int mvwvline(WINDOW *win, int y, int x, chtype ch, int n); |
|
25 |
|
26 int border_set(const cchar_t *ls, const cchar_t *rs, |
|
27 const cchar_t *ts, const cchar_t *bs, |
|
28 const cchar_t *tl, const cchar_t *tr, |
|
29 const cchar_t *bl, const cchar_t *br); |
|
30 int wborder_set(WINDOW *win, const cchar_t *ls, const cchar_t *rs, |
|
31 const cchar_t *ts, const cchar_t *bs, |
|
32 const cchar_t *tl, const cchar_t *tr, |
|
33 const cchar_t *bl, const cchar_t *br); |
|
34 int box_set(WINDOW *win, const cchar_t *verch, const cchar_t *horch); |
|
35 int hline_set(const cchar_t *wch, int n); |
|
36 int vline_set(const cchar_t *wch, int n); |
|
37 int whline_set(WINDOW *win, const cchar_t *wch, int n); |
|
38 int wvline_set(WINDOW *win, const cchar_t *wch, int n); |
|
39 int mvhline_set(int y, int x, const cchar_t *wch, int n); |
|
40 int mvvline_set(int y, int x, const cchar_t *wch, int n); |
|
41 int mvwhline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n); |
|
42 int mvwvline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n); |
|
43 |
|
44 Description: |
|
45 border(), wborder(), and box() draw a border around the edge of |
|
46 the window. If any argument is zero, an appropriate default is |
|
47 used: |
|
48 |
|
49 ls left side of border ACS_VLINE |
|
50 rs right side of border ACS_VLINE |
|
51 ts top side of border ACS_HLINE |
|
52 bs bottom side of border ACS_HLINE |
|
53 tl top left corner of border ACS_ULCORNER |
|
54 tr top right corner of border ACS_URCORNER |
|
55 bl bottom left corner of border ACS_LLCORNER |
|
56 br bottom right corner of border ACS_LRCORNER |
|
57 |
|
58 hline() and whline() draw a horizontal line, using ch, starting |
|
59 from the current cursor position. The cursor position does not |
|
60 change. The line is at most n characters long, or as many as |
|
61 will fit in the window. |
|
62 |
|
63 vline() and wvline() draw a vertical line, using ch, starting |
|
64 from the current cursor position. The cursor position does not |
|
65 change. The line is at most n characters long, or as many as |
|
66 will fit in the window. |
|
67 |
|
68 Return Value: |
|
69 These functions return OK on success and ERR on error. |
|
70 |
|
71 Portability X/Open BSD SYS V |
|
72 border Y - 4.0 |
|
73 wborder Y - 4.0 |
|
74 box Y Y Y |
|
75 hline Y - 4.0 |
|
76 vline Y - 4.0 |
|
77 whline Y - 4.0 |
|
78 wvline Y - 4.0 |
|
79 mvhline Y |
|
80 mvvline Y |
|
81 mvwhline Y |
|
82 mvwvline Y |
|
83 border_set Y |
|
84 wborder_set Y |
|
85 box_set Y |
|
86 hline_set Y |
|
87 vline_set Y |
|
88 whline_set Y |
|
89 wvline_set Y |
|
90 mvhline_set Y |
|
91 mvvline_set Y |
|
92 mvwhline_set Y |
|
93 mvwvline_set Y |
|
94 |
|
95 **man-end****************************************************************/ |
|
96 |
|
97 /* _attr_passthru() -- Takes a single chtype 'ch' and checks if the |
|
98 current attribute of window 'win', as set by wattrset(), and/or the |
|
99 current background of win, as set by wbkgd(), should by combined with |
|
100 it. Attributes set explicitly in ch take precedence. */ |
|
101 |
|
102 static chtype _attr_passthru(WINDOW *win, chtype ch) |
|
103 { |
|
104 chtype attr; |
|
105 |
|
106 /* If the incoming character doesn't have its own attribute, then |
|
107 use the current attributes for the window. If the incoming |
|
108 character has attributes, but not a color component, OR the |
|
109 attributes to the current attributes for the window. If the |
|
110 incoming character has a color component, use only the attributes |
|
111 from the incoming character. */ |
|
112 |
|
113 attr = ch & A_ATTRIBUTES; |
|
114 if (!(attr & A_COLOR)) |
|
115 attr |= win->_attrs; |
|
116 |
|
117 /* wrs (4/10/93) -- Apply the same sort of logic for the window |
|
118 background, in that it only takes precedence if other color |
|
119 attributes are not there. */ |
|
120 |
|
121 if (!(attr & A_COLOR)) |
|
122 attr |= win->_bkgd & A_ATTRIBUTES; |
|
123 else |
|
124 attr |= win->_bkgd & (A_ATTRIBUTES ^ A_COLOR); |
|
125 |
|
126 ch = (ch & A_CHARTEXT) | attr; |
|
127 |
|
128 return ch; |
|
129 } |
|
130 |
|
131 int wborder(WINDOW *win, chtype ls, chtype rs, chtype ts, chtype bs, |
|
132 chtype tl, chtype tr, chtype bl, chtype br) |
|
133 { |
|
134 int i, ymax, xmax; |
|
135 |
|
136 PDC_LOG(("wborder() - called\n")); |
|
137 |
|
138 if (!win) |
|
139 return ERR; |
|
140 |
|
141 ymax = win->_maxy - 1; |
|
142 xmax = win->_maxx - 1; |
|
143 |
|
144 ls = _attr_passthru(win, ls ? ls : ACS_VLINE); |
|
145 rs = _attr_passthru(win, rs ? rs : ACS_VLINE); |
|
146 ts = _attr_passthru(win, ts ? ts : ACS_HLINE); |
|
147 bs = _attr_passthru(win, bs ? bs : ACS_HLINE); |
|
148 tl = _attr_passthru(win, tl ? tl : ACS_ULCORNER); |
|
149 tr = _attr_passthru(win, tr ? tr : ACS_URCORNER); |
|
150 bl = _attr_passthru(win, bl ? bl : ACS_LLCORNER); |
|
151 br = _attr_passthru(win, br ? br : ACS_LRCORNER); |
|
152 |
|
153 for (i = 1; i < xmax; i++) |
|
154 { |
|
155 win->_y[0][i] = ts; |
|
156 win->_y[ymax][i] = bs; |
|
157 } |
|
158 |
|
159 for (i = 1; i < ymax; i++) |
|
160 { |
|
161 win->_y[i][0] = ls; |
|
162 win->_y[i][xmax] = rs; |
|
163 } |
|
164 |
|
165 win->_y[0][0] = tl; |
|
166 win->_y[0][xmax] = tr; |
|
167 win->_y[ymax][0] = bl; |
|
168 win->_y[ymax][xmax] = br; |
|
169 |
|
170 for (i = 0; i <= ymax; i++) |
|
171 { |
|
172 win->_firstch[i] = 0; |
|
173 win->_lastch[i] = xmax; |
|
174 } |
|
175 |
|
176 PDC_sync(win); |
|
177 |
|
178 return OK; |
|
179 } |
|
180 |
|
181 int border(chtype ls, chtype rs, chtype ts, chtype bs, chtype tl, |
|
182 chtype tr, chtype bl, chtype br) |
|
183 { |
|
184 PDC_LOG(("border() - called\n")); |
|
185 |
|
186 return wborder(stdscr, ls, rs, ts, bs, tl, tr, bl, br); |
|
187 } |
|
188 |
|
189 int box(WINDOW *win, chtype verch, chtype horch) |
|
190 { |
|
191 PDC_LOG(("box() - called\n")); |
|
192 |
|
193 return wborder(win, verch, verch, horch, horch, 0, 0, 0, 0); |
|
194 } |
|
195 |
|
196 int whline(WINDOW *win, chtype ch, int n) |
|
197 { |
|
198 chtype *dest; |
|
199 int startpos, endpos; |
|
200 |
|
201 PDC_LOG(("whline() - called\n")); |
|
202 |
|
203 if (!win || n < 1) |
|
204 return ERR; |
|
205 |
|
206 startpos = win->_curx; |
|
207 endpos = min(startpos + n, win->_maxx) - 1; |
|
208 dest = win->_y[win->_cury]; |
|
209 ch = _attr_passthru(win, ch ? ch : ACS_HLINE); |
|
210 |
|
211 for (n = startpos; n <= endpos; n++) |
|
212 dest[n] = ch; |
|
213 |
|
214 n = win->_cury; |
|
215 |
|
216 if (startpos < win->_firstch[n] || win->_firstch[n] == _NO_CHANGE) |
|
217 win->_firstch[n] = startpos; |
|
218 |
|
219 if (endpos > win->_lastch[n]) |
|
220 win->_lastch[n] = endpos; |
|
221 |
|
222 PDC_sync(win); |
|
223 |
|
224 return OK; |
|
225 } |
|
226 |
|
227 int hline(chtype ch, int n) |
|
228 { |
|
229 PDC_LOG(("hline() - called\n")); |
|
230 |
|
231 return whline(stdscr, ch, n); |
|
232 } |
|
233 |
|
234 int mvhline(int y, int x, chtype ch, int n) |
|
235 { |
|
236 PDC_LOG(("mvhline() - called\n")); |
|
237 |
|
238 if (move(y, x) == ERR) |
|
239 return ERR; |
|
240 |
|
241 return whline(stdscr, ch, n); |
|
242 } |
|
243 |
|
244 int mvwhline(WINDOW *win, int y, int x, chtype ch, int n) |
|
245 { |
|
246 PDC_LOG(("mvwhline() - called\n")); |
|
247 |
|
248 if (wmove(win, y, x) == ERR) |
|
249 return ERR; |
|
250 |
|
251 return whline(win, ch, n); |
|
252 } |
|
253 |
|
254 int wvline(WINDOW *win, chtype ch, int n) |
|
255 { |
|
256 int endpos, x; |
|
257 |
|
258 PDC_LOG(("wvline() - called\n")); |
|
259 |
|
260 if (!win || n < 1) |
|
261 return ERR; |
|
262 |
|
263 endpos = min(win->_cury + n, win->_maxy); |
|
264 x = win->_curx; |
|
265 |
|
266 ch = _attr_passthru(win, ch ? ch : ACS_VLINE); |
|
267 |
|
268 for (n = win->_cury; n < endpos; n++) |
|
269 { |
|
270 win->_y[n][x] = ch; |
|
271 |
|
272 if (x < win->_firstch[n] || win->_firstch[n] == _NO_CHANGE) |
|
273 win->_firstch[n] = x; |
|
274 |
|
275 if (x > win->_lastch[n]) |
|
276 win->_lastch[n] = x; |
|
277 } |
|
278 |
|
279 PDC_sync(win); |
|
280 |
|
281 return OK; |
|
282 } |
|
283 |
|
284 int vline(chtype ch, int n) |
|
285 { |
|
286 PDC_LOG(("vline() - called\n")); |
|
287 |
|
288 return wvline(stdscr, ch, n); |
|
289 } |
|
290 |
|
291 int mvvline(int y, int x, chtype ch, int n) |
|
292 { |
|
293 PDC_LOG(("mvvline() - called\n")); |
|
294 |
|
295 if (move(y, x) == ERR) |
|
296 return ERR; |
|
297 |
|
298 return wvline(stdscr, ch, n); |
|
299 } |
|
300 |
|
301 int mvwvline(WINDOW *win, int y, int x, chtype ch, int n) |
|
302 { |
|
303 PDC_LOG(("mvwvline() - called\n")); |
|
304 |
|
305 if (wmove(win, y, x) == ERR) |
|
306 return ERR; |
|
307 |
|
308 return wvline(win, ch, n); |
|
309 } |
|
310 |
|
311 #ifdef PDC_WIDE |
|
312 int wborder_set(WINDOW *win, const cchar_t *ls, const cchar_t *rs, |
|
313 const cchar_t *ts, const cchar_t *bs, const cchar_t *tl, |
|
314 const cchar_t *tr, const cchar_t *bl, const cchar_t *br) |
|
315 { |
|
316 PDC_LOG(("wborder_set() - called\n")); |
|
317 |
|
318 return wborder(win, ls ? *ls : 0, rs ? *rs : 0, ts ? *ts : 0, |
|
319 bs ? *bs : 0, tl ? *tl : 0, tr ? *tr : 0, |
|
320 bl ? *bl : 0, br ? *br : 0); |
|
321 } |
|
322 |
|
323 int border_set(const cchar_t *ls, const cchar_t *rs, const cchar_t *ts, |
|
324 const cchar_t *bs, const cchar_t *tl, const cchar_t *tr, |
|
325 const cchar_t *bl, const cchar_t *br) |
|
326 { |
|
327 PDC_LOG(("border_set() - called\n")); |
|
328 |
|
329 return wborder_set(stdscr, ls, rs, ts, bs, tl, tr, bl, br); |
|
330 } |
|
331 |
|
332 int box_set(WINDOW *win, const cchar_t *verch, const cchar_t *horch) |
|
333 { |
|
334 PDC_LOG(("box_set() - called\n")); |
|
335 |
|
336 return wborder_set(win, verch, verch, horch, horch, |
|
337 (const cchar_t *)NULL, (const cchar_t *)NULL, |
|
338 (const cchar_t *)NULL, (const cchar_t *)NULL); |
|
339 } |
|
340 |
|
341 int whline_set(WINDOW *win, const cchar_t *wch, int n) |
|
342 { |
|
343 PDC_LOG(("whline_set() - called\n")); |
|
344 |
|
345 return wch ? whline(win, *wch, n) : ERR; |
|
346 } |
|
347 |
|
348 int hline_set(const cchar_t *wch, int n) |
|
349 { |
|
350 PDC_LOG(("hline_set() - called\n")); |
|
351 |
|
352 return whline_set(stdscr, wch, n); |
|
353 } |
|
354 |
|
355 int mvhline_set(int y, int x, const cchar_t *wch, int n) |
|
356 { |
|
357 PDC_LOG(("mvhline_set() - called\n")); |
|
358 |
|
359 if (move(y, x) == ERR) |
|
360 return ERR; |
|
361 |
|
362 return whline_set(stdscr, wch, n); |
|
363 } |
|
364 |
|
365 int mvwhline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n) |
|
366 { |
|
367 PDC_LOG(("mvwhline_set() - called\n")); |
|
368 |
|
369 if (wmove(win, y, x) == ERR) |
|
370 return ERR; |
|
371 |
|
372 return whline_set(win, wch, n); |
|
373 } |
|
374 |
|
375 int wvline_set(WINDOW *win, const cchar_t *wch, int n) |
|
376 { |
|
377 PDC_LOG(("wvline_set() - called\n")); |
|
378 |
|
379 return wch ? wvline(win, *wch, n) : ERR; |
|
380 } |
|
381 |
|
382 int vline_set(const cchar_t *wch, int n) |
|
383 { |
|
384 PDC_LOG(("vline_set() - called\n")); |
|
385 |
|
386 return wvline_set(stdscr, wch, n); |
|
387 } |
|
388 |
|
389 int mvvline_set(int y, int x, const cchar_t *wch, int n) |
|
390 { |
|
391 PDC_LOG(("mvvline_set() - called\n")); |
|
392 |
|
393 if (move(y, x) == ERR) |
|
394 return ERR; |
|
395 |
|
396 return wvline_set(stdscr, wch, n); |
|
397 } |
|
398 |
|
399 int mvwvline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n) |
|
400 { |
|
401 PDC_LOG(("mvwvline_set() - called\n")); |
|
402 |
|
403 if (wmove(win, y, x) == ERR) |
|
404 return ERR; |
|
405 |
|
406 return wvline_set(win, wch, n); |
|
407 } |
|
408 #endif |