197049Speter/****************************************************************************
2174993Srafan * Copyright (c) 2001-2005,2007 Free Software Foundation, Inc.              *
397049Speter *                                                                          *
497049Speter * Permission is hereby granted, free of charge, to any person obtaining a  *
597049Speter * copy of this software and associated documentation files (the            *
697049Speter * "Software"), to deal in the Software without restriction, including      *
797049Speter * without limitation the rights to use, copy, modify, merge, publish,      *
897049Speter * distribute, distribute with modifications, sublicense, and/or sell       *
997049Speter * copies of the Software, and to permit persons to whom the Software is    *
1097049Speter * furnished to do so, subject to the following conditions:                 *
1197049Speter *                                                                          *
1297049Speter * The above copyright notice and this permission notice shall be included  *
1397049Speter * in all copies or substantial portions of the Software.                   *
1497049Speter *                                                                          *
1597049Speter * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
1697049Speter * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
1797049Speter * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
1897049Speter * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
1997049Speter * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
2097049Speter * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
2197049Speter * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
2297049Speter *                                                                          *
2397049Speter * Except as contained in this notice, the name(s) of the above copyright   *
2497049Speter * holders shall not be used in advertising or otherwise to promote the     *
2597049Speter * sale, use or other dealings in this Software without prior written       *
2697049Speter * authorization.                                                           *
2797049Speter ****************************************************************************/
2897049Speter
2997049Speter/*
3097049Speter**	lib_cchar.c
3197049Speter**
3297049Speter**	The routines setcchar() and getcchar().
3397049Speter**
3497049Speter*/
3597049Speter
3697049Speter#include <curses.priv.h>
3797049Speter
38174993SrafanMODULE_ID("$Id: lib_cchar.c,v 1.12 2007/05/12 19:03:06 tom Exp $")
3997049Speter
4097049Speter/*
4197049Speter * The SuSv2 description leaves some room for interpretation.  We'll assume wch
42166124Srafan * points to a string which is L'\0' terminated, contains at least one
43166124Srafan * character with strictly positive width, which must be the first, and
44166124Srafan * contains no characters of negative width.
4597049Speter */
4697049SpeterNCURSES_EXPORT(int)
47166124Srafansetcchar(cchar_t *wcval,
48166124Srafan	 const wchar_t *wch,
49166124Srafan	 const attr_t attrs,
50166124Srafan	 short color_pair,
51166124Srafan	 const void *opts)
5297049Speter{
5397049Speter    int i;
5497049Speter    int len;
5597049Speter    int code = OK;
5697049Speter
57174993Srafan    TR(TRACE_CCALLS, (T_CALLED("setcchar(%p,%s,%lu,%d,%p)"),
58174993Srafan		      wcval, _nc_viswbuf(wch),
59174993Srafan		      (unsigned long) attrs, color_pair, opts));
6097049Speter
61166124Srafan    len = wcslen(wch);
62166124Srafan    if (opts != NULL
63166124Srafan	|| (len > 1 && wcwidth(wch[0]) < 0)) {
6497049Speter	code = ERR;
6597049Speter    } else {
66166124Srafan	if (len > CCHARW_MAX)
67166124Srafan	    len = CCHARW_MAX;
6897049Speter
69166124Srafan	/*
70166124Srafan	 * If we have a following spacing-character, stop at that point.  We
71166124Srafan	 * are only interested in adding non-spacing characters.
72166124Srafan	 */
7397049Speter	for (i = 1; i < len; ++i) {
7497049Speter	    if (wcwidth(wch[i]) != 0) {
75166124Srafan		len = i;
7697049Speter		break;
7797049Speter	    }
7897049Speter	}
7997049Speter
80166124Srafan	memset(wcval, 0, sizeof(*wcval));
8197049Speter
82166124Srafan	if (len != 0) {
83166124Srafan	    SetAttr(*wcval, attrs | COLOR_PAIR(color_pair));
84166124Srafan	    SetPair(CHDEREF(wcval), color_pair);
85166124Srafan	    memcpy(&wcval->chars, wch, len * sizeof(wchar_t));
86166124Srafan	    TR(TRACE_CCALLS, ("copy %d wchars, first is %s", len,
87166124Srafan			      _tracecchar_t(wcval)));
8897049Speter	}
8997049Speter    }
9097049Speter
9197049Speter    TR(TRACE_CCALLS, (T_RETURN("%d"), code));
9297049Speter    return (code);
9397049Speter}
9497049Speter
9597049SpeterNCURSES_EXPORT(int)
96166124Srafangetcchar(const cchar_t *wcval,
97166124Srafan	 wchar_t *wch,
98166124Srafan	 attr_t *attrs,
99166124Srafan	 short *color_pair,
100166124Srafan	 void *opts)
10197049Speter{
10297049Speter    wchar_t *wp;
10397049Speter    int len;
10497049Speter    int code = ERR;
10597049Speter
10697049Speter    TR(TRACE_CCALLS, (T_CALLED("getcchar(%p,%p,%p,%p,%p)"),
10797049Speter		      wcval, wch, attrs, color_pair, opts));
10897049Speter
10997049Speter    if (opts == NULL) {
11097049Speter	len = (wp = wmemchr(wcval->chars, L'\0', CCHARW_MAX))
11197049Speter	    ? wp - wcval->chars
11297049Speter	    : CCHARW_MAX;
11397049Speter
11497049Speter	if (wch == NULL) {
11597049Speter	    code = len;
116166124Srafan	} else if (attrs == 0 || color_pair == 0) {
117166124Srafan	    code = ERR;
11897049Speter	} else if (len >= 0) {
11997049Speter	    *attrs = AttrOf(*wcval) & A_ATTRIBUTES;
120166124Srafan	    *color_pair = GetPair(*wcval);
12197049Speter	    wmemcpy(wch, wcval->chars, (unsigned) len);
12297049Speter	    wch[len] = L'\0';
12397049Speter	    code = OK;
12497049Speter	}
12597049Speter    }
12697049Speter
12797049Speter    TR(TRACE_CCALLS, (T_RETURN("%d"), code));
12897049Speter    return (code);
12997049Speter}
130