Home | History | Annotate | Line # | Download | only in libcurses
line.c revision 1.19
      1  1.19     blymn /*	$NetBSD: line.c,v 1.19 2024/12/23 02:58:03 blymn 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.19     blymn __RCSID("$NetBSD: line.c,v 1.19 2024/12/23 02:58:03 blymn 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.19     blymn 	if (__predict_false(win == NULL))
     91  1.19     blymn 		return ERR;
     92  1.19     blymn 
     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.18    rillig  *	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.19     blymn 	if (__predict_false(win == NULL))
    164  1.19     blymn 		return ERR;
    165  1.19     blymn 
    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.19     blymn 	if (__predict_false(win == NULL))
    224  1.19     blymn 		return ERR;
    225  1.19     blymn 
    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.19     blymn 	if (__predict_false(win == NULL))
    293  1.19     blymn 		return ERR;
    294  1.19     blymn 
    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