Home | History | Annotate | Line # | Download | only in libcurses
line.c revision 1.16
      1  1.16       uwe /*	$NetBSD: line.c,v 1.16 2020/07/01 02:57:01 uwe 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.16       uwe __RCSID("$NetBSD: line.c,v 1.16 2020/07/01 02:57:01 uwe 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.13       uwe 	int ocury, ocurx, n, i;
     91   1.1     blymn 
     92   1.1     blymn 	n = min(count, win->maxx - win->curx);
     93  1.15       uwe 	ocury = win->cury;
     94   1.1     blymn 	ocurx = win->curx;
     95   1.4     blymn 
     96   1.2       jdc 	if (!(ch & __CHARTEXT))
     97   1.2       jdc 		ch |= ACS_HLINE;
     98   1.1     blymn 	for (i = 0; i < n; i++)
     99  1.13       uwe 		mvwaddch(win, ocury, ocurx + i, ch);
    100   1.7       roy 
    101  1.13       uwe 	wmove(win, ocury, ocurx);
    102   1.1     blymn 	return OK;
    103   1.6  drochner #else
    104  1.16       uwe 	cchar_t cch;
    105   1.6  drochner 
    106  1.16       uwe 	__cursesi_chtype_to_cchar(ch, &cch);
    107  1.16       uwe 	return whline_set(win, &cch, count);
    108   1.6  drochner #endif
    109   1.1     blymn }
    110   1.1     blymn 
    111   1.1     blymn /*
    112   1.1     blymn  * vline --
    113   1.5     blymn  *	Draw a vertical line of character ch on stdscr.
    114   1.1     blymn  */
    115   1.1     blymn int
    116   1.1     blymn vline(chtype ch, int count)
    117   1.1     blymn {
    118   1.9       roy 
    119   1.1     blymn 	return wvline(stdscr, ch, count);
    120   1.1     blymn }
    121   1.1     blymn 
    122   1.1     blymn /*
    123   1.1     blymn  * mvvline --
    124   1.5     blymn  *	Move to the given location an draw a vertical line of character ch.
    125   1.1     blymn  */
    126   1.1     blymn int
    127   1.1     blymn mvvline(int y, int x, chtype ch, int count)
    128   1.1     blymn {
    129   1.9       roy 
    130   1.1     blymn 	return mvwvline(stdscr, y, x, ch, count);
    131   1.1     blymn }
    132   1.1     blymn 
    133   1.1     blymn /*
    134   1.1     blymn  * mvwvline --
    135   1.5     blymn  *	Move to the given location and draw a vertical line of character ch
    136   1.5     blymn  *	on the given window.
    137   1.1     blymn  */
    138   1.1     blymn int
    139   1.1     blymn mvwvline(WINDOW *win, int y, int x, chtype ch, int count)
    140   1.1     blymn {
    141   1.9       roy 
    142  1.11     blymn 	if (wmove(win, y, x) == ERR)
    143   1.1     blymn 		return ERR;
    144   1.1     blymn 
    145   1.1     blymn 	return wvline(win, ch, count);
    146   1.1     blymn }
    147   1.1     blymn 
    148   1.1     blymn /*
    149   1.1     blymn  * wvline --
    150   1.5     blymn  *	Draw a vertical line of character ch in the given window moving
    151   1.5     blymn  *	towards the bottom of the screen.  At most count characters are drawn
    152   1.5     blymn  *	or until the edge of the screen, whichever comes first.
    153   1.1     blymn  */
    154   1.1     blymn int
    155   1.1     blymn wvline(WINDOW *win, chtype ch, int count)
    156   1.1     blymn {
    157   1.6  drochner #ifndef HAVE_WCHAR
    158   1.1     blymn 	int ocury, ocurx, n, i;
    159   1.1     blymn 
    160   1.1     blymn 	n = min(count, win->maxy - win->cury);
    161   1.1     blymn 	ocury = win->cury;
    162   1.1     blymn 	ocurx = win->curx;
    163   1.1     blymn 
    164   1.2       jdc 	if (!(ch & __CHARTEXT))
    165   1.2       jdc 		ch |= ACS_VLINE;
    166   1.1     blymn 	for (i = 0; i < n; i++)
    167   1.1     blymn 		mvwaddch(win, ocury + i, ocurx, ch);
    168   1.1     blymn 
    169  1.11     blymn 	wmove(win, ocury, ocurx);
    170   1.1     blymn 	return OK;
    171   1.6  drochner #else
    172  1.16       uwe 	cchar_t cch;
    173   1.6  drochner 
    174  1.16       uwe 	__cursesi_chtype_to_cchar(ch, &cch);
    175  1.16       uwe 	return wvline_set(win, &cch, count);
    176   1.6  drochner #endif
    177   1.1     blymn }
    178   1.5     blymn 
    179   1.5     blymn int hline_set(const cchar_t *wch, int n)
    180   1.5     blymn {
    181   1.5     blymn #ifndef HAVE_WCHAR
    182   1.5     blymn 	return ERR;
    183   1.5     blymn #else
    184   1.5     blymn 	return whline_set( stdscr, wch, n );
    185   1.5     blymn #endif /* HAVE_WCHAR */
    186   1.5     blymn }
    187   1.5     blymn 
    188   1.5     blymn int mvhline_set(int y, int x, const cchar_t *wch, int n)
    189   1.5     blymn {
    190   1.5     blymn #ifndef HAVE_WCHAR
    191   1.5     blymn 	return ERR;
    192   1.5     blymn #else
    193   1.5     blymn 	return mvwhline_set( stdscr, y, x, wch, n );
    194   1.5     blymn #endif /* HAVE_WCHAR */
    195   1.5     blymn }
    196   1.5     blymn 
    197   1.5     blymn int mvwhline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n)
    198   1.5     blymn {
    199   1.5     blymn #ifndef HAVE_WCHAR
    200   1.5     blymn 	return ERR;
    201   1.5     blymn #else
    202  1.11     blymn 	if ( wmove( win, y , x ) == ERR )
    203   1.5     blymn 		return ERR;
    204   1.5     blymn 
    205   1.5     blymn 	return whline_set( win, wch, n );
    206   1.5     blymn #endif /* HAVE_WCHAR */
    207   1.5     blymn }
    208   1.5     blymn 
    209   1.5     blymn int whline_set(WINDOW *win, const cchar_t *wch, int n)
    210   1.5     blymn {
    211   1.5     blymn #ifndef HAVE_WCHAR
    212   1.5     blymn 	return ERR;
    213   1.5     blymn #else
    214  1.12       uwe 	int ocury, ocurx, wcn, i, cw;
    215   1.5     blymn 	cchar_t cc;
    216   1.5     blymn 
    217  1.16       uwe 	cc = *wch;
    218  1.16       uwe 	if (!cc.vals[0]) {
    219  1.16       uwe 		cc.vals[0] = WACS_HLINE->vals[0];
    220  1.16       uwe 		cc.attributes |= WACS_HLINE->attributes;
    221  1.16       uwe 	}
    222  1.16       uwe 
    223  1.16       uwe 	cw = wcwidth(cc.vals[0]);
    224  1.16       uwe 	if (cw <= 0)
    225   1.6  drochner 		cw = 1;
    226   1.5     blymn 	if ( ( win->maxx - win->curx ) < cw )
    227   1.5     blymn 		return ERR;
    228   1.5     blymn 	wcn = min( n, ( win->maxx - win->curx ) / cw );
    229   1.5     blymn #ifdef DEBUG
    230   1.5     blymn 	__CTRACE(__CTRACE_LINE, "whline_set: line of %d\n", wcn);
    231   1.5     blymn #endif /* DEBUG */
    232  1.12       uwe 	ocury = win->cury;
    233   1.5     blymn 	ocurx = win->curx;
    234   1.5     blymn 
    235   1.5     blymn 	for (i = 0; i < wcn; i++ ) {
    236   1.5     blymn #ifdef DEBUG
    237   1.5     blymn 		__CTRACE(__CTRACE_LINE, "whline_set: (%d,%d)\n",
    238  1.12       uwe 		   ocury, ocurx + i * cw);
    239   1.5     blymn #endif /* DEBUG */
    240  1.12       uwe 		mvwadd_wch(win, ocury, ocurx + i * cw, &cc);
    241   1.5     blymn 	}
    242   1.7       roy 
    243  1.12       uwe 	wmove(win, ocury, ocurx);
    244   1.8       roy 	__sync(win);
    245   1.5     blymn 	return OK;
    246   1.5     blymn #endif /* HAVE_WCHAR */
    247   1.5     blymn }
    248   1.5     blymn 
    249   1.5     blymn int vline_set(const cchar_t *wch, int n)
    250   1.5     blymn {
    251   1.5     blymn #ifndef HAVE_WCHAR
    252   1.5     blymn 	return ERR;
    253   1.5     blymn #else
    254   1.9       roy 	return wvline_set(stdscr, wch, n);
    255   1.5     blymn #endif /* HAVE_WCHAR */
    256   1.5     blymn }
    257   1.5     blymn 
    258   1.5     blymn int mvvline_set(int y, int x, const cchar_t *wch, int n)
    259   1.5     blymn {
    260   1.5     blymn #ifndef HAVE_WCHAR
    261   1.5     blymn 	return ERR;
    262   1.5     blymn #else
    263   1.9       roy 	return mvwvline_set(stdscr, y, x, wch, n);
    264   1.5     blymn #endif /* HAVE_WCHAR */
    265   1.5     blymn }
    266   1.5     blymn 
    267   1.5     blymn int mvwvline_set(WINDOW *win, int y, int x, const cchar_t *wch, int n)
    268   1.5     blymn {
    269   1.5     blymn #ifndef HAVE_WCHAR
    270   1.5     blymn 	return ERR;
    271   1.5     blymn #else
    272  1.11     blymn 	if (wmove(win, y, x) == ERR)
    273   1.5     blymn 		return ERR;
    274   1.5     blymn 
    275   1.9       roy 	return wvline_set(win, wch, n);
    276   1.5     blymn #endif /* HAVE_WCHAR */
    277   1.5     blymn }
    278   1.5     blymn 
    279   1.5     blymn int wvline_set(WINDOW *win, const cchar_t *wch, int n)
    280   1.5     blymn {
    281   1.5     blymn #ifndef HAVE_WCHAR
    282   1.5     blymn 	return ERR;
    283   1.5     blymn #else
    284   1.5     blymn 	int ocury, ocurx, wcn, i;
    285   1.5     blymn 	cchar_t cc;
    286   1.5     blymn 
    287   1.9       roy 	wcn = min(n, win->maxy - win->cury);
    288   1.5     blymn #ifdef DEBUG
    289   1.5     blymn 	__CTRACE(__CTRACE_LINE, "wvline_set: line of %d\n", wcn);
    290   1.5     blymn #endif /* DEBUG */
    291   1.5     blymn 	ocury = win->cury;
    292   1.5     blymn 	ocurx = win->curx;
    293   1.5     blymn 
    294  1.16       uwe 	cc = *wch;
    295  1.16       uwe 	if (!cc.vals[0]) {
    296  1.16       uwe 		cc.vals[0] = WACS_VLINE->vals[0];
    297  1.16       uwe 		cc.attributes |= WACS_VLINE->attributes;
    298  1.16       uwe 	}
    299   1.5     blymn 	for (i = 0; i < wcn; i++) {
    300   1.5     blymn 		mvwadd_wch(win, ocury + i, ocurx, &cc);
    301   1.5     blymn #ifdef DEBUG
    302   1.5     blymn 		__CTRACE(__CTRACE_LINE, "wvline_set: (%d,%d)\n",
    303   1.5     blymn 		    ocury + i, ocurx);
    304   1.5     blymn #endif /* DEBUG */
    305   1.5     blymn 	}
    306   1.8       roy 
    307  1.11     blymn 	wmove(win, ocury, ocurx);
    308   1.8       roy 	__sync(win);
    309   1.5     blymn 	return OK;
    310   1.5     blymn #endif /* HAVE_WCHAR */
    311   1.5     blymn }
    312