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