Annotation of src/usr.bin/tmux/style.c, Revision 1.12
1.12 ! nicm 1: /* $OpenBSD: style.c,v 1.11 2017/01/12 15:36:35 nicm Exp $ */
1.1 nicm 2:
3: /*
1.9 nicm 4: * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
1.1 nicm 5: * Copyright (c) 2014 Tiago Cunha <tcunha@users.sourceforge.net>
6: *
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.
10: *
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.
18: */
1.4 nicm 19:
20: #include <sys/types.h>
1.1 nicm 21:
22: #include <string.h>
23:
24: #include "tmux.h"
25:
26: /* Parse an embedded style of the form "fg=colour,bg=colour,bright,...". */
27: int
28: style_parse(const struct grid_cell *defgc, struct grid_cell *gc,
29: const char *in)
30: {
1.5 nicm 31: struct grid_cell savedgc;
32: const char delimiters[] = " ,";
33: char tmp[32];
34: int val;
35: size_t end;
1.10 nicm 36: int fg, bg;
37: u_char attr, flags;
1.1 nicm 38:
39: if (*in == '\0')
40: return (0);
41: if (strchr(delimiters, in[strlen(in) - 1]) != NULL)
42: return (-1);
1.5 nicm 43: memcpy(&savedgc, gc, sizeof savedgc);
1.1 nicm 44:
45: fg = gc->fg;
46: bg = gc->bg;
47: attr = gc->attr;
48: flags = gc->flags;
49: do {
50: end = strcspn(in, delimiters);
51: if (end > (sizeof tmp) - 1)
1.5 nicm 52: goto error;
1.1 nicm 53: memcpy(tmp, in, end);
54: tmp[end] = '\0';
55:
56: if (strcasecmp(tmp, "default") == 0) {
57: fg = defgc->fg;
58: bg = defgc->bg;
59: attr = defgc->attr;
1.10 nicm 60: flags = defgc->flags;
1.1 nicm 61: } else if (end > 3 && strncasecmp(tmp + 1, "g=", 2) == 0) {
62: if ((val = colour_fromstring(tmp + 3)) == -1)
1.5 nicm 63: goto error;
1.1 nicm 64: if (*in == 'f' || *in == 'F') {
1.10 nicm 65: if (val != 8)
1.1 nicm 66: fg = val;
1.10 nicm 67: else
1.1 nicm 68: fg = defgc->fg;
69: } else if (*in == 'b' || *in == 'B') {
1.10 nicm 70: if (val != 8)
1.1 nicm 71: bg = val;
1.10 nicm 72: else
1.1 nicm 73: bg = defgc->bg;
74: } else
1.5 nicm 75: goto error;
1.1 nicm 76: } else if (strcasecmp(tmp, "none") == 0)
77: attr = 0;
78: else if (end > 2 && strncasecmp(tmp, "no", 2) == 0) {
79: if ((val = attributes_fromstring(tmp + 2)) == -1)
1.5 nicm 80: goto error;
1.1 nicm 81: attr &= ~val;
82: } else {
83: if ((val = attributes_fromstring(tmp)) == -1)
1.5 nicm 84: goto error;
1.1 nicm 85: attr |= val;
86: }
87:
88: in += end + strspn(in + end, delimiters);
89: } while (*in != '\0');
90: gc->fg = fg;
91: gc->bg = bg;
92: gc->attr = attr;
93: gc->flags = flags;
94:
95: return (0);
1.5 nicm 96:
97: error:
98: memcpy(gc, &savedgc, sizeof *gc);
99: return (-1);
1.1 nicm 100: }
101:
102: /* Convert style to a string. */
103: const char *
104: style_tostring(struct grid_cell *gc)
105: {
1.10 nicm 106: int off = 0, comma = 0;
1.1 nicm 107: static char s[256];
108:
109: *s = '\0';
110:
1.10 nicm 111: if (gc->fg != 8) {
112: off += xsnprintf(s, sizeof s, "fg=%s", colour_tostring(gc->fg));
1.1 nicm 113: comma = 1;
114: }
115:
1.10 nicm 116: if (gc->bg != 8) {
1.1 nicm 117: off += xsnprintf(s + off, sizeof s - off, "%sbg=%s",
1.10 nicm 118: comma ? "," : "", colour_tostring(gc->bg));
1.1 nicm 119: comma = 1;
120: }
121:
122: if (gc->attr != 0 && gc->attr != GRID_ATTR_CHARSET) {
123: xsnprintf(s + off, sizeof s - off, "%s%s",
124: comma ? "," : "", attributes_tostring(gc->attr));
125: }
126:
127: if (*s == '\0')
128: return ("default");
129: return (s);
130: }
131:
132: /* Synchronize new -style option with the old one. */
133: void
134: style_update_new(struct options *oo, const char *name, const char *newname)
135: {
136: int value;
137: struct grid_cell *gc;
1.6 nicm 138: struct options_entry *o;
1.1 nicm 139:
140: /* It's a colour or attribute, but with no -style equivalent. */
141: if (newname == NULL)
142: return;
143:
1.6 nicm 144: o = options_find1(oo, newname);
145: if (o == NULL)
1.11 nicm 146: o = options_set_style(oo, newname, 0, "default");
1.6 nicm 147: gc = &o->style;
148:
149: o = options_find1(oo, name);
150: if (o == NULL)
1.7 nicm 151: o = options_set_number(oo, name, 8);
1.6 nicm 152: value = o->num;
1.1 nicm 153:
154: if (strstr(name, "-bg") != NULL)
1.10 nicm 155: gc->bg = value;
1.1 nicm 156: else if (strstr(name, "-fg") != NULL)
1.10 nicm 157: gc->fg = value;
1.1 nicm 158: else if (strstr(name, "-attr") != NULL)
159: gc->attr = value;
160: }
161:
162: /* Synchronize all the old options with the new -style one. */
163: void
164: style_update_old(struct options *oo, const char *name, struct grid_cell *gc)
165: {
166: char newname[128];
1.10 nicm 167: int size;
1.1 nicm 168:
169: size = strrchr(name, '-') - name;
170:
171: xsnprintf(newname, sizeof newname, "%.*s-bg", size, name);
1.10 nicm 172: options_set_number(oo, newname, gc->bg);
1.1 nicm 173:
174: xsnprintf(newname, sizeof newname, "%.*s-fg", size, name);
1.10 nicm 175: options_set_number(oo, newname, gc->fg);
1.1 nicm 176:
177: xsnprintf(newname, sizeof newname, "%.*s-attr", size, name);
178: options_set_number(oo, newname, gc->attr);
179: }
180:
181: /* Apply a style. */
182: void
183: style_apply(struct grid_cell *gc, struct options *oo, const char *name)
184: {
1.12 ! nicm 185: const struct grid_cell *gcp;
1.1 nicm 186:
187: memcpy(gc, &grid_default_cell, sizeof *gc);
188: gcp = options_get_style(oo, name);
1.10 nicm 189: gc->fg = gcp->fg;
190: gc->bg = gcp->bg;
1.1 nicm 191: gc->attr |= gcp->attr;
192: }
193:
194: /* Apply a style, updating if default. */
195: void
196: style_apply_update(struct grid_cell *gc, struct options *oo, const char *name)
197: {
1.12 ! nicm 198: const struct grid_cell *gcp;
1.1 nicm 199:
200: gcp = options_get_style(oo, name);
1.10 nicm 201: if (gcp->fg != 8)
202: gc->fg = gcp->fg;
203: if (gcp->bg != 8)
204: gc->bg = gcp->bg;
1.1 nicm 205: if (gcp->attr != 0)
206: gc->attr |= gcp->attr;
1.8 nicm 207: }
208:
209: /* Check if two styles are the same. */
210: int
211: style_equal(const struct grid_cell *gc1, const struct grid_cell *gc2)
212: {
1.10 nicm 213: return (gc1->fg == gc2->fg &&
214: gc1->bg == gc2->bg &&
215: (gc1->flags & ~GRID_FLAG_PADDING) ==
216: (gc2->flags & ~GRID_FLAG_PADDING) &&
217: (gc1->attr & ~GRID_ATTR_CHARSET) ==
218: (gc2->attr & ~GRID_ATTR_CHARSET));
1.1 nicm 219: }