border.c 11 KB

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