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