1 /*
2  * color.c
3  *
4  * Copyright (C) 2003, 2007 Staf Wagemakers Belgie/Belgium
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  *
20  */
21 
22 #include "color.h"
23 
24 chtype color_ch[]={ COLOR_BLACK,COLOR_RED,COLOR_GREEN,COLOR_YELLOW,
25 	            COLOR_BLUE,COLOR_MAGENTA,COLOR_CYAN,COLOR_WHITE };
26 char *color_names[] = {"black","red","green","yellow","blue",
27 	               "magenta","cyan", "white",NULL };
28 chtype attribute_ch[] = {A_NORMAL,A_BOLD,A_UNDERLINE,A_REVERSE,A_STANDOUT};
29 char *attribute_names[] = {"normal","bold","underline","reverse","standout",NULL};
30 
new_color_table(char ** color_vars)31 struct color * new_color_table ( char **color_vars ) {
32 	struct color *ret;
33 	int t=0,members=20;
34 	char **ccp;
35 	ret=xcalloc(members,sizeof(struct color));
36 	ccp=color_vars;
37 	while(*ccp!=NULL) {
38 		if(t>members-1) {
39 			members+=20;
40 			ret=xrealloc(ret,members*sizeof(struct color));
41 		}
42 		ret[t].color_pair=t+1;
43 		ret[t].fg=COLOR_WHITE;
44 		ret[t].bg=COLOR_BLACK;
45 		ret[t].attr=A_NORMAL;
46 		init_pair(t,COLOR_WHITE,COLOR_BLACK);
47 		ret[t].ch=COLOR_PAIR(ret[t].color_pair)|ret[t].attr;
48 		ret[t].name=xmalloc(strlen(*ccp)+1);
49 		strcpy(ret[t].name,*ccp);
50 		++t;
51 		++ccp;
52 	}
53 	ret=xrealloc(ret,(t+1)*sizeof(struct color));
54 	ret[t].name=NULL;
55 	return(ret);
56 }
57 
delete_color_table(struct color * color_table)58 void delete_color_table( struct color * color_table ) {
59 	struct color *color_p=color_table;
60 
61 	while(color_p->name!=NULL) {
62 		xfree(color_p->name);
63 		color_p++;
64 	}
65 	xfree(color_table);
66 }
67 
name_to_chtype(char * color_name,char ** color_names,chtype * chtype_array)68 chtype name_to_chtype(char *color_name,char **color_names, chtype *chtype_array) {
69 	char **ccp;
70 	int t=0;
71 	chtype ret=(chtype) -1;
72 	ccp=color_names;
73 	if(color_name==NULL) return(ret);
74 	while(*ccp!=NULL) {
75 		if(!strcmp(color_name,*ccp)) {
76                   ret=chtype_array[t];
77 		  break;
78 		 }
79 		 ++t;
80 		 ++ccp;
81  	}
82 
83 	return(ret);
84 }
85 
chtype_to_name(chtype color,char ** color_names,chtype * chtype_array)86 char * chtype_to_name(chtype color,char **color_names, chtype *chtype_array) {
87        char **ccp;
88        int t=0;
89        char *ret=NULL;
90        ccp=color_names;
91        while(*ccp!=NULL) {
92 	    if(color==chtype_array[t]) {
93                 ret=xmalloc(strlen(color_names[t])+1);
94 		strcpy(ret,color_names[t]);
95                 break;
96             }
97        ++t;
98        ++ccp;
99        }
100        return(ret);
101 }
102 
chtype_to_number(chtype color,char ** color_names,chtype * chtype_array)103 int chtype_to_number(chtype color,char **color_names, chtype *chtype_array) {
104        char **ccp;
105        int t=0;
106        int ret=-1;
107        ccp=color_names;
108        while(*ccp!=NULL) {
109             if(color==chtype_array[t]) {
110               ret=t;
111               break;
112             }
113             ++t;
114             ++ccp;
115        }
116        return(ret);
117 }
118 
color_to_number(chtype color)119 int color_to_number(chtype color) {
120 	int ret=chtype_to_number(color,color_names,color_ch);
121 	return(ret);
122 }
123 
number_to_color(int n)124 chtype number_to_color(int n) {
125 	return(color_ch[n]);
126 }
127 
number_to_attr(int n)128 chtype number_to_attr(int n) {
129 	return(attribute_ch[n]);
130 }
131 
132 
attr_to_number(chtype color)133 int attr_to_number(chtype color) {
134 	int ret=chtype_to_number(color,attribute_names,attribute_ch);
135 	return(ret);
136 }
137 
138 
139 
read_config_colors(FILE * fp,struct color * color_table,int mode)140 void read_config_colors (FILE *fp, struct color *color_table, int mode ) {
141 	chtype fg,bg,attr;
142 	char txt_color[]="color";
143 	char txt_mono[]="mono";
144 	char **ccp,*color_type=txt_color;
145 	struct color *color_p;
146 	color_p=color_table;
147 	if(mode) {
148 		color_type=txt_mono;
149 	}
150 	while((ccp=get_next_config_var_array(fp,color_type))!=NULL) {
151 	  if(ccp[0]==NULL) {
152              free_string_array(ccp);
153 	     continue;
154 	  }
155 	color_p=color_table;
156 	while(color_p->name!=NULL) {
157 	  if(!strcmp(ccp[0],color_p->name)) {
158 	    if(!mode) {
159               fg=name_to_chtype(ccp[1],color_names,color_ch);
160 	      bg=name_to_chtype(ccp[2],color_names,color_ch);
161 	      attr=name_to_chtype(ccp[3],attribute_names,attribute_ch);
162 	      if(fg!=-1) color_p->fg=fg;
163 	      if(bg!=-1) color_p->bg=bg;
164 	      if(attr!=-1) color_p->attr=attr;
165 	    }
166 	    else {
167 	       fg=name_to_chtype(ccp[1],attribute_names,attribute_ch);
168 	       bg=name_to_chtype(ccp[2],attribute_names,attribute_ch);
169 	       if(fg!=-1) color_p->fg=fg;
170 	         else color_p->fg=A_NORMAL;
171 	       if(bg!=-1) color_p->bg=bg;
172 	         else color_p->bg=A_NORMAL;
173 	       color_p->attr=color_p->fg|color_p->bg;
174 	    }
175 	    init_pair(color_p->color_pair,color_p->fg,color_p->bg);
176 	    if(!mode)
177 	      color_p->ch=COLOR_PAIR(color_p->color_pair)|color_p->attr;
178 	    else
179 	      color_p->ch=COLOR_PAIR(0)|color_p->attr;
180 	    break;
181 	   }
182 	color_p++;
183 	}
184 		free_string_array(ccp);
185 	}
186 }
187 
get_color(char * name,struct color * color_table)188 chtype get_color(char *name,struct color *color_table) {
189         struct color *color_p=color_table;
190 	chtype ret=COLOR_PAIR(0);
191 
192         while(color_p->name!=NULL) {
193 	     if(!strcmp(color_p->name,name)) {
194 	       ret=color_p->ch;
195 	       break;
196 	       }
197              color_p++;
198         }
199 
200 	return(ret);
201 
202 }
set_color(char * name,struct color * color_table,chtype fg,chtype bg,chtype attr,int color_mode)203 int set_color(char *name,struct color *color_table, chtype fg,chtype bg,chtype attr,int color_mode) {
204        struct color *color_p=color_table;
205        int ret=-1;
206 
207        while(color_p->name!=NULL) {
208          if(!strcmp(color_p->name,name)) {
209 	   ret=0;
210 	   color_p->fg=fg;
211 	   color_p->bg=bg;
212 	   color_p->attr=attr;
213 	   if(!color_mode) {
214 	      init_pair(color_p->color_pair,color_p->fg,color_p->bg);
215 	      color_p->ch=COLOR_PAIR(color_p->color_pair)|color_p->attr;
216 	   }
217 	   else {
218 	       color_p->attr=color_p->fg|color_p->bg;
219 	       color_p->ch=COLOR_PAIR(0)|color_p->attr;
220 	   }
221               break;
222          }
223          color_p++;
224        }
225 
226        return(ret);
227 
228 }
save_colors(FILE * fp,struct color * colors,int color_mode)229 void save_colors(FILE *fp,struct color *colors,int color_mode) {
230 	char txt_color[]="color";
231 	char txt_mono[]="mono";
232 	char txt_null[]="\0";
233 	char *color_type=txt_color;
234 	struct color *color_p;
235 	char *line;
236 	char **cccp;
237 	char *fg_name=NULL;
238 	char *bg_name=NULL;
239 	char *attr_name=NULL;
240 	color_p=colors;
241 	cccp=color_names;
242 	while(color_p->name!=NULL) {
243 	     if(!color_mode) {
244 
245 	     	 fg_name=chtype_to_name(color_p->fg,color_names,color_ch);
246 		 if(fg_name==NULL) fg_name=txt_null;
247 		 bg_name=chtype_to_name(color_p->bg,color_names,color_ch);
248 		 if(bg_name==NULL) bg_name=txt_null;
249 		 attr_name=chtype_to_name(color_p->attr,attribute_names,attribute_ch);
250 		 if(attr_name==NULL) attr_name=txt_null;
251 
252 	     }
253 	     else {
254 		 color_type=txt_mono;
255 		 fg_name=chtype_to_name(color_p->fg,attribute_names,attribute_ch);
256 		 if(fg_name==NULL) fg_name=txt_null;
257 		 bg_name=chtype_to_name(color_p->bg,attribute_names,attribute_ch);
258 		 if(bg_name==NULL) bg_name=txt_null;
259 		 attr_name=txt_null;
260 	     }
261 
262 	     line=xmalloc(strlen(color_type)+strlen(" ")+strlen(color_p->name)+strlen("\t")+strlen(fg_name)+strlen("\t")+strlen(bg_name)+strlen("\t")+strlen(attr_name)+1);
263 	     strcpy(line,color_type);
264 	     strcat(line," ");
265 	     strcat(line,color_p->name);
266 	     strcat(line,"\t");
267 	     strcat(line,fg_name);
268 	     strcat(line,"\t");
269 	     strcat(line,bg_name);
270 	     strcat(line,"\t");
271 	     strcat(line,attr_name);
272 
273 	     fputs(line,fp);
274 	     fputs("\n",fp);
275 	     xfree(line);
276 	     if(fg_name!=txt_null) xfree(fg_name);
277 	     if(bg_name!=txt_null) xfree(bg_name);
278 	     if(attr_name!=txt_null) xfree(attr_name);
279 	     ++color_p;
280 	}
281 }
282 
cp_color(struct color * color1,struct color * color2)283 void cp_color(struct color *color1,struct color *color2) {
284 	color1->fg=color2->fg;
285 	color1->bg=color2->bg;
286 	color1->attr=color2->attr;
287 	color1->ch=color2->ch;
288 	color1->color_pair=color2->color_pair;
289 	color1->name=color2->name;
290 }
291 
color_array_members(struct color * color_array)292 int color_array_members (struct color *color_array) {
293 	struct color *color_p;
294 	int ret=1;
295 	if(color_array==NULL) return(-1);
296 	color_p=color_array;
297 	while(color_p->name!=NULL)  {
298 		++ret;
299 		++color_p;
300 	}
301 	return(ret);
302 }
303 
cp_color_array(struct color * color1_array,struct color * color2_array)304 void cp_color_array(struct color *color1_array,struct color *color2_array) {
305 	unsigned u;
306 	for(u=0;color2_array[u].name!=NULL;u++) {
307 		cp_color(&color1_array[u],&color2_array[u]);
308 	}
309 	cp_color(&color1_array[u],&color2_array[u]);
310 }
311 
reinit_color_table(struct color * colors,int mode)312 void reinit_color_table (struct color *colors,int mode) {
313 	struct color *color_p=colors;
314 	if(color_p==NULL) return;
315 	while(color_p->name!=NULL) {
316 		set_color(color_p->name,colors,color_p->fg,color_p->bg,color_p->attr,mode);
317 		color_p++;
318 	}
319 }
320 
321