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