NeoMutt  2021-10-29-225-gb9986f
Teaching an old dog new tricks
DOXYGEN
color.c
Go to the documentation of this file.
1 
30 #include "config.h"
31 #include <stdbool.h>
32 #include <stdint.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include "mutt/lib.h"
37 #include "config/lib.h"
38 #include "email/lib.h"
39 #include "core/lib.h"
40 #include "gui/lib.h"
41 #include "mutt.h"
42 #include "lib.h"
43 #include "pattern/lib.h"
44 #include "context.h"
45 #include "init.h"
46 #include "mutt_globals.h"
47 #include "options.h"
48 
51 
55 struct ColorList
56 {
57  /* TrueColor uses 24bit. Use fixed-width integer type to make sure it fits.
58  * Use the upper 8 bits to store flags. */
59  uint32_t fg;
60  uint32_t bg;
61  short index;
62  short ref_count;
63  struct ColorList *next;
64 };
65 
66 const struct Mapping ColorNames[] = {
67  // clang-format off
68  { "black", COLOR_BLACK },
69  { "blue", COLOR_BLUE },
70  { "cyan", COLOR_CYAN },
71  { "green", COLOR_GREEN },
72  { "magenta", COLOR_MAGENTA },
73  { "red", COLOR_RED },
74  { "white", COLOR_WHITE },
75  { "yellow", COLOR_YELLOW },
76  { "default", COLOR_DEFAULT },
77  { 0, 0 },
78  // clang-format on
79 };
80 
85 static void color_list_free(struct ColorList **ptr)
86 {
87  if (!ptr || !*ptr)
88  return;
89 
90  struct ColorList *cl = *ptr;
91  struct ColorList *next = NULL;
92 
93  while (cl)
94  {
95  next = cl->next;
96  FREE(&cl);
97  cl = next;
98  }
99  *ptr = NULL;
100 }
101 
109 void mutt_color_free(uint32_t fg, uint32_t bg)
110 {
111  struct ColorList *q = NULL;
112 
113  struct ColorList *p = UserColors;
114  while (p)
115  {
116  if ((p->fg == fg) && (p->bg == bg))
117  {
118  (p->ref_count)--;
119  if (p->ref_count > 0)
120  return;
121 
122  NumUserColors--;
123  mutt_debug(LL_DEBUG1, "Color pairs used so far: %d\n", NumUserColors);
124 
125  if (p == UserColors)
126  {
128  FREE(&p);
129  return;
130  }
131  q = UserColors;
132  while (q)
133  {
134  if (q->next == p)
135  {
136  q->next = p->next;
137  FREE(&p);
138  return;
139  }
140  q = q->next;
141  }
142  /* can't get here */
143  }
144  p = p->next;
145  }
146 }
147 
151 void colors_clear(void)
152 {
156 
158 }
159 
164 {
165  colors_clear();
167 }
168 
173 {
178 
179  start_color();
180 }
181 
188 int mutt_color_alloc(uint32_t fg, uint32_t bg)
189 {
190  struct ColorList *p = UserColors;
191 
192  /* check to see if this color is already allocated to save space */
193  while (p)
194  {
195  if ((p->fg == fg) && (p->bg == bg))
196  {
197  (p->ref_count)++;
198  return COLOR_PAIR(p->index);
199  }
200  p = p->next;
201  }
202 
203  /* check to see if there are colors left */
204  if (++NumUserColors > COLOR_PAIRS)
205  return A_NORMAL;
206 
207  /* find the smallest available index (object) */
208  int i = 1;
209  while (true)
210  {
211  p = UserColors;
212  while (p)
213  {
214  if (p->index == i)
215  break;
216  p = p->next;
217  }
218  if (!p)
219  break;
220  i++;
221  }
222 
223  /* Check for pair overflow too.
224  * We are currently using init_pair(), which only accepts size short. */
225  if (i > SHRT_MAX)
226  return (0);
227 
228  p = mutt_mem_malloc(sizeof(struct ColorList));
229  p->next = UserColors;
230  UserColors = p;
231 
232  p->index = i;
233  p->ref_count = 1;
234  p->bg = bg;
235  p->fg = fg;
236 
237  if (fg == COLOR_DEFAULT)
238  fg = COLOR_UNSET;
239  if (bg == COLOR_DEFAULT)
240  bg = COLOR_UNSET;
241  init_pair(i, fg, bg);
242 
243  mutt_debug(LL_DEBUG3, "Color pairs used so far: %d\n", NumUserColors);
244 
245  return COLOR_PAIR(p->index);
246 }
247 
256 static int mutt_lookup_color(short pair, uint32_t *fg, uint32_t *bg)
257 {
258  struct ColorList *p = UserColors;
259 
260  while (p)
261  {
262  if (COLOR_PAIR(p->index) == pair)
263  {
264  if (fg)
265  *fg = p->fg;
266  if (bg)
267  *bg = p->bg;
268  return 0;
269  }
270  p = p->next;
271  }
272  return -1;
273 }
274 
281 int mutt_color_combine(uint32_t fg_attr, uint32_t bg_attr)
282 {
283  uint32_t fg = COLOR_DEFAULT;
284  uint32_t bg = COLOR_DEFAULT;
285 
286  mutt_lookup_color(fg_attr, &fg, NULL);
287  mutt_lookup_color(bg_attr, NULL, &bg);
288 
289  if ((fg == COLOR_DEFAULT) && (bg == COLOR_DEFAULT))
290  return A_NORMAL;
291  return mutt_color_alloc(fg, bg);
292 }
void color_notify_free(void)
Free the Colour notification.
Definition: notify.c:47
void color_notify_init(void)
Initialise the Colour notification.
Definition: notify.c:38
void regex_colors_clear(void)
Clear the Regex colours.
Definition: regex.c:112
void regex_colors_init(void)
Initialise the Regex colours.
Definition: regex.c:96
void simple_colors_init(void)
Initialise the simple colour definitions.
Definition: simple.c:41
void simple_colors_clear(void)
Reset the simple colour definitions.
Definition: simple.c:58
struct ColorList * UserColors
Array of user colours.
Definition: color.c:49
const struct Mapping ColorNames[]
Definition: color.c:66
int NumUserColors
Number of user colours.
Definition: color.c:50
static int mutt_lookup_color(short pair, uint32_t *fg, uint32_t *bg)
Get the colours from a colour pair.
Definition: color.c:256
void mutt_colors_cleanup(void)
Cleanup all the colours.
Definition: color.c:163
void mutt_color_free(uint32_t fg, uint32_t bg)
Free a colour.
Definition: color.c:109
static void color_list_free(struct ColorList **ptr)
Free the list of curses colours.
Definition: color.c:85
int mutt_color_combine(uint32_t fg_attr, uint32_t bg_attr)
Combine two colours.
Definition: color.c:281
int mutt_color_alloc(uint32_t fg, uint32_t bg)
Allocate a colour pair.
Definition: color.c:188
void mutt_colors_init(void)
Initialize colours.
Definition: color.c:172
void colors_clear(void)
Reset all the colours.
Definition: color.c:151
#define COLOR_DEFAULT
Definition: color.h:103
#define COLOR_UNSET
Definition: color.h:104
Convenience wrapper for the config headers.
The "currently-open" mailbox.
Convenience wrapper for the core headers.
Structs that make up an email.
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
Convenience wrapper for the gui headers.
Config/command parsing.
@ LL_DEBUG3
Log at debug level 3.
Definition: logging.h:42
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
#define FREE(x)
Definition: memory.h:40
Convenience wrapper for the library headers.
Many unsorted constants and some structs.
Hundreds of global variables to back the user variables.
Handling of global boolean variables.
Match patterns to emails.
void quoted_colors_init(void)
Initialise the quoted-email colours.
Definition: quoted.c:53
void quoted_colors_clear(void)
Reset the quoted-email colours.
Definition: quoted.c:44
Key value store.
A set of colors.
Definition: color.c:56
struct ColorList * next
Linked list.
Definition: color.c:63
short index
Index number.
Definition: color.c:61
uint32_t fg
Foreground colour.
Definition: color.c:59
uint32_t bg
Background colour.
Definition: color.c:60
short ref_count
Number of users.
Definition: color.c:62
Mapping between user-readable string and a constant.
Definition: mapping.h:32