attributes.c revision 1.32 1 /* $NetBSD: attributes.c,v 1.32 2021/09/06 07:03:49 rin Exp $ */
2
3 /*-
4 * Copyright (c) 1999 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: attributes.c,v 1.32 2021/09/06 07:03:49 rin Exp $");
35 #endif /* not lint */
36
37 #include "curses.h"
38 #include "curses_private.h"
39
40 static int __wattr_off(WINDOW *, attr_t);
41 static int __wattr_on(WINDOW *, attr_t);
42 static void __wcolor_set(WINDOW *, attr_t);
43
44
45 #ifndef _CURSES_USE_MACROS
46 #ifdef HAVE_WCHAR
47 /*
48 * attr_get --
49 * Get wide attributes and color pair from stdscr
50 */
51 /* ARGSUSED */
52 int
53 attr_get(attr_t *attr, short *pair, void *opts)
54 {
55 return wattr_get(stdscr, attr, pair, opts);
56 }
57
58 /*
59 * attr_on --
60 * Test and set wide attributes on stdscr
61 */
62 /* ARGSUSED */
63 int
64 attr_on(attr_t attr, void *opts)
65 {
66 return wattr_on(stdscr, attr, opts);
67 }
68
69 /*
70 * attr_off --
71 * Test and unset wide attributes on stdscr
72 */
73 /* ARGSUSED */
74 int
75 attr_off(attr_t attr, void *opts)
76 {
77 return wattr_off(stdscr, attr, opts);
78 }
79
80 /*
81 * attr_set --
82 * Set wide attributes and color pair on stdscr
83 */
84 /* ARGSUSED */
85 int
86 attr_set(attr_t attr, short pair, void *opts)
87 {
88 return wattr_set(stdscr, attr, pair, opts);
89 }
90
91 /*
92 * color_set --
93 * Set color pair on stdscr
94 */
95 /* ARGSUSED */
96 int
97 color_set(short pair, void *opts)
98 {
99 return wcolor_set(stdscr, pair, opts);
100 }
101 #endif /* HAVE_WCHAR */
102
103 /*
104 * attron --
105 * Test and set attributes on stdscr
106 */
107 int
108 attron(int attr)
109 {
110 return wattron(stdscr, attr);
111 }
112
113 /*
114 * attroff --
115 * Test and unset attributes on stdscr.
116 */
117 int
118 attroff(int attr)
119 {
120 return wattroff(stdscr, attr);
121 }
122
123 /*
124 * attrset --
125 * Set specific attribute modes.
126 * Unset others. On stdscr.
127 */
128 int
129 attrset(int attr)
130 {
131 return wattrset(stdscr, attr);
132 }
133 #endif /* _CURSES_USE_MACROS */
134
135
136 #ifdef HAVE_WCHAR
137 /*
138 * wattr_get --
139 * Get wide attributes and colour pair from window
140 * Note that attributes also includes colour.
141 */
142 /* ARGSUSED */
143 int
144 wattr_get(WINDOW *win, attr_t *attr, short *pair, void *opts)
145 {
146 __CTRACE(__CTRACE_ATTR, "wattr_get: win %p\n", win);
147 if (attr != NULL) {
148 *attr = win->wattr;
149 #ifdef HAVE_WCHAR
150 *attr &= WA_ATTRIBUTES;
151 #endif
152 }
153
154 if (pair != NULL)
155 *pair = PAIR_NUMBER(win->wattr);
156 return OK;
157 }
158
159 /*
160 * wattr_on --
161 * Test and set wide attributes on window
162 */
163 int
164 wattr_on(WINDOW *win, attr_t attr, void *opts)
165 {
166 if (__predict_false(opts != NULL))
167 return ERR;
168
169 return __wattr_on(win, attr);
170 }
171
172 /*
173 * wattr_off --
174 * Test and unset wide attributes on window
175 *
176 * Note that the 'me' sequence unsets all attributes. We handle
177 * which attributes should really be set in refresh.c:makech().
178 */
179 int
180 wattr_off(WINDOW *win, attr_t attr, void *opts)
181 {
182 if (__predict_false(opts != NULL))
183 return ERR;
184
185 return __wattr_off(win, attr);
186 }
187
188
189 /*
190 * wattr_set --
191 * Set wide attributes and color pair on window
192 */
193 int
194 wattr_set(WINDOW *win, attr_t attr, short pair, void *opts)
195 {
196 __CTRACE(__CTRACE_ATTR, "wattr_set: win %p, attr %08x, pair %d\n",
197 win, attr, pair);
198 if (__predict_false(opts != NULL))
199 return ERR;
200
201 /*
202 * This overwrites any colour setting from the attributes
203 * and is compatible with ncurses.
204 */
205 attr = (attr & ~__COLOR) | COLOR_PAIR(pair);
206
207 __wattr_off(win, WA_ATTRIBUTES);
208 __wattr_on(win, attr);
209 return OK;
210 }
211
212 /*
213 * wcolor_set --
214 * Set color pair on window
215 */
216 /* ARGSUSED */
217 int
218 wcolor_set(WINDOW *win, short pair, void *opts)
219 {
220 __CTRACE(__CTRACE_COLOR, "wolor_set: win %p, pair %d\n", win, pair);
221 __wcolor_set(win, (attr_t) COLOR_PAIR(pair));
222 return OK;
223 }
224 #endif /* HAVE_WCHAR */
225
226
227 /*
228 * getattrs --
229 * Get window attributes.
230 */
231 chtype
232 getattrs(WINDOW *win)
233 {
234 __CTRACE(__CTRACE_ATTR, "getattrs: win %p\n", win);
235 return((chtype) win->wattr);
236 }
237
238 /*
239 * wattron --
240 * Test and set attributes.
241 */
242 int
243 wattron(WINDOW *win, int attr)
244 {
245 __CTRACE(__CTRACE_ATTR, "wattron: win %p, attr %08x\n", win, attr);
246 return __wattr_on(win, (attr_t) attr);
247 }
248
249 /*
250 * wattroff --
251 * Test and unset attributes.
252 */
253 int
254 wattroff(WINDOW *win, int attr)
255 {
256 __CTRACE(__CTRACE_ATTR, "wattroff: win %p, attr %08x\n", win, attr);
257 return __wattr_off(win, (attr_t) attr);
258 }
259
260 /*
261 * wattrset --
262 * Set specific attribute modes.
263 * Unset others.
264 */
265 int
266 wattrset(WINDOW *win, int attr)
267 {
268 __CTRACE(__CTRACE_ATTR, "wattrset: win %p, attr %08x\n", win, attr);
269 __wattr_off(win, __ATTRIBUTES);
270 __wattr_on(win, (attr_t) attr);
271 return OK;
272 }
273
274 /*
275 * termattrs --
276 * Get terminal attributes
277 */
278 chtype
279 termattrs(void)
280 {
281 chtype ch = 0;
282
283 __CTRACE(__CTRACE_ATTR, "termattrs\n");
284 if (exit_attribute_mode != NULL) {
285 __CTRACE(__CTRACE_ATTR, "termattrs: have exit attribute mode\n");
286 if (enter_blink_mode != NULL)
287 ch |= __BLINK;
288 if (enter_bold_mode != NULL)
289 ch |= __BOLD;
290 if (enter_dim_mode != NULL)
291 ch |= __DIM;
292 if (enter_secure_mode != NULL)
293 ch |= __BLANK;
294 if (enter_protected_mode != NULL)
295 ch |= __PROTECT;
296 if (enter_reverse_mode != NULL)
297 ch |= __REVERSE;
298 }
299 if (enter_standout_mode != NULL && exit_standout_mode != NULL)
300 ch |= __STANDOUT;
301 if (enter_underline_mode != NULL && exit_underline_mode != NULL)
302 ch |= __UNDERSCORE;
303 if (enter_alt_charset_mode != NULL && exit_alt_charset_mode != NULL)
304 ch |= __ALTCHARSET;
305
306 return ch;
307 }
308
309
310 #ifdef HAVE_WCHAR
311 /*
312 * term_attrs --
313 * Get terminal wide attributes
314 */
315 attr_t
316 term_attrs(void)
317 {
318 attr_t attr = 0;
319
320 __CTRACE(__CTRACE_ATTR, "term_attrs\n");
321 if (exit_attribute_mode != NULL) {
322 if (enter_blink_mode != NULL)
323 attr |= __BLINK;
324 if (enter_bold_mode != NULL)
325 attr |= __BOLD;
326 if (enter_dim_mode != NULL)
327 attr |= __DIM;
328 if (enter_secure_mode != NULL)
329 attr |= __BLANK;
330 if (enter_protected_mode != NULL)
331 attr |= __PROTECT;
332 if (enter_reverse_mode != NULL)
333 attr |= __REVERSE;
334 #ifdef HAVE_WCHAR
335 if (enter_low_hl_mode != NULL)
336 attr |= WA_LOW;
337 if (enter_top_hl_mode != NULL)
338 attr |= WA_TOP;
339 if (enter_left_hl_mode != NULL)
340 attr |= WA_LEFT;
341 if (enter_right_hl_mode != NULL)
342 attr |= WA_RIGHT;
343 if (enter_horizontal_hl_mode != NULL)
344 attr |= WA_HORIZONTAL;
345 if (enter_vertical_hl_mode != NULL)
346 attr |= WA_VERTICAL;
347 #endif /* HAVE_WCHAR */
348 }
349 if (enter_standout_mode != NULL && exit_standout_mode != NULL)
350 attr |= __STANDOUT;
351 if (enter_underline_mode != NULL && exit_underline_mode != NULL)
352 attr |= __UNDERSCORE;
353 if (enter_alt_charset_mode != NULL && exit_alt_charset_mode != NULL)
354 attr |= __ALTCHARSET;
355
356 return attr;
357 }
358 #endif /* HAVE_WCHAR */
359
360
361 static int
362 __wattr_on(WINDOW *win, attr_t attr)
363 {
364 const TERMINAL *t = win->screen->term;
365
366 __CTRACE(__CTRACE_ATTR, "wattr_on: win %p, attr %08x\n", win, attr);
367 /* If can enter modes, set the relevent attribute bits. */
368 if (t_exit_attribute_mode(t) != NULL) {
369 if (attr & __BLINK && t_enter_blink_mode(t) != NULL)
370 win->wattr |= __BLINK;
371 if (attr & __BOLD && t_enter_bold_mode(t) != NULL)
372 win->wattr |= __BOLD;
373 if (attr & __DIM && t_enter_dim_mode(t) != NULL)
374 win->wattr |= __DIM;
375 if (attr & __BLANK && t_enter_secure_mode(t) != NULL)
376 win->wattr |= __BLANK;
377 if (attr & __PROTECT && t_enter_protected_mode(t) != NULL)
378 win->wattr |= __PROTECT;
379 if (attr & __REVERSE && t_enter_reverse_mode(t) != NULL)
380 win->wattr |= __REVERSE;
381 #ifdef HAVE_WCHAR
382 if (attr & WA_LOW && t_enter_low_hl_mode(t) != NULL)
383 win->wattr |= WA_LOW;
384 if (attr & WA_TOP && t_enter_top_hl_mode(t) != NULL)
385 win->wattr |= WA_TOP;
386 if (attr & WA_LEFT && t_enter_left_hl_mode(t) != NULL)
387 win->wattr |= WA_LEFT;
388 if (attr & WA_RIGHT && t_enter_right_hl_mode(t) != NULL)
389 win->wattr |= WA_RIGHT;
390 if (attr & WA_HORIZONTAL && t_enter_horizontal_hl_mode(t) != NULL)
391 win->wattr |= WA_HORIZONTAL;
392 if (attr & WA_VERTICAL && t_enter_vertical_hl_mode(t) != NULL)
393 win->wattr |= WA_VERTICAL;
394 #endif /* HAVE_WCHAR */
395 }
396 if (attr & __STANDOUT && t_enter_standout_mode(t) != NULL &&
397 t_exit_standout_mode(t) != NULL)
398 wstandout(win);
399 if (attr & __UNDERSCORE && t_enter_underline_mode(t) != NULL &&
400 t_exit_underline_mode(t) != NULL)
401 wunderscore(win);
402 if (attr & __COLOR)
403 __wcolor_set(win, attr);
404 return OK;
405 }
406
407
408 static int
409 __wattr_off(WINDOW *win, attr_t attr)
410 {
411 const TERMINAL *t = win->screen->term;
412
413 __CTRACE(__CTRACE_ATTR, "wattr_off: win %p, attr %08x\n", win, attr);
414 /* If can do exit modes, unset the relevent attribute bits. */
415 if (t_exit_attribute_mode(t) != NULL) {
416 if (attr & __BLINK)
417 win->wattr &= ~__BLINK;
418 if (attr & __BOLD)
419 win->wattr &= ~__BOLD;
420 if (attr & __DIM)
421 win->wattr &= ~__DIM;
422 if (attr & __BLANK)
423 win->wattr &= ~__BLANK;
424 if (attr & __PROTECT)
425 win->wattr &= ~__PROTECT;
426 if (attr & __REVERSE)
427 win->wattr &= ~__REVERSE;
428 #ifdef HAVE_WCHAR
429 if (attr & WA_LOW)
430 win->wattr &= ~WA_LOW;
431 if (attr & WA_TOP)
432 win->wattr &= ~WA_TOP;
433 if (attr & WA_LEFT)
434 win->wattr &= ~WA_LEFT;
435 if (attr & WA_RIGHT)
436 win->wattr &= ~WA_RIGHT;
437 if (attr & WA_HORIZONTAL)
438 win->wattr &= ~WA_HORIZONTAL;
439 if (attr & WA_VERTICAL)
440 win->wattr &= ~WA_VERTICAL;
441 #endif /* HAVE_WCHAR */
442 }
443 if (attr & __STANDOUT)
444 wstandend(win);
445 if (attr & __UNDERSCORE)
446 wunderend(win);
447 if (attr & __COLOR) {
448 if (max_colors != 0)
449 win->wattr &= ~__COLOR;
450 }
451 return OK;
452 }
453
454
455 static void
456 __wcolor_set(WINDOW *win, attr_t attr)
457 {
458 const TERMINAL *t = win->screen->term;
459
460 /* If another color pair is set, turn that off first. */
461 win->wattr &= ~__COLOR;
462 /* If can do color video, set the color pair bits. */
463 if (t_max_colors(t) != 0 && attr & __COLOR)
464 win->wattr |= attr & __COLOR;
465 }
466