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