1*0c3ae37fSLionel Sambuc /* $NetBSD: acs.c,v 1.20 2012/04/21 12:27:27 roy Exp $ */
251ffecc1SBen Gras
351ffecc1SBen Gras /*
451ffecc1SBen Gras * Copyright (c) 2000 The NetBSD Foundation, Inc.
551ffecc1SBen Gras * All rights reserved.
651ffecc1SBen Gras *
751ffecc1SBen Gras * This code is derived from software contributed to The NetBSD Foundation
851ffecc1SBen Gras * by Julian Coleman.
951ffecc1SBen Gras *
1051ffecc1SBen Gras * Redistribution and use in source and binary forms, with or without
1151ffecc1SBen Gras * modification, are permitted provided that the following conditions
1251ffecc1SBen Gras * are met:
1351ffecc1SBen Gras * 1. Redistributions of source code must retain the above copyright
1451ffecc1SBen Gras * notice, this list of conditions and the following disclaimer.
1551ffecc1SBen Gras * 2. Redistributions in binary form must reproduce the above copyright
1651ffecc1SBen Gras * notice, this list of conditions and the following disclaimer in the
1751ffecc1SBen Gras * documentation and/or other materials provided with the distribution.
1851ffecc1SBen Gras *
1951ffecc1SBen Gras * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2051ffecc1SBen Gras * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2151ffecc1SBen Gras * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2251ffecc1SBen Gras * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2351ffecc1SBen Gras * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2451ffecc1SBen Gras * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2551ffecc1SBen Gras * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2651ffecc1SBen Gras * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2751ffecc1SBen Gras * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2851ffecc1SBen Gras * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2951ffecc1SBen Gras * POSSIBILITY OF SUCH DAMAGE.
3051ffecc1SBen Gras */
3151ffecc1SBen Gras
3251ffecc1SBen Gras #include <sys/cdefs.h>
3351ffecc1SBen Gras #ifndef lint
34*0c3ae37fSLionel Sambuc __RCSID("$NetBSD: acs.c,v 1.20 2012/04/21 12:27:27 roy Exp $");
3551ffecc1SBen Gras #endif /* not lint */
3651ffecc1SBen Gras
3751ffecc1SBen Gras #include "curses.h"
3851ffecc1SBen Gras #include "curses_private.h"
3951ffecc1SBen Gras
4051ffecc1SBen Gras chtype _acs_char[NUM_ACS];
4151ffecc1SBen Gras #ifdef HAVE_WCHAR
4251ffecc1SBen Gras #include <assert.h>
4351ffecc1SBen Gras #include <locale.h>
4451ffecc1SBen Gras #include <langinfo.h>
4551ffecc1SBen Gras #include <strings.h>
4651ffecc1SBen Gras
4751ffecc1SBen Gras cchar_t _wacs_char[ NUM_ACS ];
4851ffecc1SBen Gras #endif /* HAVE_WCHAR */
4951ffecc1SBen Gras
5051ffecc1SBen Gras /*
5151ffecc1SBen Gras * __init_acs --
52*0c3ae37fSLionel Sambuc * Fill in the ACS characters. The 'acs_chars' terminfo entry is a list of
5351ffecc1SBen Gras * character pairs - ACS definition then terminal representation.
5451ffecc1SBen Gras */
5551ffecc1SBen Gras void
__init_acs(SCREEN * screen)5651ffecc1SBen Gras __init_acs(SCREEN *screen)
5751ffecc1SBen Gras {
5851ffecc1SBen Gras int count;
5951ffecc1SBen Gras const char *aofac; /* Address of 'ac' */
6051ffecc1SBen Gras unsigned char acs, term;
6151ffecc1SBen Gras
6251ffecc1SBen Gras /* Default value '+' for all ACS characters */
6351ffecc1SBen Gras for (count=0; count < NUM_ACS; count++)
6451ffecc1SBen Gras _acs_char[count]= '+';
6551ffecc1SBen Gras
6651ffecc1SBen Gras /* Add the SUSv2 defaults (those that are not '+') */
6751ffecc1SBen Gras ACS_RARROW = '>';
6851ffecc1SBen Gras ACS_LARROW = '<';
6951ffecc1SBen Gras ACS_UARROW = '^';
7051ffecc1SBen Gras ACS_DARROW = 'v';
7151ffecc1SBen Gras ACS_BLOCK = '#';
7251ffecc1SBen Gras /* ACS_DIAMOND = '+'; */
7351ffecc1SBen Gras ACS_CKBOARD = ':';
7451ffecc1SBen Gras ACS_DEGREE = 39; /* ' */
7551ffecc1SBen Gras ACS_PLMINUS = '#';
7651ffecc1SBen Gras ACS_BOARD = '#';
7751ffecc1SBen Gras ACS_LANTERN = '#';
7851ffecc1SBen Gras /* ACS_LRCORNER = '+'; */
7951ffecc1SBen Gras /* ACS_URCORNER = '+'; */
8051ffecc1SBen Gras /* ACS_ULCORNER = '+'; */
8151ffecc1SBen Gras /* ACS_LLCORNER = '+'; */
8251ffecc1SBen Gras /* ACS_PLUS = '+'; */
8351ffecc1SBen Gras ACS_HLINE = '-';
8451ffecc1SBen Gras ACS_S1 = '-';
8551ffecc1SBen Gras ACS_S9 = '_';
8651ffecc1SBen Gras /* ACS_LTEE = '+'; */
8751ffecc1SBen Gras /* ACS_RTEE = '+'; */
8851ffecc1SBen Gras /* ACS_BTEE = '+'; */
8951ffecc1SBen Gras /* ACS_TTEE = '+'; */
9051ffecc1SBen Gras ACS_VLINE = '|';
9151ffecc1SBen Gras ACS_BULLET = 'o';
9251ffecc1SBen Gras /* Add the extensions defaults */
9351ffecc1SBen Gras ACS_S3 = '-';
9451ffecc1SBen Gras ACS_S7 = '-';
9551ffecc1SBen Gras ACS_LEQUAL = '<';
9651ffecc1SBen Gras ACS_GEQUAL = '>';
9751ffecc1SBen Gras ACS_PI = '*';
9851ffecc1SBen Gras ACS_NEQUAL = '!';
9951ffecc1SBen Gras ACS_STERLING = 'f';
10051ffecc1SBen Gras
10151ffecc1SBen Gras if (t_acs_chars(screen->term) == NULL)
10251ffecc1SBen Gras goto out;
10351ffecc1SBen Gras
10451ffecc1SBen Gras aofac = t_acs_chars(screen->term);
10551ffecc1SBen Gras
10651ffecc1SBen Gras while (*aofac != '\0') {
10751ffecc1SBen Gras if ((acs = *aofac) == '\0')
10851ffecc1SBen Gras return;
10951ffecc1SBen Gras if ((term = *++aofac) == '\0')
11051ffecc1SBen Gras return;
11151ffecc1SBen Gras /* Only add characters 1 to 127 */
11251ffecc1SBen Gras if (acs < NUM_ACS)
11351ffecc1SBen Gras _acs_char[acs] = term | __ALTCHARSET;
11451ffecc1SBen Gras aofac++;
11551ffecc1SBen Gras #ifdef DEBUG
11651ffecc1SBen Gras __CTRACE(__CTRACE_INIT, "__init_acs: %c = %c\n", acs, term);
11751ffecc1SBen Gras #endif
11851ffecc1SBen Gras }
11951ffecc1SBen Gras
12051ffecc1SBen Gras if (t_ena_acs(screen->term) != NULL)
12151ffecc1SBen Gras ti_puts(screen->term, t_ena_acs(screen->term), 0,
12251ffecc1SBen Gras __cputchar_args, screen->outfd);
12351ffecc1SBen Gras
12451ffecc1SBen Gras out:
12551ffecc1SBen Gras for (count=0; count < NUM_ACS; count++)
12651ffecc1SBen Gras screen->acs_char[count]= _acs_char[count];
12751ffecc1SBen Gras }
12851ffecc1SBen Gras
12951ffecc1SBen Gras void
_cursesi_reset_acs(SCREEN * screen)13051ffecc1SBen Gras _cursesi_reset_acs(SCREEN *screen)
13151ffecc1SBen Gras {
13251ffecc1SBen Gras int count;
13351ffecc1SBen Gras
13451ffecc1SBen Gras for (count=0; count < NUM_ACS; count++)
13551ffecc1SBen Gras _acs_char[count]= screen->acs_char[count];
13651ffecc1SBen Gras }
13751ffecc1SBen Gras
13851ffecc1SBen Gras #ifdef HAVE_WCHAR
13951ffecc1SBen Gras /*
14051ffecc1SBen Gras * __init_wacs --
141*0c3ae37fSLionel Sambuc * Fill in the ACS characters. The 'acs_chars' terminfo entry is a list of
14251ffecc1SBen Gras * character pairs - ACS definition then terminal representation.
14351ffecc1SBen Gras */
14451ffecc1SBen Gras void
__init_wacs(SCREEN * screen)14551ffecc1SBen Gras __init_wacs(SCREEN *screen)
14651ffecc1SBen Gras {
14751ffecc1SBen Gras int count;
14851ffecc1SBen Gras const char *aofac; /* Address of 'ac' */
14951ffecc1SBen Gras unsigned char acs, term;
15051ffecc1SBen Gras char *lstr;
15151ffecc1SBen Gras
15251ffecc1SBen Gras /* Default value '+' for all ACS characters */
15351ffecc1SBen Gras for (count=0; count < NUM_ACS; count++) {
15451ffecc1SBen Gras _wacs_char[ count ].vals[ 0 ] = ( wchar_t )btowc( '+' );
15551ffecc1SBen Gras _wacs_char[ count ].attributes = 0;
15651ffecc1SBen Gras _wacs_char[ count ].elements = 1;
15751ffecc1SBen Gras }
15851ffecc1SBen Gras
15951ffecc1SBen Gras /* Add the SUSv2 defaults (those that are not '+') */
16051ffecc1SBen Gras if (!strcmp(setlocale(LC_CTYPE, NULL), "C"))
16151ffecc1SBen Gras setlocale(LC_CTYPE, "");
16251ffecc1SBen Gras lstr = nl_langinfo(CODESET);
16351ffecc1SBen Gras _DIAGASSERT(lstr);
16451ffecc1SBen Gras if (strcasecmp(lstr, "UTF-8")) {
16551ffecc1SBen Gras #ifdef DEBUG
16651ffecc1SBen Gras __CTRACE(__CTRACE_INIT, "__init_wacs: setting defaults\n" );
16751ffecc1SBen Gras #endif /* DEBUG */
16851ffecc1SBen Gras WACS_RARROW->vals[0] = ( wchar_t )btowc( '>' );
16951ffecc1SBen Gras WACS_LARROW->vals[0] = ( wchar_t )btowc( '<' );
17051ffecc1SBen Gras WACS_UARROW->vals[0] = ( wchar_t )btowc( '^' );
17151ffecc1SBen Gras WACS_DARROW->vals[0] = ( wchar_t )btowc( 'v' );
17251ffecc1SBen Gras WACS_BLOCK->vals[0] = ( wchar_t )btowc( '#' );
17351ffecc1SBen Gras WACS_CKBOARD->vals[0] = ( wchar_t )btowc( ':' );
17451ffecc1SBen Gras WACS_DEGREE->vals[0] = ( wchar_t )btowc( 39 ); /* ' */
17551ffecc1SBen Gras WACS_PLMINUS->vals[0] = ( wchar_t )btowc( '#' );
17651ffecc1SBen Gras WACS_BOARD->vals[0] = ( wchar_t )btowc( '#' );
17751ffecc1SBen Gras WACS_LANTERN->vals[0] = ( wchar_t )btowc( '#' );
17851ffecc1SBen Gras WACS_HLINE->vals[0] = ( wchar_t )btowc( '-' );
17951ffecc1SBen Gras WACS_S1->vals[0] = ( wchar_t )btowc( '-' );
18051ffecc1SBen Gras WACS_S9->vals[0] = ( wchar_t )btowc( '_' );
18151ffecc1SBen Gras WACS_VLINE->vals[0] = ( wchar_t )btowc( '|' );
18251ffecc1SBen Gras WACS_BULLET->vals[0] = ( wchar_t )btowc( 'o' );
18351ffecc1SBen Gras WACS_S3->vals[0] = ( wchar_t )btowc( 'p' );
18451ffecc1SBen Gras WACS_S7->vals[0] = ( wchar_t )btowc( 'r' );
18551ffecc1SBen Gras WACS_LEQUAL->vals[0] = ( wchar_t )btowc( 'y' );
18651ffecc1SBen Gras WACS_GEQUAL->vals[0] = ( wchar_t )btowc( 'z' );
18751ffecc1SBen Gras WACS_PI->vals[0] = ( wchar_t )btowc( '{' );
18851ffecc1SBen Gras WACS_NEQUAL->vals[0] = ( wchar_t )btowc( '|' );
18951ffecc1SBen Gras WACS_STERLING->vals[0]= ( wchar_t )btowc( '}' );
19051ffecc1SBen Gras } else {
19151ffecc1SBen Gras /* Unicode defaults */
19251ffecc1SBen Gras #ifdef DEBUG
19351ffecc1SBen Gras __CTRACE(__CTRACE_INIT,
19451ffecc1SBen Gras "__init_wacs: setting Unicode defaults\n" );
19551ffecc1SBen Gras #endif /* DEBUG */
19651ffecc1SBen Gras WACS_RARROW->vals[0] = 0x2192;
19751ffecc1SBen Gras ACS_RARROW = '+' | __ACS_IS_WACS;
19851ffecc1SBen Gras WACS_LARROW->vals[0] = 0x2190;
19951ffecc1SBen Gras ACS_LARROW = ',' | __ACS_IS_WACS;
20051ffecc1SBen Gras WACS_UARROW->vals[0] = 0x2191;
20151ffecc1SBen Gras ACS_UARROW = '-' | __ACS_IS_WACS;
20251ffecc1SBen Gras WACS_DARROW->vals[0] = 0x2193;
20351ffecc1SBen Gras ACS_DARROW = '.' | __ACS_IS_WACS;
20451ffecc1SBen Gras WACS_BLOCK->vals[0] = 0x25ae;
20551ffecc1SBen Gras ACS_BLOCK = '0' | __ACS_IS_WACS;
20651ffecc1SBen Gras WACS_DIAMOND->vals[0] = 0x25c6;
20751ffecc1SBen Gras ACS_DIAMOND = '`' | __ACS_IS_WACS;
20851ffecc1SBen Gras WACS_CKBOARD->vals[0] = 0x2592;
20951ffecc1SBen Gras ACS_CKBOARD = 'a' | __ACS_IS_WACS;
21051ffecc1SBen Gras WACS_DEGREE->vals[0] = 0x00b0;
21151ffecc1SBen Gras ACS_DEGREE = 'f' | __ACS_IS_WACS;
21251ffecc1SBen Gras WACS_PLMINUS->vals[0] = 0x00b1;
21351ffecc1SBen Gras ACS_PLMINUS = 'g' | __ACS_IS_WACS;
21451ffecc1SBen Gras WACS_BOARD->vals[0] = 0x2592;
21551ffecc1SBen Gras ACS_BOARD = 'h' | __ACS_IS_WACS;
21651ffecc1SBen Gras WACS_LANTERN->vals[0] = 0x2603;
21751ffecc1SBen Gras ACS_LANTERN = 'i' | __ACS_IS_WACS;
21851ffecc1SBen Gras WACS_LRCORNER->vals[0]= 0x2518;
21951ffecc1SBen Gras ACS_LRCORNER = 'j' | __ACS_IS_WACS;
22051ffecc1SBen Gras WACS_URCORNER->vals[0]= 0x2510;
22151ffecc1SBen Gras ACS_URCORNER = 'k' | __ACS_IS_WACS;
22251ffecc1SBen Gras WACS_ULCORNER->vals[0]= 0x250c;
22351ffecc1SBen Gras ACS_ULCORNER = 'l' | __ACS_IS_WACS;
22451ffecc1SBen Gras WACS_LLCORNER->vals[0]= 0x2514;
22551ffecc1SBen Gras ACS_LLCORNER = 'm' | __ACS_IS_WACS;
22651ffecc1SBen Gras WACS_PLUS->vals[0] = 0x253c;
22751ffecc1SBen Gras ACS_PLUS = 'n' | __ACS_IS_WACS;
22851ffecc1SBen Gras WACS_HLINE->vals[0] = 0x2500;
22951ffecc1SBen Gras ACS_HLINE = 'q' | __ACS_IS_WACS;
23051ffecc1SBen Gras WACS_S1->vals[0] = 0x23ba;
23151ffecc1SBen Gras ACS_S1 = 'o' | __ACS_IS_WACS;
23251ffecc1SBen Gras WACS_S9->vals[0] = 0x23bd;
23351ffecc1SBen Gras ACS_S9 = 's' | __ACS_IS_WACS;
23451ffecc1SBen Gras WACS_LTEE->vals[0] = 0x251c;
23551ffecc1SBen Gras ACS_LTEE = 't' | __ACS_IS_WACS;
23651ffecc1SBen Gras WACS_RTEE->vals[0] = 0x2524;
23751ffecc1SBen Gras ACS_RTEE = 'u' | __ACS_IS_WACS;
23851ffecc1SBen Gras WACS_BTEE->vals[0] = 0x2534;
23951ffecc1SBen Gras ACS_BTEE = 'v' | __ACS_IS_WACS;
24051ffecc1SBen Gras WACS_TTEE->vals[0] = 0x252c;
24151ffecc1SBen Gras ACS_TTEE = 'w' | __ACS_IS_WACS;
24251ffecc1SBen Gras WACS_VLINE->vals[0] = 0x2502;
24351ffecc1SBen Gras ACS_VLINE = 'x' | __ACS_IS_WACS;
24451ffecc1SBen Gras WACS_BULLET->vals[0] = 0x00b7;
24551ffecc1SBen Gras ACS_BULLET = '~' | __ACS_IS_WACS;
24651ffecc1SBen Gras WACS_S3->vals[0] = 0x23bb;
24751ffecc1SBen Gras ACS_S3 = 'p' | __ACS_IS_WACS;
24851ffecc1SBen Gras WACS_S7->vals[0] = 0x23bc;
24951ffecc1SBen Gras ACS_S7 = 'r' | __ACS_IS_WACS;
25051ffecc1SBen Gras WACS_LEQUAL->vals[0] = 0x2264;
25151ffecc1SBen Gras ACS_LEQUAL = 'y' | __ACS_IS_WACS;
25251ffecc1SBen Gras WACS_GEQUAL->vals[0] = 0x2265;
25351ffecc1SBen Gras ACS_GEQUAL = 'z' | __ACS_IS_WACS;
25451ffecc1SBen Gras WACS_PI->vals[0] = 0x03C0;
25551ffecc1SBen Gras ACS_PI = '{' | __ACS_IS_WACS;
25651ffecc1SBen Gras WACS_NEQUAL->vals[0] = 0x2260;
25751ffecc1SBen Gras ACS_NEQUAL = '|' | __ACS_IS_WACS;
25851ffecc1SBen Gras WACS_STERLING->vals[0]= 0x00A3;
25951ffecc1SBen Gras ACS_STERLING = '}' | __ACS_IS_WACS;
26051ffecc1SBen Gras }
26151ffecc1SBen Gras
26251ffecc1SBen Gras if (t_acs_chars(screen->term) == NULL) {
26351ffecc1SBen Gras #ifdef DEBUG
26451ffecc1SBen Gras __CTRACE(__CTRACE_INIT,
26551ffecc1SBen Gras "__init_wacs: no alternative characters\n" );
26651ffecc1SBen Gras #endif /* DEBUG */
26751ffecc1SBen Gras goto out;
26851ffecc1SBen Gras }
26951ffecc1SBen Gras
27051ffecc1SBen Gras aofac = t_acs_chars(screen->term);
27151ffecc1SBen Gras
27251ffecc1SBen Gras while (*aofac != '\0') {
27351ffecc1SBen Gras if ((acs = *aofac) == '\0')
27451ffecc1SBen Gras return;
27551ffecc1SBen Gras if ((term = *++aofac) == '\0')
27651ffecc1SBen Gras return;
27751ffecc1SBen Gras /* Only add characters 1 to 127 */
27851ffecc1SBen Gras if (acs < NUM_ACS) {
27951ffecc1SBen Gras _wacs_char[acs].vals[ 0 ] = term;
28051ffecc1SBen Gras _wacs_char[acs].attributes |= WA_ALTCHARSET;
28151ffecc1SBen Gras }
28251ffecc1SBen Gras aofac++;
28351ffecc1SBen Gras #ifdef DEBUG
28451ffecc1SBen Gras __CTRACE(__CTRACE_INIT, "__init_wacs: %c = %c\n", acs, term);
28551ffecc1SBen Gras #endif
28651ffecc1SBen Gras }
28751ffecc1SBen Gras
28851ffecc1SBen Gras if (t_ena_acs(screen->term) != NULL)
28951ffecc1SBen Gras ti_puts(screen->term, t_ena_acs(screen->term), 0,
29051ffecc1SBen Gras __cputchar_args, screen->outfd);
29151ffecc1SBen Gras
29251ffecc1SBen Gras out:
29351ffecc1SBen Gras for (count=0; count < NUM_ACS; count++) {
29451ffecc1SBen Gras memcpy(&screen->wacs_char[count], &_wacs_char[count],
29551ffecc1SBen Gras sizeof(cchar_t));
29651ffecc1SBen Gras screen->acs_char[count]= _acs_char[count];
29751ffecc1SBen Gras }
29851ffecc1SBen Gras }
29951ffecc1SBen Gras
30051ffecc1SBen Gras void
_cursesi_reset_wacs(SCREEN * screen)30151ffecc1SBen Gras _cursesi_reset_wacs(SCREEN *screen)
30251ffecc1SBen Gras {
30351ffecc1SBen Gras int count;
30451ffecc1SBen Gras
30551ffecc1SBen Gras for (count=0; count < NUM_ACS; count++)
30651ffecc1SBen Gras memcpy( &_wacs_char[count], &screen->wacs_char[count],
30751ffecc1SBen Gras sizeof( cchar_t ));
30851ffecc1SBen Gras }
30951ffecc1SBen Gras #endif /* HAVE_WCHAR */
310