1/* $NetBSD: acs.c,v 1.22 2021/09/06 07:03:49 rin Exp $ */ 2 3/* 4 * Copyright (c) 2000 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Julian Coleman. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include <sys/cdefs.h> 33#ifndef lint 34__RCSID("$NetBSD: acs.c,v 1.22 2021/09/06 07:03:49 rin Exp $"); 35#endif /* not lint */ 36 37#include "curses.h" 38#include "curses_private.h" 39 40chtype _acs_char[NUM_ACS]; 41#ifdef HAVE_WCHAR 42#include <assert.h> 43#include <locale.h> 44#include <langinfo.h> 45#include <strings.h> 46 47cchar_t _wacs_char[ NUM_ACS ]; 48#endif /* HAVE_WCHAR */ 49 50/* 51 * __init_acs -- 52 * Fill in the ACS characters. The 'acs_chars' terminfo entry is a list of 53 * character pairs - ACS definition then terminal representation. 54 */ 55void 56__init_acs(SCREEN *screen) 57{ 58 int count; 59 const char *aofac; /* Address of 'ac' */ 60 unsigned char acs, term; 61 62 /* Default value '+' for all ACS characters */ 63 for (count=0; count < NUM_ACS; count++) 64 _acs_char[count]= '+'; 65 66 /* Add the SUSv2 defaults (those that are not '+') */ 67 ACS_RARROW = '>'; 68 ACS_LARROW = '<'; 69 ACS_UARROW = '^'; 70 ACS_DARROW = 'v'; 71 ACS_BLOCK = '#'; 72/* ACS_DIAMOND = '+'; */ 73 ACS_CKBOARD = ':'; 74 ACS_DEGREE = 39; /* ' */ 75 ACS_PLMINUS = '#'; 76 ACS_BOARD = '#'; 77 ACS_LANTERN = '#'; 78/* ACS_LRCORNER = '+'; */ 79/* ACS_URCORNER = '+'; */ 80/* ACS_ULCORNER = '+'; */ 81/* ACS_LLCORNER = '+'; */ 82/* ACS_PLUS = '+'; */ 83 ACS_HLINE = '-'; 84 ACS_S1 = '-'; 85 ACS_S9 = '_'; 86/* ACS_LTEE = '+'; */ 87/* ACS_RTEE = '+'; */ 88/* ACS_BTEE = '+'; */ 89/* ACS_TTEE = '+'; */ 90 ACS_VLINE = '|'; 91 ACS_BULLET = 'o'; 92 /* Add the extensions defaults */ 93 ACS_S3 = '-'; 94 ACS_S7 = '-'; 95 ACS_LEQUAL = '<'; 96 ACS_GEQUAL = '>'; 97 ACS_PI = '*'; 98 ACS_NEQUAL = '!'; 99 ACS_STERLING = 'f'; 100 101 if (t_acs_chars(screen->term) == NULL) 102 goto out; 103 104 aofac = t_acs_chars(screen->term); 105 106 while (*aofac != '\0') { 107 if ((acs = *aofac) == '\0') 108 return; 109 if ((term = *++aofac) == '\0') 110 return; 111 /* Only add characters 1 to 127 */ 112 if (acs < NUM_ACS) 113 _acs_char[acs] = term | __ALTCHARSET; 114 aofac++; 115 __CTRACE(__CTRACE_INIT, "__init_acs: %c = %c\n", acs, term); 116 } 117 118 if (t_ena_acs(screen->term) != NULL) 119 ti_puts(screen->term, t_ena_acs(screen->term), 0, 120 __cputchar_args, screen->outfd); 121 122out: 123 for (count=0; count < NUM_ACS; count++) 124 screen->acs_char[count]= _acs_char[count]; 125} 126 127void 128_cursesi_reset_acs(SCREEN *screen) 129{ 130 int count; 131 132 for (count=0; count < NUM_ACS; count++) 133 _acs_char[count]= screen->acs_char[count]; 134} 135 136#ifdef HAVE_WCHAR 137/* 138 * __init_wacs -- 139 * Fill in the ACS characters. The 'acs_chars' terminfo entry is a list of 140 * character pairs - ACS definition then terminal representation. 141 */ 142void 143__init_wacs(SCREEN *screen) 144{ 145 int count; 146 const char *aofac; /* Address of 'ac' */ 147 unsigned char acs, term; 148 char *lstr; 149 150 /* Default value '+' for all ACS characters */ 151 for (count=0; count < NUM_ACS; count++) { 152 _wacs_char[ count ].vals[ 0 ] = ( wchar_t )btowc( '+' ); 153 _wacs_char[ count ].attributes = 0; 154 _wacs_char[ count ].elements = 1; 155 } 156 157 /* Add the SUSv2 defaults (those that are not '+') */ 158 if (!strcmp(setlocale(LC_CTYPE, NULL), "C")) 159 setlocale(LC_CTYPE, ""); 160 lstr = nl_langinfo(CODESET); 161 _DIAGASSERT(lstr); 162 if (strcasecmp(lstr, "UTF-8")) { 163 __CTRACE(__CTRACE_INIT, "__init_wacs: setting defaults\n" ); 164 WACS_RARROW->vals[0] = ( wchar_t )btowc( '>' ); 165 WACS_LARROW->vals[0] = ( wchar_t )btowc( '<' ); 166 WACS_UARROW->vals[0] = ( wchar_t )btowc( '^' ); 167 WACS_DARROW->vals[0] = ( wchar_t )btowc( 'v' ); 168 WACS_BLOCK->vals[0] = ( wchar_t )btowc( '#' ); 169 WACS_CKBOARD->vals[0] = ( wchar_t )btowc( ':' ); 170 WACS_DEGREE->vals[0] = ( wchar_t )btowc( 39 ); /* ' */ 171 WACS_PLMINUS->vals[0] = ( wchar_t )btowc( '#' ); 172 WACS_BOARD->vals[0] = ( wchar_t )btowc( '#' ); 173 WACS_LANTERN->vals[0] = ( wchar_t )btowc( '#' ); 174 WACS_HLINE->vals[0] = ( wchar_t )btowc( '-' ); 175 WACS_S1->vals[0] = ( wchar_t )btowc( '-' ); 176 WACS_S9->vals[0] = ( wchar_t )btowc( '_' ); 177 WACS_VLINE->vals[0] = ( wchar_t )btowc( '|' ); 178 WACS_BULLET->vals[0] = ( wchar_t )btowc( 'o' ); 179 WACS_S3->vals[0] = ( wchar_t )btowc( 'p' ); 180 WACS_S7->vals[0] = ( wchar_t )btowc( 'r' ); 181 WACS_LEQUAL->vals[0] = ( wchar_t )btowc( 'y' ); 182 WACS_GEQUAL->vals[0] = ( wchar_t )btowc( 'z' ); 183 WACS_PI->vals[0] = ( wchar_t )btowc( '{' ); 184 WACS_NEQUAL->vals[0] = ( wchar_t )btowc( '|' ); 185 WACS_STERLING->vals[0]= ( wchar_t )btowc( '}' ); 186 } else { 187 /* Unicode defaults */ 188 __CTRACE(__CTRACE_INIT, 189 "__init_wacs: setting Unicode defaults\n" ); 190 WACS_RARROW->vals[0] = 0x2192; 191 ACS_RARROW = '+' | __ACS_IS_WACS; 192 WACS_LARROW->vals[0] = 0x2190; 193 ACS_LARROW = ',' | __ACS_IS_WACS; 194 WACS_UARROW->vals[0] = 0x2191; 195 ACS_UARROW = '-' | __ACS_IS_WACS; 196 WACS_DARROW->vals[0] = 0x2193; 197 ACS_DARROW = '.' | __ACS_IS_WACS; 198 WACS_BLOCK->vals[0] = 0x25ae; 199 ACS_BLOCK = '0' | __ACS_IS_WACS; 200 WACS_DIAMOND->vals[0] = 0x25c6; 201 ACS_DIAMOND = '`' | __ACS_IS_WACS; 202 WACS_CKBOARD->vals[0] = 0x2592; 203 ACS_CKBOARD = 'a' | __ACS_IS_WACS; 204 WACS_DEGREE->vals[0] = 0x00b0; 205 ACS_DEGREE = 'f' | __ACS_IS_WACS; 206 WACS_PLMINUS->vals[0] = 0x00b1; 207 ACS_PLMINUS = 'g' | __ACS_IS_WACS; 208 WACS_BOARD->vals[0] = 0x2592; 209 ACS_BOARD = 'h' | __ACS_IS_WACS; 210 WACS_LANTERN->vals[0] = 0x2603; 211 ACS_LANTERN = 'i' | __ACS_IS_WACS; 212 WACS_LRCORNER->vals[0]= 0x2518; 213 ACS_LRCORNER = 'j' | __ACS_IS_WACS; 214 WACS_URCORNER->vals[0]= 0x2510; 215 ACS_URCORNER = 'k' | __ACS_IS_WACS; 216 WACS_ULCORNER->vals[0]= 0x250c; 217 ACS_ULCORNER = 'l' | __ACS_IS_WACS; 218 WACS_LLCORNER->vals[0]= 0x2514; 219 ACS_LLCORNER = 'm' | __ACS_IS_WACS; 220 WACS_PLUS->vals[0] = 0x253c; 221 ACS_PLUS = 'n' | __ACS_IS_WACS; 222 WACS_HLINE->vals[0] = 0x2500; 223 ACS_HLINE = 'q' | __ACS_IS_WACS; 224 WACS_S1->vals[0] = 0x23ba; 225 ACS_S1 = 'o' | __ACS_IS_WACS; 226 WACS_S9->vals[0] = 0x23bd; 227 ACS_S9 = 's' | __ACS_IS_WACS; 228 WACS_LTEE->vals[0] = 0x251c; 229 ACS_LTEE = 't' | __ACS_IS_WACS; 230 WACS_RTEE->vals[0] = 0x2524; 231 ACS_RTEE = 'u' | __ACS_IS_WACS; 232 WACS_BTEE->vals[0] = 0x2534; 233 ACS_BTEE = 'v' | __ACS_IS_WACS; 234 WACS_TTEE->vals[0] = 0x252c; 235 ACS_TTEE = 'w' | __ACS_IS_WACS; 236 WACS_VLINE->vals[0] = 0x2502; 237 ACS_VLINE = 'x' | __ACS_IS_WACS; 238 WACS_BULLET->vals[0] = 0x00b7; 239 ACS_BULLET = '~' | __ACS_IS_WACS; 240 WACS_S3->vals[0] = 0x23bb; 241 ACS_S3 = 'p' | __ACS_IS_WACS; 242 WACS_S7->vals[0] = 0x23bc; 243 ACS_S7 = 'r' | __ACS_IS_WACS; 244 WACS_LEQUAL->vals[0] = 0x2264; 245 ACS_LEQUAL = 'y' | __ACS_IS_WACS; 246 WACS_GEQUAL->vals[0] = 0x2265; 247 ACS_GEQUAL = 'z' | __ACS_IS_WACS; 248 WACS_PI->vals[0] = 0x03C0; 249 ACS_PI = '{' | __ACS_IS_WACS; 250 WACS_NEQUAL->vals[0] = 0x2260; 251 ACS_NEQUAL = '|' | __ACS_IS_WACS; 252 WACS_STERLING->vals[0]= 0x00A3; 253 ACS_STERLING = '}' | __ACS_IS_WACS; 254 } 255 256 if (t_acs_chars(screen->term) == NULL) { 257 __CTRACE(__CTRACE_INIT, 258 "__init_wacs: no alternative characters\n" ); 259 goto out; 260 } 261 262 aofac = t_acs_chars(screen->term); 263 264 while (*aofac != '\0') { 265 if ((acs = *aofac) == '\0') 266 return; 267 if ((term = *++aofac) == '\0') 268 return; 269 /* Only add characters 1 to 127 */ 270 if (acs < NUM_ACS) { 271 _wacs_char[acs].vals[ 0 ] = term; 272 _wacs_char[acs].attributes |= WA_ALTCHARSET; 273 } 274 aofac++; 275 __CTRACE(__CTRACE_INIT, "__init_wacs: %c = %c\n", acs, term); 276 } 277 278 if (t_ena_acs(screen->term) != NULL) 279 ti_puts(screen->term, t_ena_acs(screen->term), 0, 280 __cputchar_args, screen->outfd); 281 282out: 283 for (count=0; count < NUM_ACS; count++) { 284 memcpy(&screen->wacs_char[count], &_wacs_char[count], 285 sizeof(cchar_t)); 286 screen->acs_char[count]= _acs_char[count]; 287 } 288} 289 290void 291_cursesi_reset_wacs(SCREEN *screen) 292{ 293 int count; 294 295 for (count=0; count < NUM_ACS; count++) 296 memcpy( &_wacs_char[count], &screen->wacs_char[count], 297 sizeof( cchar_t )); 298} 299#endif /* HAVE_WCHAR */ 300