NeoMutt  2024-04-16-36-g75b6fb
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
attr.c File Reference

Colour and attributes. More...

#include "config.h"
#include <stddef.h>
#include <assert.h>
#include <string.h>
#include "mutt/lib.h"
#include "config/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "attr.h"
#include "color.h"
#include "curses2.h"
#include "debug.h"
+ Include dependency graph for attr.c:

Go to the source code of this file.

Functions

void attr_color_clear (struct AttrColor *ac)
 Free the contents of an AttrColor.
 
void attr_color_free (struct AttrColor **ptr)
 Free an AttrColor.
 
struct AttrColorattr_color_new (void)
 Create a new AttrColor.
 
void attr_color_list_clear (struct AttrColorList *acl)
 Free the contents of an AttrColorList.
 
struct AttrColorattr_color_list_find (struct AttrColorList *acl, color_t fg, color_t bg, int attrs)
 Find an AttrColor in a list.
 
struct AttrColor attr_color_copy (const struct AttrColor *ac)
 Copy a colour.
 
bool attr_color_is_set (const struct AttrColor *ac)
 Is the object coloured?
 
bool attr_color_match (struct AttrColor *ac1, struct AttrColor *ac2)
 Do the colours match?
 
void modify_color_by_prefix (enum ColorPrefix prefix, bool is_fg, color_t *col, int *attrs)
 Modify a colour/attributes based on a prefix, e.g.
 
color_t color_xterm256_to_24bit (const color_t color)
 Convert a xterm color to its RGB value.
 
void attr_color_overwrite (struct AttrColor *ac_old, struct AttrColor *ac_new)
 Update an AttrColor in-place.
 

Detailed Description

Colour and attributes.

Authors
  • Richard Russon

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file attr.c.

Function Documentation

◆ attr_color_clear()

void attr_color_clear ( struct AttrColor ac)

Free the contents of an AttrColor.

Parameters
acAttrColor to empty
Note
The AttrColor object isn't freed

Definition at line 49 of file attr.c.

50{
51 if (!ac)
52 return;
53
54 if (ac->curses_color)
55 color_debug(LL_DEBUG5, "clear %p\n", (void *) ac);
57
58 memset(&ac->fg, 0, sizeof(ac->fg));
59 memset(&ac->bg, 0, sizeof(ac->bg));
60
63 ac->attrs = A_NORMAL;
64}
#define COLOR_DEFAULT
Definition: color.h:100
void curses_color_free(struct CursesColor **ptr)
Free a CursesColor.
Definition: curses.c:120
static int color_debug(enum LogLevel level, const char *format,...)
Definition: debug.h:53
@ LL_DEBUG5
Log at debug level 5.
Definition: logging2.h:47
struct ColorElement bg
Background colour.
Definition: attr.h:68
struct ColorElement fg
Foreground colour.
Definition: attr.h:67
int attrs
Text attributes, e.g. A_BOLD.
Definition: attr.h:69
struct CursesColor * curses_color
Underlying Curses colour.
Definition: attr.h:70
color_t color
Colour.
Definition: attr.h:57
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ attr_color_free()

void attr_color_free ( struct AttrColor **  ptr)

Free an AttrColor.

Parameters
ptrAttrColor to free

Definition at line 70 of file attr.c.

71{
72 if (!ptr || !*ptr)
73 return;
74
75 struct AttrColor *ac = *ptr;
76 if (ac->ref_count > 1)
77 {
78 ac->ref_count--;
79 *ptr = NULL;
80 return;
81 }
82
84 FREE(ptr);
85}
void attr_color_clear(struct AttrColor *ac)
Free the contents of an AttrColor.
Definition: attr.c:49
#define FREE(x)
Definition: memory.h:45
A curses colour and its attributes.
Definition: attr.h:66
short ref_count
Number of users.
Definition: attr.h:71
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ attr_color_new()

struct AttrColor * attr_color_new ( void  )

Create a new AttrColor.

Return values
ptrNew AttrColor

Definition at line 91 of file attr.c.

92{
93 struct AttrColor *ac = mutt_mem_calloc(1, sizeof(*ac));
94
96 ac->fg.type = CT_SIMPLE;
98
100 ac->bg.type = CT_SIMPLE;
102
103 ac->attrs = A_NORMAL;
104
105 ac->ref_count = 1;
106
107 return ac;
108}
@ COLOR_PREFIX_NONE
no prefix
Definition: attr.h:46
@ CT_SIMPLE
Simple colour, e.g. "Red".
Definition: attr.h:36
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
enum ColorType type
Type of Colour.
Definition: attr.h:58
enum ColorPrefix prefix
Optional Colour Modifier.
Definition: attr.h:59
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ attr_color_list_clear()

void attr_color_list_clear ( struct AttrColorList *  acl)

Free the contents of an AttrColorList.

Parameters
aclList to clear

Free each of the AttrColors in a list.

Note
The list object isn't freed, only emptied

Definition at line 118 of file attr.c.

119{
120 if (!acl)
121 return;
122
123 struct AttrColor *ac = NULL;
124 struct AttrColor *tmp = NULL;
125 TAILQ_FOREACH_SAFE(ac, acl, entries, tmp)
126 {
127 TAILQ_REMOVE(acl, ac, entries);
128 attr_color_free(&ac);
129 }
130}
void attr_color_free(struct AttrColor **ptr)
Free an AttrColor.
Definition: attr.c:70
#define TAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:735
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:841
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ attr_color_list_find()

struct AttrColor * attr_color_list_find ( struct AttrColorList *  acl,
color_t  fg,
color_t  bg,
int  attrs 
)

Find an AttrColor in a list.

Parameters
aclList to search
fgForeground colour
bgBackground colour
attrsAttributes, e.g. A_UNDERLINE
Return values
ptrMatching AttrColor

Definition at line 140 of file attr.c.

142{
143 if (!acl)
144 return NULL;
145
146 struct AttrColor *ac = NULL;
147 TAILQ_FOREACH(ac, acl, entries)
148 {
149 if (ac->attrs != attrs)
150 continue;
151
152 struct CursesColor *cc = ac->curses_color;
153 if (!cc)
154 continue;
155
156 if ((cc->fg == fg) && (cc->bg == bg))
157 return ac;
158 }
159 return NULL;
160}
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
Colour in the ncurses palette.
Definition: curses2.h:41
color_t fg
Foreground colour.
Definition: curses2.h:42
color_t bg
Background colour.
Definition: curses2.h:43
+ Here is the caller graph for this function:

◆ attr_color_copy()

struct AttrColor attr_color_copy ( const struct AttrColor ac)

Copy a colour.

Parameters
acColour to copy
Return values
objCopy of the colour

Definition at line 167 of file attr.c.

168{
169 if (ac)
170 return *ac;
171 else
172 return (struct AttrColor){ 0 };
173}
+ Here is the caller graph for this function:

◆ attr_color_is_set()

bool attr_color_is_set ( const struct AttrColor ac)

Is the object coloured?

Parameters
acColour to check
Return values
trueYes, a 'color' command has been used on this object

Definition at line 180 of file attr.c.

181{
182 if (!ac)
183 return false;
184
185 return ((ac->attrs != A_NORMAL) || ac->curses_color);
186}
+ Here is the caller graph for this function:

◆ attr_color_match()

bool attr_color_match ( struct AttrColor ac1,
struct AttrColor ac2 
)

Do the colours match?

Parameters
ac1First colour
ac2Second colour
Return values
trueThe colours and attributes match

Definition at line 194 of file attr.c.

195{
196 if ((!ac1) ^ (!ac2)) // One is set, but not the other
197 return false;
198
199 if (!ac1) // Two empty colours match
200 return true;
201
202 return ((ac1->curses_color == ac2->curses_color) && (ac1->attrs == ac2->attrs));
203}
+ Here is the caller graph for this function:

◆ modify_color_by_prefix()

void modify_color_by_prefix ( enum ColorPrefix  prefix,
bool  is_fg,
color_t col,
int *  attrs 
)

Modify a colour/attributes based on a prefix, e.g.

"bright"

Parameters
[in]prefixprefix to apply
[in]is_fgtrue if a foreground colour should be modified
[in,out]colcolour to modify
[in,out]attrsattributes to modify

Definition at line 212 of file attr.c.

213{
214 if (prefix == COLOR_PREFIX_NONE)
215 return; // nothing to do here
216
217 if (prefix == COLOR_PREFIX_ALERT)
218 {
219 *attrs |= A_BOLD;
220 *attrs |= A_BLINK;
221 }
222 else if (is_fg)
223 {
224 if ((COLORS >= 16) && (prefix == COLOR_PREFIX_LIGHT))
225 {
226 if (*col <= 7)
227 {
228 /* Advance the color 0-7 by 8 to get the light version */
229 *col += 8;
230 }
231 }
232 else
233 {
234 *attrs |= A_BOLD;
235 }
236 }
237 else
238 {
239 if (COLORS >= 16)
240 {
241 if (*col <= 7)
242 {
243 /* Advance the color 0-7 by 8 to get the light version */
244 *col += 8;
245 }
246 }
247 }
248}
@ COLOR_PREFIX_ALERT
"alert" colour prefix
Definition: attr.h:47
@ COLOR_PREFIX_LIGHT
"light" colour prefix
Definition: attr.h:49
+ Here is the caller graph for this function:

◆ color_xterm256_to_24bit()

color_t color_xterm256_to_24bit ( const color_t  color)

Convert a xterm color to its RGB value.

Parameters
[in]colorxterm color number to be converted
Return values
numThe color's RGB value as number with value 0xRRGGBB

There are 256 xterm colors numbered 0 to 255.

Caller contract: color must be between 0 and 255.

Xterm Color Codes

Basic and Bright Colors

  • 0-7 correspond to the 8 terminal colours
  • 8-15 are the bright variants of 0-7
0 #000000 1 #800000 2 #008000 3 #808000 4 #000080 5 #800080 6 #008080 7 #c0c0c0
8 #808080 9 #ff0000 10 #00ff00 11 #ffff00 12 #0000ff 13 #ff00ff 14 #00ffff 15 #ffffff

Color palette

16 #000000 17 #00005f 18 #000087 19 #0000af 20 #0000d7 21 #0000ff
22 #005f00 23 #005f5f 24 #005f87 25 #005faf 26 #005fd7 27 #005fff
28 #008700 29 #00875f 30 #008787 31 #0087af 32 #0087d7 33 #0087ff
34 #00af00 35 #00af5f 36 #00af87 37 #00afaf 38 #00afd7 39 #00afff
40 #00d700 41 #00d75f 42 #00d787 43 #00d7af 44 #00d7d7 45 #00d7ff
46 #00ff00 47 #00ff5f 48 #00ff87 49 #00ffaf 50 #00ffd7 51 #00ffff
52 #5f0000 53 #5f005f 54 #5f0087 55 #5f00af 56 #5f00d7 57 #5f00ff
58 #5f5f00 59 #5f5f5f 60 #5f5f87 61 #5f5faf 62 #5f5fd7 63 #5f5fff
64 #5f8700 65 #5f875f 66 #5f8787 67 #5f87af 68 #5f87d7 69 #5f87ff
70 #5faf00 71 #5faf5f 72 #5faf87 73 #5fafaf 74 #5fafd7 75 #5fafff
76 #5fd700 77 #5fd75f 78 #5fd787 79 #5fd7af 80 #5fd7d7 81 #5fd7ff
82 #5fff00 83 #5fff5f 84 #5fff87 85 #5fffaf 86 #5fffd7 87 #5fffff
88 #870000 89 #87005f 90 #870087 91 #8700af 92 #8700d7 93 #8700ff
94 #875f00 95 #875f5f 96 #875f87 97 #875faf 98 #875fd7 99 #875fff
100 #878700 101 #87875f 102 #878787 103 #8787af 104 #8787d7 105 #8787ff
106 #87af00 107 #87af5f 108 #87af87 109 #87afaf 110 #87afd7 111 #87afff
112 #87d700 113 #87d75f 114 #87d787 115 #87d7af 116 #87d7d7 117 #87d7ff
118 #87ff00 119 #87ff5f 120 #87ff87 121 #87ffaf 122 #87ffd7 123 #87ffff
124 #af0000 125 #af005f 126 #af0087 127 #af00af 128 #af00d7 129 #af00ff
130 #af5f00 131 #af5f5f 132 #af5f87 133 #af5faf 134 #af5fd7 135 #af5fff
136 #af8700 137 #af875f 138 #af8787 139 #af87af 140 #af87d7 141 #af87ff
142 #afaf00 143 #afaf5f 144 #afaf87 145 #afafaf 146 #afafd7 147 #afafff
148 #afd700 149 #afd75f 150 #afd787 151 #afd7af 152 #afd7d7 153 #afd7ff
154 #afff00 155 #afff5f 156 #afff87 157 #afffaf 158 #afffd7 159 #afffff
160 #d70000 161 #d7005f 162 #d70087 163 #d700af 164 #d700d7 165 #d700ff
166 #d75f00 167 #d75f5f 168 #d75f87 169 #d75faf 170 #d75fd7 171 #d75fff
172 #d78700 173 #d7875f 174 #d78787 175 #d787af 176 #d787d7 177 #d787ff
178 #d7af00 179 #d7af5f 180 #d7af87 181 #d7afaf 182 #d7afd7 183 #d7afff
184 #d7d700 185 #d7d75f 186 #d7d787 187 #d7d7af 188 #d7d7d7 189 #d7d7ff
190 #d7ff00 191 #d7ff5f 192 #d7ff87 193 #d7ffaf 194 #d7ffd7 195 #d7ffff
196 #ff0000 197 #ff005f 198 #ff0087 199 #ff00af 200 #ff00d7 201 #ff00ff
202 #ff5f00 203 #ff5f5f 204 #ff5f87 205 #ff5faf 206 #ff5fd7 207 #ff5fff
208 #ff8700 209 #ff875f 210 #ff8787 211 #ff87af 212 #ff87d7 213 #ff87ff
214 #ffaf00 215 #ffaf5f 216 #ffaf87 217 #ffafaf 218 #ffafd7 219 #ffafff
220 #ffd700 221 #ffd75f 222 #ffd787 223 #ffd7af 224 #ffd7d7 225 #ffd7ff
226 #ffff00 227 #ffff5f 228 #ffff87 229 #ffffaf 230 #ffffd7 231 #ffffff

Grey Scale Ramp

232 #080808 233 #121212 234 #1c1c1c 235 #262626 236 #303030 237 #3a3a3a 238 #444444 239 #4e4e4e
240 #585858 241 #626262 242 #6c6c6c 243 #767676 244 #808080 245 #8a8a8a 246 #949494 247 #9e9e9e
248 #a8a8a8 249 #b2b2b2 250 #bcbcbc 251 #c6c6c6 252 #d0d0d0 253 #dadada 254 #e4e4e4 255 #eeeeee

Definition at line 321 of file attr.c.

322{
323 static const color_t basic[] = {
324 0x000000, 0x800000, 0x008000, 0x808000, 0x000080, 0x800080,
325 0x008080, 0xc0c0c0, 0x808080, 0xff0000, 0x00ff00, 0xffff00,
326 0x0000ff, 0xff00ff, 0x00ffff, 0xffffff,
327 };
328
329 assert(color < 256);
330
331 if (color < 0)
332 return color;
333
334 const bool c_color_directcolor = cs_subset_bool(NeoMutt->sub, "color_directcolor");
335 if (!c_color_directcolor)
336 {
337 return color;
338 }
339
340 if (color < 16)
341 {
342 color_debug(LL_DEBUG5, "Converted color 0-15: %d\n", color);
343 /* The first 16 colours are the "usual" terminal colours */
344 return basic[color];
345 }
346
347 if (color < 232)
348 {
349 /* The Color palette is divided in 6x6x6 colours, i.e. each R, G, B channel
350 * has six values:
351 *
352 * value: 1 2 3 4 5 6
353 * color: 0x00 0x5f 0x87 0xaf 0xd7 0xff
354 *
355 * The steps between the values is 0x28 = 40, the EXCEPT for the first one
356 * where it is 0x5f = 95.
357 *
358 * If we express the xterm color number minus 16 to base 6, i.e.
359 *
360 * color - 16 = (vr * 36) + (vg * 6) + (vb * 1)
361 *
362 * with vr, vg, vb integers between 0 and 5, then vr, vg, vb is the channel
363 * value for red, green, and blue, respectively.
364 */
365
366 color_t normalised_color = color - 16;
367 color_t vr = (normalised_color % 216) / 36; /* 216 = 6*6*6 */
368 color_t vg = (normalised_color % 36) / 6;
369 color_t vb = (normalised_color % 6) / 1;
370
371 /* First step is wider than the other ones, so add the difference if needed */
372 color_t r = (vr * 0x28) + ((vr > 0) ? (0x5f - 0x28) : 0);
373 color_t g = (vg * 0x28) + ((vg > 0) ? (0x5f - 0x28) : 0);
374 color_t b = (vb * 0x28) + ((vb > 0) ? (0x5f - 0x28) : 0);
375
376 color_t rgb = (r << 16) + (g << 8) + (b << 0);
377 color_debug(LL_DEBUG5, "Converted xterm color %d to RGB #%x:\n", color, rgb);
378 return rgb;
379 }
380
381 /* Grey scale starts at 0x08 and adds 0xa = 10 in very step ending in 0xee.
382 * There are a total of 6*4 = 24 grey colors in total. */
383 color_t steps = color - 232;
384 color_t grey = (steps * 0x0a) + 0x08;
385 color_t rgb = (grey << 16) + (grey << 8) + (grey << 0);
386 color_debug(LL_DEBUG5, "Converted xterm color %d to RGB #%x:\n", color, rgb);
387 return rgb;
388}
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:48
int32_t color_t
Type for 24-bit colour value.
Definition: curses2.h:31
Container for Accounts, Notifications.
Definition: neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:45
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ attr_color_overwrite()

void attr_color_overwrite ( struct AttrColor ac_old,
struct AttrColor ac_new 
)

Update an AttrColor in-place.

Parameters
ac_oldAttrColor to overwrite
ac_newAttrColor to copy

Definition at line 396 of file attr.c.

397{
398 if (!ac_old || !ac_new)
399 return;
400
401 color_t fg = ac_new->fg.color;
402 color_t bg = ac_new->bg.color;
403 int attrs = ac_new->attrs;
404
405 modify_color_by_prefix(ac_new->fg.prefix, true, &fg, &attrs);
406 modify_color_by_prefix(ac_new->bg.prefix, false, &bg, &attrs);
407
408#ifdef NEOMUTT_DIRECT_COLORS
409 if ((ac_new->fg.type == CT_SIMPLE) || (ac_new->fg.type == CT_PALETTE))
411 else if (fg < 8)
412 fg = 8;
413 if ((ac_new->bg.type == CT_SIMPLE) || (ac_new->bg.type == CT_PALETTE))
415 else if (bg < 8)
416 bg = 8;
417#endif
418
419 struct CursesColor *cc = curses_color_new(fg, bg);
421 ac_old->fg = ac_new->fg;
422 ac_old->bg = ac_new->bg;
423 ac_old->attrs = attrs;
424 ac_old->curses_color = cc;
425}
color_t color_xterm256_to_24bit(const color_t color)
Convert a xterm color to its RGB value.
Definition: attr.c:321
void modify_color_by_prefix(enum ColorPrefix prefix, bool is_fg, color_t *col, int *attrs)
Modify a colour/attributes based on a prefix, e.g.
Definition: attr.c:212
@ CT_PALETTE
Palette colour, e.g. "color207".
Definition: attr.h:37
struct CursesColor * curses_color_new(color_t fg, color_t bg)
Create a new CursesColor.
Definition: curses.c:151
+ Here is the call graph for this function:
+ Here is the caller graph for this function: