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