Change terminal-overrides to a server option (now that we have them), it
[tmux-openbsd.git] / style.c
blob99744086df7f11bf57386f61481b70b772bd6193
1 /* $OpenBSD$ */
3 /*
4 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
5 * Copyright (c) 2014 Tiago Cunha <tcunha@users.sourceforge.net>
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
16 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
17 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #include <string.h>
22 #include "tmux.h"
24 /* Parse an embedded style of the form "fg=colour,bg=colour,bright,...". */
25 int
26 style_parse(const struct grid_cell *defgc, struct grid_cell *gc,
27 const char *in)
29 const char delimiters[] = " ,";
30 char tmp[32];
31 int val;
32 size_t end;
33 u_char fg, bg, attr, flags;
35 if (*in == '\0')
36 return (0);
37 if (strchr(delimiters, in[strlen(in) - 1]) != NULL)
38 return (-1);
40 fg = gc->fg;
41 bg = gc->bg;
42 attr = gc->attr;
43 flags = gc->flags;
44 do {
45 end = strcspn(in, delimiters);
46 if (end > (sizeof tmp) - 1)
47 return (-1);
48 memcpy(tmp, in, end);
49 tmp[end] = '\0';
51 if (strcasecmp(tmp, "default") == 0) {
52 fg = defgc->fg;
53 bg = defgc->bg;
54 attr = defgc->attr;
55 flags &= ~(GRID_FLAG_FG256|GRID_FLAG_BG256);
56 flags |=
57 defgc->flags & (GRID_FLAG_FG256|GRID_FLAG_BG256);
58 } else if (end > 3 && strncasecmp(tmp + 1, "g=", 2) == 0) {
59 if ((val = colour_fromstring(tmp + 3)) == -1)
60 return (-1);
61 if (*in == 'f' || *in == 'F') {
62 if (val != 8) {
63 if (val & 0x100) {
64 flags |= GRID_FLAG_FG256;
65 val &= ~0x100;
66 } else
67 flags &= ~GRID_FLAG_FG256;
68 fg = val;
69 } else {
70 fg = defgc->fg;
71 flags &= ~GRID_FLAG_FG256;
72 flags |= defgc->flags & GRID_FLAG_FG256;
74 } else if (*in == 'b' || *in == 'B') {
75 if (val != 8) {
76 if (val & 0x100) {
77 flags |= GRID_FLAG_BG256;
78 val &= ~0x100;
79 } else
80 flags &= ~GRID_FLAG_BG256;
81 bg = val;
82 } else {
83 bg = defgc->bg;
84 flags &= ~GRID_FLAG_BG256;
85 flags |= defgc->flags & GRID_FLAG_BG256;
87 } else
88 return (-1);
89 } else if (strcasecmp(tmp, "none") == 0)
90 attr = 0;
91 else if (end > 2 && strncasecmp(tmp, "no", 2) == 0) {
92 if ((val = attributes_fromstring(tmp + 2)) == -1)
93 return (-1);
94 attr &= ~val;
95 } else {
96 if ((val = attributes_fromstring(tmp)) == -1)
97 return (-1);
98 attr |= val;
101 in += end + strspn(in + end, delimiters);
102 } while (*in != '\0');
103 gc->fg = fg;
104 gc->bg = bg;
105 gc->attr = attr;
106 gc->flags = flags;
108 return (0);
111 /* Convert style to a string. */
112 const char *
113 style_tostring(struct grid_cell *gc)
115 int c, off = 0, comma = 0;
116 static char s[256];
118 *s = '\0';
120 if (gc->fg != 8) {
121 if (gc->flags & GRID_FLAG_FG256)
122 c = gc->fg | 0x100;
123 else
124 c = gc->fg;
125 off += xsnprintf(s, sizeof s, "fg=%s", colour_tostring(c));
126 comma = 1;
129 if (gc->bg != 8) {
130 if (gc->flags & GRID_FLAG_BG256)
131 c = gc->bg | 0x100;
132 else
133 c = gc->bg;
134 off += xsnprintf(s + off, sizeof s - off, "%sbg=%s",
135 comma ? "," : "", colour_tostring(c));
136 comma = 1;
139 if (gc->attr != 0 && gc->attr != GRID_ATTR_CHARSET) {
140 xsnprintf(s + off, sizeof s - off, "%s%s",
141 comma ? "," : "", attributes_tostring(gc->attr));
144 if (*s == '\0')
145 return ("default");
146 return (s);
149 /* Synchronize new -style option with the old one. */
150 void
151 style_update_new(struct options *oo, const char *name, const char *newname)
153 int value;
154 struct grid_cell *gc;
156 /* It's a colour or attribute, but with no -style equivalent. */
157 if (newname == NULL)
158 return;
160 gc = options_get_style(oo, newname);
161 value = options_get_number(oo, name);
163 if (strstr(name, "-bg") != NULL)
164 colour_set_bg(gc, value);
165 else if (strstr(name, "-fg") != NULL)
166 colour_set_fg(gc, value);
167 else if (strstr(name, "-attr") != NULL)
168 gc->attr = value;
171 /* Synchronize all the old options with the new -style one. */
172 void
173 style_update_old(struct options *oo, const char *name, struct grid_cell *gc)
175 char newname[128];
176 int c, size;
178 size = strrchr(name, '-') - name;
180 if (gc->flags & GRID_FLAG_BG256)
181 c = gc->bg | 0x100;
182 else
183 c = gc->bg;
184 xsnprintf(newname, sizeof newname, "%.*s-bg", size, name);
185 options_set_number(oo, newname, c);
187 if (gc->flags & GRID_FLAG_FG256)
188 c = gc->fg | 0x100;
189 else
190 c = gc->fg;
191 xsnprintf(newname, sizeof newname, "%.*s-fg", size, name);
192 options_set_number(oo, newname, c);
194 xsnprintf(newname, sizeof newname, "%.*s-attr", size, name);
195 options_set_number(oo, newname, gc->attr);
198 /* Apply a style. */
199 void
200 style_apply(struct grid_cell *gc, struct options *oo, const char *name)
202 struct grid_cell *gcp;
204 memcpy(gc, &grid_default_cell, sizeof *gc);
205 gcp = options_get_style(oo, name);
206 if (gcp->flags & GRID_FLAG_FG256)
207 colour_set_fg(gc, gcp->fg | 0x100);
208 else
209 colour_set_fg(gc, gcp->fg);
210 if (gcp->flags & GRID_FLAG_BG256)
211 colour_set_bg(gc, gcp->bg | 0x100);
212 else
213 colour_set_bg(gc, gcp->bg);
214 gc->attr |= gcp->attr;
217 /* Apply a style, updating if default. */
218 void
219 style_apply_update(struct grid_cell *gc, struct options *oo, const char *name)
221 struct grid_cell *gcp;
223 gcp = options_get_style(oo, name);
224 if (gcp->fg != 8) {
225 if (gcp->flags & GRID_FLAG_FG256)
226 colour_set_fg(gc, gcp->fg | 0x100);
227 else
228 colour_set_fg(gc, gcp->fg);
230 if (gcp->bg != 8) {
231 if (gcp->flags & GRID_FLAG_BG256)
232 colour_set_bg(gc, gcp->bg | 0x100);
233 else
234 colour_set_bg(gc, gcp->bg);
236 if (gcp->attr != 0)
237 gc->attr |= gcp->attr;