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
__init_acs(SCREEN * screen)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
_cursesi_reset_acs(SCREEN * screen)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
__init_wacs(SCREEN * screen)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
_cursesi_reset_wacs(SCREEN * screen)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