1 /* $NetBSD: acs.c,v 1.20 2012/04/21 12:27:27 roy 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.20 2012/04/21 12:27:27 roy Exp $"); 35 #endif /* not lint */ 36 37 #include "curses.h" 38 #include "curses_private.h" 39 40 chtype _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 47 cchar_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 */ 55 void 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 #ifdef DEBUG 116 __CTRACE(__CTRACE_INIT, "__init_acs: %c = %c\n", acs, term); 117 #endif 118 } 119 120 if (t_ena_acs(screen->term) != NULL) 121 ti_puts(screen->term, t_ena_acs(screen->term), 0, 122 __cputchar_args, screen->outfd); 123 124 out: 125 for (count=0; count < NUM_ACS; count++) 126 screen->acs_char[count]= _acs_char[count]; 127 } 128 129 void 130 _cursesi_reset_acs(SCREEN *screen) 131 { 132 int count; 133 134 for (count=0; count < NUM_ACS; count++) 135 _acs_char[count]= screen->acs_char[count]; 136 } 137 138 #ifdef HAVE_WCHAR 139 /* 140 * __init_wacs -- 141 * Fill in the ACS characters. The 'acs_chars' terminfo entry is a list of 142 * character pairs - ACS definition then terminal representation. 143 */ 144 void 145 __init_wacs(SCREEN *screen) 146 { 147 int count; 148 const char *aofac; /* Address of 'ac' */ 149 unsigned char acs, term; 150 char *lstr; 151 152 /* Default value '+' for all ACS characters */ 153 for (count=0; count < NUM_ACS; count++) { 154 _wacs_char[ count ].vals[ 0 ] = ( wchar_t )btowc( '+' ); 155 _wacs_char[ count ].attributes = 0; 156 _wacs_char[ count ].elements = 1; 157 } 158 159 /* Add the SUSv2 defaults (those that are not '+') */ 160 if (!strcmp(setlocale(LC_CTYPE, NULL), "C")) 161 setlocale(LC_CTYPE, ""); 162 lstr = nl_langinfo(CODESET); 163 _DIAGASSERT(lstr); 164 if (strcasecmp(lstr, "UTF-8")) { 165 #ifdef DEBUG 166 __CTRACE(__CTRACE_INIT, "__init_wacs: setting defaults\n" ); 167 #endif /* DEBUG */ 168 WACS_RARROW->vals[0] = ( wchar_t )btowc( '>' ); 169 WACS_LARROW->vals[0] = ( wchar_t )btowc( '<' ); 170 WACS_UARROW->vals[0] = ( wchar_t )btowc( '^' ); 171 WACS_DARROW->vals[0] = ( wchar_t )btowc( 'v' ); 172 WACS_BLOCK->vals[0] = ( wchar_t )btowc( '#' ); 173 WACS_CKBOARD->vals[0] = ( wchar_t )btowc( ':' ); 174 WACS_DEGREE->vals[0] = ( wchar_t )btowc( 39 ); /* ' */ 175 WACS_PLMINUS->vals[0] = ( wchar_t )btowc( '#' ); 176 WACS_BOARD->vals[0] = ( wchar_t )btowc( '#' ); 177 WACS_LANTERN->vals[0] = ( wchar_t )btowc( '#' ); 178 WACS_HLINE->vals[0] = ( wchar_t )btowc( '-' ); 179 WACS_S1->vals[0] = ( wchar_t )btowc( '-' ); 180 WACS_S9->vals[0] = ( wchar_t )btowc( '_' ); 181 WACS_VLINE->vals[0] = ( wchar_t )btowc( '|' ); 182 WACS_BULLET->vals[0] = ( wchar_t )btowc( 'o' ); 183 WACS_S3->vals[0] = ( wchar_t )btowc( 'p' ); 184 WACS_S7->vals[0] = ( wchar_t )btowc( 'r' ); 185 WACS_LEQUAL->vals[0] = ( wchar_t )btowc( 'y' ); 186 WACS_GEQUAL->vals[0] = ( wchar_t )btowc( 'z' ); 187 WACS_PI->vals[0] = ( wchar_t )btowc( '{' ); 188 WACS_NEQUAL->vals[0] = ( wchar_t )btowc( '|' ); 189 WACS_STERLING->vals[0]= ( wchar_t )btowc( '}' ); 190 } else { 191 /* Unicode defaults */ 192 #ifdef DEBUG 193 __CTRACE(__CTRACE_INIT, 194 "__init_wacs: setting Unicode defaults\n" ); 195 #endif /* DEBUG */ 196 WACS_RARROW->vals[0] = 0x2192; 197 ACS_RARROW = '+' | __ACS_IS_WACS; 198 WACS_LARROW->vals[0] = 0x2190; 199 ACS_LARROW = ',' | __ACS_IS_WACS; 200 WACS_UARROW->vals[0] = 0x2191; 201 ACS_UARROW = '-' | __ACS_IS_WACS; 202 WACS_DARROW->vals[0] = 0x2193; 203 ACS_DARROW = '.' | __ACS_IS_WACS; 204 WACS_BLOCK->vals[0] = 0x25ae; 205 ACS_BLOCK = '0' | __ACS_IS_WACS; 206 WACS_DIAMOND->vals[0] = 0x25c6; 207 ACS_DIAMOND = '`' | __ACS_IS_WACS; 208 WACS_CKBOARD->vals[0] = 0x2592; 209 ACS_CKBOARD = 'a' | __ACS_IS_WACS; 210 WACS_DEGREE->vals[0] = 0x00b0; 211 ACS_DEGREE = 'f' | __ACS_IS_WACS; 212 WACS_PLMINUS->vals[0] = 0x00b1; 213 ACS_PLMINUS = 'g' | __ACS_IS_WACS; 214 WACS_BOARD->vals[0] = 0x2592; 215 ACS_BOARD = 'h' | __ACS_IS_WACS; 216 WACS_LANTERN->vals[0] = 0x2603; 217 ACS_LANTERN = 'i' | __ACS_IS_WACS; 218 WACS_LRCORNER->vals[0]= 0x2518; 219 ACS_LRCORNER = 'j' | __ACS_IS_WACS; 220 WACS_URCORNER->vals[0]= 0x2510; 221 ACS_URCORNER = 'k' | __ACS_IS_WACS; 222 WACS_ULCORNER->vals[0]= 0x250c; 223 ACS_ULCORNER = 'l' | __ACS_IS_WACS; 224 WACS_LLCORNER->vals[0]= 0x2514; 225 ACS_LLCORNER = 'm' | __ACS_IS_WACS; 226 WACS_PLUS->vals[0] = 0x253c; 227 ACS_PLUS = 'n' | __ACS_IS_WACS; 228 WACS_HLINE->vals[0] = 0x2500; 229 ACS_HLINE = 'q' | __ACS_IS_WACS; 230 WACS_S1->vals[0] = 0x23ba; 231 ACS_S1 = 'o' | __ACS_IS_WACS; 232 WACS_S9->vals[0] = 0x23bd; 233 ACS_S9 = 's' | __ACS_IS_WACS; 234 WACS_LTEE->vals[0] = 0x251c; 235 ACS_LTEE = 't' | __ACS_IS_WACS; 236 WACS_RTEE->vals[0] = 0x2524; 237 ACS_RTEE = 'u' | __ACS_IS_WACS; 238 WACS_BTEE->vals[0] = 0x2534; 239 ACS_BTEE = 'v' | __ACS_IS_WACS; 240 WACS_TTEE->vals[0] = 0x252c; 241 ACS_TTEE = 'w' | __ACS_IS_WACS; 242 WACS_VLINE->vals[0] = 0x2502; 243 ACS_VLINE = 'x' | __ACS_IS_WACS; 244 WACS_BULLET->vals[0] = 0x00b7; 245 ACS_BULLET = '~' | __ACS_IS_WACS; 246 WACS_S3->vals[0] = 0x23bb; 247 ACS_S3 = 'p' | __ACS_IS_WACS; 248 WACS_S7->vals[0] = 0x23bc; 249 ACS_S7 = 'r' | __ACS_IS_WACS; 250 WACS_LEQUAL->vals[0] = 0x2264; 251 ACS_LEQUAL = 'y' | __ACS_IS_WACS; 252 WACS_GEQUAL->vals[0] = 0x2265; 253 ACS_GEQUAL = 'z' | __ACS_IS_WACS; 254 WACS_PI->vals[0] = 0x03C0; 255 ACS_PI = '{' | __ACS_IS_WACS; 256 WACS_NEQUAL->vals[0] = 0x2260; 257 ACS_NEQUAL = '|' | __ACS_IS_WACS; 258 WACS_STERLING->vals[0]= 0x00A3; 259 ACS_STERLING = '}' | __ACS_IS_WACS; 260 } 261 262 if (t_acs_chars(screen->term) == NULL) { 263 #ifdef DEBUG 264 __CTRACE(__CTRACE_INIT, 265 "__init_wacs: no alternative characters\n" ); 266 #endif /* DEBUG */ 267 goto out; 268 } 269 270 aofac = t_acs_chars(screen->term); 271 272 while (*aofac != '\0') { 273 if ((acs = *aofac) == '\0') 274 return; 275 if ((term = *++aofac) == '\0') 276 return; 277 /* Only add characters 1 to 127 */ 278 if (acs < NUM_ACS) { 279 _wacs_char[acs].vals[ 0 ] = term; 280 _wacs_char[acs].attributes |= WA_ALTCHARSET; 281 } 282 aofac++; 283 #ifdef DEBUG 284 __CTRACE(__CTRACE_INIT, "__init_wacs: %c = %c\n", acs, term); 285 #endif 286 } 287 288 if (t_ena_acs(screen->term) != NULL) 289 ti_puts(screen->term, t_ena_acs(screen->term), 0, 290 __cputchar_args, screen->outfd); 291 292 out: 293 for (count=0; count < NUM_ACS; count++) { 294 memcpy(&screen->wacs_char[count], &_wacs_char[count], 295 sizeof(cchar_t)); 296 screen->acs_char[count]= _acs_char[count]; 297 } 298 } 299 300 void 301 _cursesi_reset_wacs(SCREEN *screen) 302 { 303 int count; 304 305 for (count=0; count < NUM_ACS; count++) 306 memcpy( &_wacs_char[count], &screen->wacs_char[count], 307 sizeof( cchar_t )); 308 } 309 #endif /* HAVE_WCHAR */ 310