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