Home | History | Annotate | Line # | Download | only in libcurses
line.c revision 1.17.4.1
      1  1.17.4.1  perseant /*	$NetBSD: line.c,v 1.17.4.1 2025/08/02 05:54:47 perseant Exp $	*/
      2       1.1     blymn 
      3       1.1     blymn /*-
      4       1.1     blymn  * Copyright (c) 1998-1999 Brett Lymn
      5      1.14       uwe  *                         (blymn (at) baea.com.au, brett_lymn (at) yahoo.com.au)
      6       1.1     blymn  * All rights reserved.
      7       1.1     blymn  *
      8       1.1     blymn  * This code has been donated to The NetBSD Foundation by the Author.
      9       1.1     blymn  *
     10       1.1     blymn  * Redistribution and use in source and binary forms, with or without
     11       1.1     blymn  * modification, are permitted provided that the following conditions
     12       1.1     blymn  * are met:
     13       1.1     blymn  * 1. Redistributions of source code must retain the above copyright
     14       1.1     blymn  *    notice, this list of conditions and the following disclaimer.
     15       1.1     blymn  * 2. The name of the author may not be used to endorse or promote products
     16       1.3       wiz  *    derived from this software without specific prior written permission
     17       1.1     blymn  *
     18       1.1     blymn  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     19       1.1     blymn  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     20       1.1     blymn  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     21       1.1     blymn  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     22       1.1     blymn  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     23       1.1     blymn  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     24       1.1     blymn  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     25       1.1     blymn  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     26       1.1     blymn  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     27       1.1     blymn  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28       1.1     blymn  *
     29       1.1     blymn  *
     30       1.1     blymn  */
     31       1.1     blymn 
     32       1.1     blymn #include <sys/cdefs.h>
     33       1.1     blymn #ifndef lint
     34  1.17.4.1  perseant __RCSID("$NetBSD: line.c,v 1.17.4.1 2025/08/02 05:54:47 perseant Exp $");
     35       1.1     blymn #endif				/* not lint */
     36       1.1     blymn 
     37       1.5     blymn #include <string.h>
     38       1.5     blymn 
     39       1.1     blymn #include "curses.h"
     40       1.1     blymn #include "curses_private.h"
     41       1.1     blymn 
     42       1.1     blymn /*
     43       1.1     blymn  * hline --
     44       1.5     blymn  *	Draw a horizontal line of character c on stdscr.
     45       1.1     blymn  */
     46       1.1     blymn int
     47       1.1     blymn hline(chtype ch, int count)
     48       1.1     blymn {
     49       1.9       roy 
     50       1.1     blymn 	return whline(stdscr, ch, count);
     51       1.1     blymn }
     52       1.1     blymn 
     53       1.1     blymn /*
     54       1.1     blymn  * mvhline --
     55       1.5     blymn  *	Move to location (y, x) and draw a horizontal line of character c
     56       1.5     blymn  *	on stdscr.
     57       1.1     blymn  */
     58       1.1     blymn int
     59       1.1     blymn mvhline(int y, int x, chtype ch, int count)
     60       1.1     blymn {
     61       1.9       roy 
     62       1.1     blymn 	return mvwhline(stdscr, y, x, ch, count);
     63       1.1     blymn }
     64       1.1     blymn 
     65       1.1     blymn /*
     66       1.1     blymn  * mvwhline --
     67       1.5     blymn  *	Move to location (y, x) and draw a horizontal line of character c
     68       1.5     blymn  *	in the given window.
     69       1.1     blymn  */
     70       1.1     blymn int
     71       1.1     blymn mvwhline(WINDOW *win, int y, int x, chtype ch, int count)
     72       1.1     blymn {
     73       1.9       roy 
     74      1.11     blymn 	if (wmove(win, y, x) == ERR)
     75       1.1     blymn 		return ERR;
     76       1.1     blymn 
     77       1.1     blymn 	return whline(win, ch, count);
     78       1.1     blymn }
     79       1.1     blymn 
     80       1.1     blymn /*
     81       1.1     blymn  * whline --
     82       1.5     blymn  *	Draw a horizontal line of character c in the given window moving
     83       1.5     blymn  *	towards the rightmost column.  At most count characters are drawn
     84       1.5     blymn  *	or until the edge of the screen, whichever comes first.
     85       1.1     blymn  */
     86       1.1     blymn int
     87       1.1     blymn whline(WINDOW *win, chtype ch, int count)
     88       1.1     blymn {
     89       1.6  drochner #ifndef HAVE_WCHAR
     90  1.17.4.1  perseant 	if (__predict_false(win == NULL))
     91  1.17.4.1  perseant 		return ERR;
     92  1.17.4.1  perseant 
     93      1.13       uwe 	int ocury, ocurx, n, i;
     94       1.1     blymn 
     95       1.1     blymn 	n = min(count, win->maxx - win->curx);
     96      1.15       uwe 	ocury = win->cury;
     97       1.1     blymn 	ocurx = win->curx;
     98       1.4     blymn 
     99       1.2       jdc 	if (!(ch & __CHARTEXT))
    100       1.2       jdc 		ch |= ACS_HLINE;
    101       1.1     blymn 	for (i = 0; i < n; i++)
    102      1.13       uwe 		mvwaddch(win, ocury, ocurx + i, ch);
    103       1.7       roy 
    104      1.13       uwe 	wmove(win, ocury, ocurx);
    105       1.1     blymn 	return OK;
    106       1.6  drochner #else
    107      1.16       uwe 	cchar_t cch;
    108       1.6  drochner 
    109      1.16       uwe 	__cursesi_chtype_to_cchar(ch, &cch);
    110      1.16       uwe 	return whline_set(win, &cch, count);
    111       1.6  drochner #endif
    112       1.1     blymn }
    113       1.1     blymn 
    114       1.1     blymn /*
    115       1.1     blymn  * vline --
    116       1.5     blymn  *	Draw a vertical line of character ch on stdscr.
    117       1.1     blymn  */
    118       1.1     blymn int
    119       1.1     blymn vline(chtype ch, int count)
    120       1.1     blymn {
    121       1.9       roy 
    122       1.1     blymn 	return wvline(stdscr, ch, count);
    123       1.1     blymn }
    124       1.1     blymn 
    125       1.1     blymn /*
    126       1.1     blymn  * mvvline --
    127  1.17.4.1  perseant  *	Move to the given location and draw a vertical line of character ch.
    128       1.1     blymn  */
    129       1.1     blymn int
    130       1.1     blymn mvvline(int y, int x, chtype ch, int count)
    131       1.1     blymn {
    132       1.9       roy 
    133       1.1     blymn 	return mvwvline(stdscr, y, x, ch, count);
    134       1.1     blymn }
    135       1.1     blymn 
    136       1.1     blymn /*
    137       1.1     blymn  * mvwvline --
    138       1.5     blymn  *	Move to the given location and draw a vertical line of character ch
    139       1.5     blymn  *	on the given window.
    140       1.1     blymn  */
    141       1.1     blymn int
    142       1.1     blymn mvwvline(WINDOW *win, int y, int x, chtype ch, int count)
    143       1.1     blymn {
    144       1.9       roy 
    145      1.11     blymn 	if (wmove(win, y, x) == ERR)
    146       1.1     blymn 		return ERR;
    147       1.1     blymn 
    148       1.1     blymn 	return wvline(win, ch, count);
    149       1.1     blymn }
    150       1.1     blymn 
    151       1.1     blymn /*
    152       1.1     blymn  * wvline --
    153       1.5     blymn  *	Draw a vertical line of character ch in the given window moving
    154       1.5     blymn  *	towards the bottom of the screen.  At most count characters are drawn
    155       1.5     blymn  *	or until the edge of the screen, whichever comes first.
    156       1.1     blymn  */
    157       1.1     blymn int
    158       1.1     blymn wvline(WINDOW *win, chtype ch, int count)
    159       1.1     blymn {
    160       1.6  drochner #ifndef HAVE_WCHAR
    161       1.1     blymn 	int ocury, ocurx, n, i;
    162       1.1     blymn 
    163  1.17.4.1  perseant 	if (__predict_false(win == NULL))
    164  1.17.4.1  perseant 		return ERR;
    165  1.17.4.1  perseant 
    166       1.1     blymn 	n = min(count, win->maxy - win->cury);
    167       1.1     blymn 	ocury = win->cury;
    168       1.1     blymn 	ocurx = win->curx;
    169       1.1     blymn 
    170       1.2       jdc 	if (!(ch & __CHARTEXT))
    171       1.2       jdc 		ch |= ACS_VLINE;
    172       1.1     blymn 	for (i = 0; i < n; i++)
    173       1.1     blymn 		mvwaddch(win, ocury + i, ocurx, ch);
    174       1.1     blymn 
    175      1.11     blymn 	wmove(win, ocury, ocurx);
    176       1.1     blymn 	return OK;
    177       1.6  drochner #else
    178      1.16       uwe 	cchar_t cch;
    179       1.6  drochner 
    180      1.16       uwe 	__cursesi_chtype_to_cchar(ch, &cch);
    181      1.16       uwe 	return wvline_set(win, &cch, count);
    182       1.6  drochner #endif
    183       1.1     blymn }
    184       1.5     blymn 
    185       1.5     blymn int hline_set(const cchar_t *wch, int n)
    186       1.5     blymn {
    187       1.5     blymn #ifndef HAVE_WCHAR
    188       1.5     blymn 	return ERR;
    189       1.5     blymn #else
    190       1.5     blymn 	return whline_set( stdscr, wch, n );
    191       1.5     blymn #endif /* HAVE_WCHAR */
    192       1.5     blymn }
    193       1.5     blymn 
    194       1.5     blymn int mvhline_set(int y, int x, const cchar_t *wch, int n)
    195       1.5     blymn {
    196       1.5     blymn #ifndef HAVE_WCHAR
    197       1.5     blymn 	return ERR;
    198       1.5     blymn #else
    199       1.5     blymn 	return mvwhline_set( stdscr, y, x, wch, n );
    200       1.5     blymn #endif /* HAVE_WCHAR */
    201       1.5     blymn }
    202       1.5     blymn 
    203       1.5     blymn int mvwhline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n)
    204       1.5     blymn {
    205       1.5     blymn #ifndef HAVE_WCHAR
    206       1.5     blymn 	return ERR;
    207       1.5     blymn #else
    208      1.11     blymn 	if ( wmove( win, y , x ) == ERR )
    209       1.5     blymn 		return ERR;
    210       1.5     blymn 
    211       1.5     blymn 	return whline_set( win, wch, n );
    212       1.5     blymn #endif /* HAVE_WCHAR */
    213       1.5     blymn }
    214       1.5     blymn 
    215       1.5     blymn int whline_set(WINDOW *win, const cchar_t *wch, int n)
    216       1.5     blymn {
    217       1.5     blymn #ifndef HAVE_WCHAR
    218       1.5     blymn 	return ERR;
    219       1.5     blymn #else
    220      1.12       uwe 	int ocury, ocurx, wcn, i, cw;
    221       1.5     blymn 	cchar_t cc;
    222       1.5     blymn 
    223  1.17.4.1  perseant 	if (__predict_false(win == NULL))
    224  1.17.4.1  perseant 		return ERR;
    225  1.17.4.1  perseant 
    226      1.16       uwe 	cc = *wch;
    227      1.16       uwe 	if (!cc.vals[0]) {
    228      1.16       uwe 		cc.vals[0] = WACS_HLINE->vals[0];
    229      1.16       uwe 		cc.attributes |= WACS_HLINE->attributes;
    230      1.16       uwe 	}
    231      1.16       uwe 
    232      1.16       uwe 	cw = wcwidth(cc.vals[0]);
    233      1.16       uwe 	if (cw <= 0)
    234       1.6  drochner 		cw = 1;
    235       1.5     blymn 	if ( ( win->maxx - win->curx ) < cw )
    236       1.5     blymn 		return ERR;
    237       1.5     blymn 	wcn = min( n, ( win->maxx - win->curx ) / cw );
    238       1.5     blymn 	__CTRACE(__CTRACE_LINE, "whline_set: line of %d\n", wcn);
    239      1.12       uwe 	ocury = win->cury;
    240       1.5     blymn 	ocurx = win->curx;
    241       1.5     blymn 
    242       1.5     blymn 	for (i = 0; i < wcn; i++ ) {
    243       1.5     blymn 		__CTRACE(__CTRACE_LINE, "whline_set: (%d,%d)\n",
    244      1.12       uwe 		   ocury, ocurx + i * cw);
    245      1.12       uwe 		mvwadd_wch(win, ocury, ocurx + i * cw, &cc);
    246       1.5     blymn 	}
    247       1.7       roy 
    248      1.12       uwe 	wmove(win, ocury, ocurx);
    249       1.8       roy 	__sync(win);
    250       1.5     blymn 	return OK;
    251       1.5     blymn #endif /* HAVE_WCHAR */
    252       1.5     blymn }
    253       1.5     blymn 
    254       1.5     blymn int vline_set(const cchar_t *wch, int n)
    255       1.5     blymn {
    256       1.5     blymn #ifndef HAVE_WCHAR
    257       1.5     blymn 	return ERR;
    258       1.5     blymn #else
    259       1.9       roy 	return wvline_set(stdscr, wch, n);
    260       1.5     blymn #endif /* HAVE_WCHAR */
    261       1.5     blymn }
    262       1.5     blymn 
    263       1.5     blymn int mvvline_set(int y, int x, const cchar_t *wch, int n)
    264       1.5     blymn {
    265       1.5     blymn #ifndef HAVE_WCHAR
    266       1.5     blymn 	return ERR;
    267       1.5     blymn #else
    268       1.9       roy 	return mvwvline_set(stdscr, y, x, wch, n);
    269       1.5     blymn #endif /* HAVE_WCHAR */
    270       1.5     blymn }
    271       1.5     blymn 
    272       1.5     blymn int mvwvline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n)
    273       1.5     blymn {
    274       1.5     blymn #ifndef HAVE_WCHAR
    275       1.5     blymn 	return ERR;
    276       1.5     blymn #else
    277      1.11     blymn 	if (wmove(win, y, x) == ERR)
    278       1.5     blymn 		return ERR;
    279       1.5     blymn 
    280       1.9       roy 	return wvline_set(win, wch, n);
    281       1.5     blymn #endif /* HAVE_WCHAR */
    282       1.5     blymn }
    283       1.5     blymn 
    284       1.5     blymn int wvline_set(WINDOW *win, const cchar_t *wch, int n)
    285       1.5     blymn {
    286       1.5     blymn #ifndef HAVE_WCHAR
    287       1.5     blymn 	return ERR;
    288       1.5     blymn #else
    289       1.5     blymn 	int ocury, ocurx, wcn, i;
    290       1.5     blymn 	cchar_t cc;
    291       1.5     blymn 
    292  1.17.4.1  perseant 	if (__predict_false(win == NULL))
    293  1.17.4.1  perseant 		return ERR;
    294  1.17.4.1  perseant 
    295       1.9       roy 	wcn = min(n, win->maxy - win->cury);
    296       1.5     blymn 	__CTRACE(__CTRACE_LINE, "wvline_set: line of %d\n", wcn);
    297       1.5     blymn 	ocury = win->cury;
    298       1.5     blymn 	ocurx = win->curx;
    299       1.5     blymn 
    300      1.16       uwe 	cc = *wch;
    301      1.16       uwe 	if (!cc.vals[0]) {
    302      1.16       uwe 		cc.vals[0] = WACS_VLINE->vals[0];
    303      1.16       uwe 		cc.attributes |= WACS_VLINE->attributes;
    304      1.16       uwe 	}
    305       1.5     blymn 	for (i = 0; i < wcn; i++) {
    306       1.5     blymn 		mvwadd_wch(win, ocury + i, ocurx, &cc);
    307       1.5     blymn 		__CTRACE(__CTRACE_LINE, "wvline_set: (%d,%d)\n",
    308       1.5     blymn 		    ocury + i, ocurx);
    309       1.5     blymn 	}
    310       1.8       roy 
    311      1.11     blymn 	wmove(win, ocury, ocurx);
    312       1.8       roy 	__sync(win);
    313       1.5     blymn 	return OK;
    314       1.5     blymn #endif /* HAVE_WCHAR */
    315       1.5     blymn }
    316