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