attributes.c revision 1.35 1 /* $NetBSD: attributes.c,v 1.35 2022/10/25 06:20:01 blymn 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.35 2022/10/25 06:20:01 blymn 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 if (__predict_false(win == NULL))
147 return ERR;
148
149 __CTRACE(__CTRACE_ATTR, "wattr_get: win %p\n", win);
150 if (attr != NULL) {
151 *attr = win->wattr;
152 #ifdef HAVE_WCHAR
153 *attr &= WA_ATTRIBUTES;
154 #endif
155 }
156
157 if (pair != NULL)
158 *pair = PAIR_NUMBER(win->wattr);
159 return OK;
160 }
161
162 /*
163 * wattr_on --
164 * Test and set wide attributes on window
165 */
166 int
167 wattr_on(WINDOW *win, attr_t attr, void *opts)
168 {
169 if (__predict_false(opts != NULL))
170 return ERR;
171
172 return __wattr_on(win, attr);
173 }
174
175 /*
176 * wattr_off --
177 * Test and unset wide attributes on window
178 *
179 * Note that the 'me' sequence unsets all attributes. We handle
180 * which attributes should really be set in refresh.c:makech().
181 */
182 int
183 wattr_off(WINDOW *win, attr_t attr, void *opts)
184 {
185 if (__predict_false(opts != NULL))
186 return ERR;
187
188 return __wattr_off(win, attr);
189 }
190
191
192 /*
193 * wattr_set --
194 * Set wide attributes and color pair on window
195 */
196 int
197 wattr_set(WINDOW *win, attr_t attr, short pair, void *opts)
198 {
199 __CTRACE(__CTRACE_ATTR, "wattr_set: win %p, attr %08x, pair %d\n",
200 win, attr, pair);
201 if (__predict_false(opts != NULL))
202 return ERR;
203
204 /*
205 * This overwrites any colour setting from the attributes
206 * and is compatible with ncurses.
207 */
208 attr = (attr & ~__COLOR) | COLOR_PAIR(pair);
209
210 __wattr_off(win, WA_ATTRIBUTES);
211 __wattr_on(win, attr);
212 return OK;
213 }
214
215 /*
216 * wcolor_set --
217 * Set color pair on window
218 */
219 /* ARGSUSED */
220 int
221 wcolor_set(WINDOW *win, short pair, void *opts)
222 {
223 __CTRACE(__CTRACE_COLOR, "wolor_set: win %p, pair %d\n", win, pair);
224 __wcolor_set(win, (attr_t) COLOR_PAIR(pair));
225 return OK;
226 }
227 #endif /* HAVE_WCHAR */
228
229
230 /*
231 * getattrs --
232 * Get window attributes.
233 */
234 chtype
235 getattrs(WINDOW *win)
236 {
237 if (__predict_false(win == NULL))
238 return ERR;
239
240 __CTRACE(__CTRACE_ATTR, "getattrs: win %p\n", win);
241 return((chtype) win->wattr);
242 }
243
244 /*
245 * wattron --
246 * Test and set attributes.
247 */
248 int
249 wattron(WINDOW *win, int attr)
250 {
251 __CTRACE(__CTRACE_ATTR, "wattron: win %p, attr %08x\n", win, attr);
252 return __wattr_on(win, (attr_t) attr);
253 }
254
255 /*
256 * wattroff --
257 * Test and unset attributes.
258 */
259 int
260 wattroff(WINDOW *win, int attr)
261 {
262 __CTRACE(__CTRACE_ATTR, "wattroff: win %p, attr %08x\n", win, attr);
263 return __wattr_off(win, (attr_t) attr);
264 }
265
266 /*
267 * wattrset --
268 * Set specific attribute modes.
269 * Unset others.
270 */
271 int
272 wattrset(WINDOW *win, int attr)
273 {
274 __CTRACE(__CTRACE_ATTR, "wattrset: win %p, attr %08x\n", win, attr);
275 __wattr_off(win, __ATTRIBUTES);
276 __wattr_on(win, (attr_t) attr);
277 return OK;
278 }
279
280 /*
281 * termattrs --
282 * Get terminal attributes
283 */
284 chtype
285 termattrs(void)
286 {
287 chtype ch = 0;
288
289 __CTRACE(__CTRACE_ATTR, "termattrs\n");
290 if (exit_attribute_mode != NULL) {
291 __CTRACE(__CTRACE_ATTR, "termattrs: have exit attribute mode\n");
292 if (enter_blink_mode != NULL)
293 ch |= __BLINK;
294 if (enter_bold_mode != NULL)
295 ch |= __BOLD;
296 if (enter_dim_mode != NULL)
297 ch |= __DIM;
298 if (enter_secure_mode != NULL)
299 ch |= __BLANK;
300 if (enter_protected_mode != NULL)
301 ch |= __PROTECT;
302 if (enter_reverse_mode != NULL)
303 ch |= __REVERSE;
304 }
305 if (enter_standout_mode != NULL && exit_standout_mode != NULL)
306 ch |= __STANDOUT;
307 if (enter_underline_mode != NULL && exit_underline_mode != NULL)
308 ch |= __UNDERSCORE;
309 if (enter_alt_charset_mode != NULL && exit_alt_charset_mode != NULL)
310 ch |= __ALTCHARSET;
311
312 return ch;
313 }
314
315
316 #ifdef HAVE_WCHAR
317 /*
318 * term_attrs --
319 * Get terminal wide attributes
320 */
321 attr_t
322 term_attrs(void)
323 {
324 attr_t attr = 0;
325
326 __CTRACE(__CTRACE_ATTR, "term_attrs\n");
327 if (exit_attribute_mode != NULL) {
328 if (enter_blink_mode != NULL)
329 attr |= __BLINK;
330 if (enter_bold_mode != NULL)
331 attr |= __BOLD;
332 if (enter_dim_mode != NULL)
333 attr |= __DIM;
334 if (enter_secure_mode != NULL)
335 attr |= __BLANK;
336 if (enter_protected_mode != NULL)
337 attr |= __PROTECT;
338 if (enter_reverse_mode != NULL)
339 attr |= __REVERSE;
340 #ifdef HAVE_WCHAR
341 if (enter_low_hl_mode != NULL)
342 attr |= WA_LOW;
343 if (enter_top_hl_mode != NULL)
344 attr |= WA_TOP;
345 if (enter_left_hl_mode != NULL)
346 attr |= WA_LEFT;
347 if (enter_right_hl_mode != NULL)
348 attr |= WA_RIGHT;
349 if (enter_horizontal_hl_mode != NULL)
350 attr |= WA_HORIZONTAL;
351 if (enter_vertical_hl_mode != NULL)
352 attr |= WA_VERTICAL;
353 #endif /* HAVE_WCHAR */
354 }
355 if (enter_standout_mode != NULL && exit_standout_mode != NULL)
356 attr |= __STANDOUT;
357 if (enter_underline_mode != NULL && exit_underline_mode != NULL)
358 attr |= __UNDERSCORE;
359 if (enter_alt_charset_mode != NULL && exit_alt_charset_mode != NULL)
360 attr |= __ALTCHARSET;
361
362 return attr;
363 }
364 #endif /* HAVE_WCHAR */
365
366
367 static int
368 __wattr_on(WINDOW *win, attr_t attr)
369 {
370 const TERMINAL *t;
371
372 if (__predict_false(win == NULL))
373 return ERR;
374
375 t = win->screen->term;
376
377 __CTRACE(__CTRACE_ATTR, "wattr_on: win %p, attr %08x\n", win, attr);
378 /* If can enter modes, set the relevant attribute bits. */
379 if (t_exit_attribute_mode(t) != NULL) {
380 if (attr & __BLINK && t_enter_blink_mode(t) != NULL)
381 win->wattr |= __BLINK;
382 if (attr & __BOLD && t_enter_bold_mode(t) != NULL)
383 win->wattr |= __BOLD;
384 if (attr & __DIM && t_enter_dim_mode(t) != NULL)
385 win->wattr |= __DIM;
386 if (attr & __BLANK && t_enter_secure_mode(t) != NULL)
387 win->wattr |= __BLANK;
388 if (attr & __PROTECT && t_enter_protected_mode(t) != NULL)
389 win->wattr |= __PROTECT;
390 if (attr & __REVERSE && t_enter_reverse_mode(t) != NULL)
391 win->wattr |= __REVERSE;
392 #ifdef HAVE_WCHAR
393 if (attr & WA_LOW && t_enter_low_hl_mode(t) != NULL)
394 win->wattr |= WA_LOW;
395 if (attr & WA_TOP && t_enter_top_hl_mode(t) != NULL)
396 win->wattr |= WA_TOP;
397 if (attr & WA_LEFT && t_enter_left_hl_mode(t) != NULL)
398 win->wattr |= WA_LEFT;
399 if (attr & WA_RIGHT && t_enter_right_hl_mode(t) != NULL)
400 win->wattr |= WA_RIGHT;
401 if (attr & WA_HORIZONTAL && t_enter_horizontal_hl_mode(t) != NULL)
402 win->wattr |= WA_HORIZONTAL;
403 if (attr & WA_VERTICAL && t_enter_vertical_hl_mode(t) != NULL)
404 win->wattr |= WA_VERTICAL;
405 #endif /* HAVE_WCHAR */
406 }
407 if (attr & __STANDOUT && t_enter_standout_mode(t) != NULL &&
408 t_exit_standout_mode(t) != NULL)
409 wstandout(win);
410 if (attr & __UNDERSCORE && t_enter_underline_mode(t) != NULL &&
411 t_exit_underline_mode(t) != NULL)
412 wunderscore(win);
413 if (attr & __COLOR)
414 __wcolor_set(win, attr);
415 return OK;
416 }
417
418
419 static int
420 __wattr_off(WINDOW *win, attr_t attr)
421 {
422 const TERMINAL *t;
423
424 if (__predict_false(win == NULL))
425 return ERR;
426
427 t = win->screen->term;
428
429 __CTRACE(__CTRACE_ATTR, "wattr_off: win %p, attr %08x\n", win, attr);
430 /* If can do exit modes, unset the relevant attribute bits. */
431 if (t_exit_attribute_mode(t) != NULL) {
432 if (attr & __BLINK)
433 win->wattr &= ~__BLINK;
434 if (attr & __BOLD)
435 win->wattr &= ~__BOLD;
436 if (attr & __DIM)
437 win->wattr &= ~__DIM;
438 if (attr & __BLANK)
439 win->wattr &= ~__BLANK;
440 if (attr & __PROTECT)
441 win->wattr &= ~__PROTECT;
442 if (attr & __REVERSE)
443 win->wattr &= ~__REVERSE;
444 #ifdef HAVE_WCHAR
445 if (attr & WA_LOW)
446 win->wattr &= ~WA_LOW;
447 if (attr & WA_TOP)
448 win->wattr &= ~WA_TOP;
449 if (attr & WA_LEFT)
450 win->wattr &= ~WA_LEFT;
451 if (attr & WA_RIGHT)
452 win->wattr &= ~WA_RIGHT;
453 if (attr & WA_HORIZONTAL)
454 win->wattr &= ~WA_HORIZONTAL;
455 if (attr & WA_VERTICAL)
456 win->wattr &= ~WA_VERTICAL;
457 #endif /* HAVE_WCHAR */
458 }
459 if (attr & __STANDOUT)
460 wstandend(win);
461 if (attr & __UNDERSCORE)
462 wunderend(win);
463 if (attr & __COLOR) {
464 if (max_colors != 0)
465 win->wattr &= ~__COLOR;
466 }
467 return OK;
468 }
469
470
471 static void
472 __wcolor_set(WINDOW *win, attr_t attr)
473 {
474 const TERMINAL *t;
475
476 if (__predict_false(win == NULL))
477 return;
478
479 t = win->screen->term;
480
481 /* If another color pair is set, turn that off first. */
482 win->wattr &= ~__COLOR;
483 /* If can do color video, set the color pair bits. */
484 if (t_max_colors(t) != 0)
485 win->wattr |= attr & __COLOR;
486 }
487