1 /* $NetBSD: acs.c,v 1.16 2008/07/04 16:24:45 tnozaki 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.16 2008/07/04 16:24:45 tnozaki 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 <langinfo.h> 44 #include <strings.h> 45 46 cchar_t _wacs_char[ NUM_ACS ]; 47 #endif /* HAVE_WCHAR */ 48 49 /* 50 * __init_acs -- 51 * Fill in the ACS characters. The 'ac' termcap entry is a list of 52 * character pairs - ACS definition then terminal representation. 53 */ 54 void 55 __init_acs(SCREEN *screen) 56 { 57 int count; 58 char *aofac; /* Address of 'ac' */ 59 unsigned char acs, term; 60 61 /* Default value '+' for all ACS characters */ 62 for (count=0; count < NUM_ACS; count++) 63 _acs_char[count]= '+'; 64 65 /* Add the SUSv2 defaults (those that are not '+') */ 66 ACS_RARROW = '>'; 67 ACS_LARROW = '<'; 68 ACS_UARROW = '^'; 69 ACS_DARROW = 'v'; 70 ACS_BLOCK = '#'; 71 /* ACS_DIAMOND = '+'; */ 72 ACS_CKBOARD = ':'; 73 ACS_DEGREE = 39; /* ' */ 74 ACS_PLMINUS = '#'; 75 ACS_BOARD = '#'; 76 ACS_LANTERN = '#'; 77 /* ACS_LRCORNER = '+'; */ 78 /* ACS_URCORNER = '+'; */ 79 /* ACS_ULCORNER = '+'; */ 80 /* ACS_LLCORNER = '+'; */ 81 /* ACS_PLUS = '+'; */ 82 ACS_HLINE = '-'; 83 ACS_S1 = '-'; 84 ACS_S9 = '_'; 85 /* ACS_LTEE = '+'; */ 86 /* ACS_RTEE = '+'; */ 87 /* ACS_BTEE = '+'; */ 88 /* ACS_TTEE = '+'; */ 89 ACS_VLINE = '|'; 90 ACS_BULLET = 'o'; 91 /* Add the extensions defaults */ 92 ACS_S3 = '-'; 93 ACS_S7 = '-'; 94 ACS_LEQUAL = '<'; 95 ACS_GEQUAL = '>'; 96 ACS_PI = '*'; 97 ACS_NEQUAL = '!'; 98 ACS_STERLING = 'f'; 99 100 if (screen->tc_ac == NULL) 101 goto out; 102 103 aofac = screen->tc_ac; 104 105 while (*aofac != '\0') { 106 if ((acs = *aofac) == '\0') 107 return; 108 if (++aofac == '\0') 109 return; 110 if ((term = *aofac) == '\0') 111 return; 112 /* Only add characters 1 to 127 */ 113 if (acs < NUM_ACS) 114 _acs_char[acs] = term | __ALTCHARSET; 115 aofac++; 116 #ifdef DEBUG 117 __CTRACE(__CTRACE_INIT, "__init_acs: %c = %c\n", acs, term); 118 #endif 119 } 120 121 if (screen->tc_eA != NULL) 122 t_puts(screen->cursesi_genbuf, screen->tc_eA, 0, 123 __cputchar_args, screen->outfd); 124 125 out: 126 for (count=0; count < NUM_ACS; count++) 127 screen->acs_char[count]= _acs_char[count]; 128 } 129 130 void 131 _cursesi_reset_acs(SCREEN *screen) 132 { 133 int count; 134 135 for (count=0; count < NUM_ACS; count++) 136 _acs_char[count]= screen->acs_char[count]; 137 } 138 139 #ifdef HAVE_WCHAR 140 /* 141 * __init_wacs -- 142 * Fill in the ACS characters. The 'ac' termcap entry is a list of 143 * character pairs - ACS definition then terminal representation. 144 */ 145 void 146 __init_wacs(SCREEN *screen) 147 { 148 int count; 149 char *aofac; /* Address of 'ac' */ 150 unsigned char acs, term; 151 char *lstr; 152 153 /* Default value '+' for all ACS characters */ 154 for (count=0; count < NUM_ACS; count++) { 155 _wacs_char[ count ].vals[ 0 ] = ( wchar_t )btowc( '+' ); 156 _wacs_char[ count ].attributes = 0; 157 _wacs_char[ count ].elements = 1; 158 } 159 160 /* Add the SUSv2 defaults (those that are not '+') */ 161 lstr = nl_langinfo(CODESET); 162 _DIAGASSERT(lstr); 163 if (!strcasecmp(lstr, "UTF-8")) { 164 #ifdef DEBUG 165 __CTRACE(__CTRACE_INIT, "__init_wacs: setting defaults\n" ); 166 #endif /* DEBUG */ 167 WACS_RARROW = ( wchar_t )btowc( '>' ); 168 WACS_LARROW = ( wchar_t )btowc( '<' ); 169 WACS_UARROW = ( wchar_t )btowc( '^' ); 170 WACS_DARROW = ( wchar_t )btowc( 'v' ); 171 WACS_BLOCK = ( wchar_t )btowc( '#' ); 172 WACS_CKBOARD = ( wchar_t )btowc( ':' ); 173 WACS_DEGREE = ( wchar_t )btowc( 39 ); /* ' */ 174 WACS_PLMINUS = ( wchar_t )btowc( '#' ); 175 WACS_BOARD = ( wchar_t )btowc( '#' ); 176 WACS_LANTERN = ( wchar_t )btowc( '#' ); 177 WACS_HLINE = ( wchar_t )btowc( '-' ); 178 WACS_S1 = ( wchar_t )btowc( '-' ); 179 WACS_S9 = ( wchar_t )btowc( '_' ); 180 WACS_VLINE = ( wchar_t )btowc( '|' ); 181 WACS_BULLET = ( wchar_t )btowc( 'o' ); 182 WACS_S3 = ( wchar_t )btowc( 'p' ); 183 WACS_S7 = ( wchar_t )btowc( 'r' ); 184 WACS_LEQUAL = ( wchar_t )btowc( 'y' ); 185 WACS_GEQUAL = ( wchar_t )btowc( 'z' ); 186 WACS_PI = ( wchar_t )btowc( '{' ); 187 WACS_NEQUAL = ( wchar_t )btowc( '|' ); 188 WACS_STERLING = ( wchar_t )btowc( '}' ); 189 } else { 190 /* Unicode defaults */ 191 #ifdef DEBUG 192 __CTRACE(__CTRACE_INIT, 193 "__init_wacs: setting Unicode defaults\n" ); 194 #endif /* DEBUG */ 195 WACS_RARROW = 0x2192; 196 WACS_LARROW = 0x2190; 197 WACS_UARROW = 0x2192; 198 WACS_DARROW = 0x2193; 199 WACS_BLOCK = 0x25ae; 200 WACS_DIAMOND = 0x25c6; 201 WACS_CKBOARD = 0x2592; 202 WACS_DEGREE = 0x00b0; 203 WACS_PLMINUS = 0x00b1; 204 WACS_BOARD = 0x2592; 205 WACS_LANTERN = 0x2603; 206 WACS_LRCORNER = 0x2518; 207 WACS_URCORNER = 0x2510; 208 WACS_ULCORNER = 0x250c; 209 WACS_LLCORNER = 0x2514; 210 WACS_PLUS = 0x253c; 211 WACS_HLINE = 0x2500; 212 WACS_S1 = 0x23ba; 213 WACS_S9 = 0x23bd; 214 WACS_LTEE = 0x251c; 215 WACS_RTEE = 0x2524; 216 WACS_BTEE = 0x2534; 217 WACS_TTEE = 0x252c; 218 WACS_VLINE = 0x2502; 219 WACS_BULLET = 0x00b7; 220 WACS_S3 = 0x23bb; 221 WACS_S7 = 0x23bc; 222 WACS_LEQUAL = 0x2264; 223 WACS_GEQUAL = 0x2265; 224 WACS_PI = 0x03C0; 225 WACS_NEQUAL = 0x2260; 226 WACS_STERLING = 0x00A3; 227 } 228 229 if (screen->tc_ac == NULL) { 230 #ifdef DEBUG 231 __CTRACE(__CTRACE_INIT, 232 "__init_wacs: no alternative characters\n" ); 233 #endif /* DEBUG */ 234 goto out; 235 } 236 237 aofac = screen->tc_ac; 238 239 while (*aofac != '\0') { 240 if ((acs = *aofac) == '\0') 241 return; 242 if (++aofac == '\0') 243 return; 244 if ((term = *aofac) == '\0') 245 return; 246 /* Only add characters 1 to 127 */ 247 if (acs < NUM_ACS) { 248 _wacs_char[acs].vals[ 0 ] = term; 249 _wacs_char[acs].attributes |= WA_ALTCHARSET; 250 } 251 aofac++; 252 #ifdef DEBUG 253 __CTRACE(__CTRACE_INIT, "__init_wacs: %c = %c\n", acs, term); 254 #endif 255 } 256 257 if (screen->tc_eA != NULL) 258 t_puts(screen->cursesi_genbuf, screen->tc_eA, 0, 259 __cputchar_args, screen->outfd); 260 261 out: 262 for (count=0; count < NUM_ACS; count++) 263 memcpy(&screen->wacs_char[count], &_wacs_char[count], 264 sizeof(cchar_t)); 265 } 266 267 void 268 _cursesi_reset_wacs(SCREEN *screen) 269 { 270 int count; 271 272 for (count=0; count < NUM_ACS; count++) 273 memcpy( &_wacs_char[count], &screen->wacs_char[count], 274 sizeof( cchar_t )); 275 } 276 #endif /* HAVE_WCHAR */ 277