1 /*
2  * Copyright (C) 2000-2017 the xine project
3  *
4  * This file is part of xine, a unix video player.
5  *
6  * xine 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  * xine 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
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19  *
20  */
21 
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 
26 #include <stdio.h>
27 #include <string.h>
28 
29 #include "_xitk.h"
30 
31 /*
32  * Extract color values
33  */
xitk_config_colors(xitk_config_t * xtcf)34 static void xitk_config_colors(xitk_config_t *xtcf) {
35   char  *p = NULL;
36   char  *c = NULL;
37   int    pixel;
38 
39   ABORT_IF_NULL(xtcf);
40   ABORT_IF_NULL(xtcf->ln);
41 
42   p = xtcf->ln + 6;
43   if(p)
44     c = strchr(p, '=');
45 
46   if(c) {
47 
48     *(c++) = '\0';
49 
50     while(*c == ' ' || *c == '\t') c++;
51 
52     if((strchr(c, '#')) || (isalpha(*c))) {
53       xitk_color_names_t *color;
54 
55       if((color = xitk_get_color_name(c)) != NULL) {
56 	/*
57 	 * We can't use xitk_get_pixel_from_rgb() here,
58 	 * 'cause we didn't have any ImlibData object.
59 	 */
60 	pixel = ((color->red & 0xf8) << 8) |
61 	  ((color->green & 0xf8) << 3) |
62 	  ((color->blue & 0xf8) >> 3);
63 
64 	xitk_free_color_name(color);
65       }
66       else {
67 	XITK_WARNING("%s@%d: wrong color name: '%s'\n", __FUNCTION__, __LINE__, c);
68 	pixel = 0;
69       }
70     }
71     else
72       sscanf(c, "%d", &pixel);
73 
74     if(!strncasecmp(p, "warning_foreground", 15))
75       xtcf->colors.warn_foreground = pixel;
76     else if(!strncasecmp(p, "warning_background", 15))
77       xtcf->colors.warn_background = pixel;
78     else if(!strncasecmp(p, "background", 10))
79       xtcf->colors.background = pixel;
80     else if(!strncasecmp(p, "select", 6))
81       xtcf->colors.select = pixel;
82     else if(!strncasecmp(p, "focus", 5))
83       xtcf->colors.focus = pixel;
84     else if(!strncasecmp(p, "black", 5))
85       xtcf->colors.black = pixel;
86     else if(!strncasecmp(p, "white", 5))
87       xtcf->colors.white = pixel;
88 
89   }
90 }
91 
92 /*
93  * Extract font names.
94  */
xitk_config_fonts(xitk_config_t * xtcf)95 static void xitk_config_fonts(xitk_config_t *xtcf) {
96   char  *p = NULL;
97   char  *c = NULL;
98 
99   ABORT_IF_NULL(xtcf);
100   ABORT_IF_NULL(xtcf->ln);
101 
102   p = xtcf->ln + 5;
103   if(p)
104     c = strchr(p, '=');
105 
106   if(c) {
107 
108     *(c++) = '\0';
109 
110     while(*c == ' ' || *c == '\t') c++;
111 
112     if(!strncasecmp(p, "default", 7))
113       xtcf->fonts.fallback = strdup(c);
114     else if(!strncasecmp(p, "system", 6)) {
115       xtcf->fonts.system = (char *) realloc(xtcf->fonts.system, (strlen(c) + 1));
116       strcpy(xtcf->fonts.system, c);
117     }
118     else if(!strncasecmp(p, "xmb", 3)) {
119       xtcf->fonts.xmb = ((strtol(c, &c, 10)) >= 1) ? 1 : 0;
120     }
121 
122   }
123 }
124 
125 /*
126  * Extract timer.
127  */
xitk_config_timers(xitk_config_t * xtcf)128 static void xitk_config_timers(xitk_config_t *xtcf) {
129   char  *p = NULL;
130   char  *c = NULL;
131 
132   ABORT_IF_NULL(xtcf);
133   ABORT_IF_NULL(xtcf->ln);
134 
135   p = xtcf->ln + 6;
136   if(p)
137     c = strchr(p, '=');
138 
139   if(c) {
140 
141     *(c++) = '\0';
142 
143     while(*c == ' ' || *c == '\t') c++;
144 
145     if(!strncasecmp(p, "label_animation", 15))
146       xtcf->timers.label_anim = strtol(c, &c, 10);
147     else if(!strncasecmp(p, "double_click", 12))
148       xtcf->timers.dbl_click = strtol(c, &c, 10);
149   }
150 }
151 
152 /*
153  * Extract features.
154  */
xitk_config_features(xitk_config_t * xtcf)155 static void xitk_config_features(xitk_config_t *xtcf) {
156   char  *p = NULL;
157   char  *c = NULL;
158 
159   ABORT_IF_NULL(xtcf);
160   ABORT_IF_NULL(xtcf->ln);
161 
162   p = xtcf->ln + 8;
163   if(p)
164     c = strchr(p, '=');
165 
166   if(c) {
167 
168     *(c++) = '\0';
169 
170     while(*c == ' ' || *c == '\t') c++;
171 
172     if(!strncasecmp(p, "old_title_style", 15))
173       xtcf->features.oldbarstyle = strtol(c, &c, 10);
174     if(!strncasecmp(p, "check_style", 11)) {
175       if(!strcasecmp(c, "old"))
176 	xtcf->features.checkstyle = CHECK_STYLE_OLD;
177       else if(!strcasecmp(c, "round"))
178 	xtcf->features.checkstyle = CHECK_STYLE_ROUND;
179       else if(!strcasecmp(c, "check"))
180 	xtcf->features.checkstyle = CHECK_STYLE_CHECK;
181     }
182     else if(!strncasecmp(p, "cursors", 7))
183       xtcf->features.cursors = xitk_get_bool_value(c);
184     else if(!strncasecmp(p, "shm", 3))
185       xtcf->features.shm = strtol(c, &c, 10);
186   }
187 }
188 
189 /*
190  * menus.
191  */
xitk_config_menus(xitk_config_t * xtcf)192 static void xitk_config_menus(xitk_config_t *xtcf) {
193   char  *p = NULL;
194   char  *c = NULL;
195 
196   ABORT_IF_NULL(xtcf);
197   ABORT_IF_NULL(xtcf->ln);
198 
199   p = xtcf->ln + 6;
200   if(p)
201     c = strchr(p, '=');
202 
203   if(c) {
204 
205     *(c++) = '\0';
206 
207     while(*c == ' ' || *c == '\t') c++;
208 
209     if(!strncasecmp(p, "shortcuts", 9))
210       xtcf->menus.shortcuts = xitk_get_bool_value(c);
211   }
212 }
213 
214 /*
215  * Guess entries.
216  */
xitk_config_store_entry(xitk_config_t * xtcf)217 static void xitk_config_store_entry(xitk_config_t *xtcf) {
218 
219   ABORT_IF_NULL(xtcf);
220 
221   if(!strncasecmp(xtcf->ln, "feature.", 8))
222     xitk_config_features(xtcf);
223   else if(!strncasecmp(xtcf->ln, "color.", 6))
224     xitk_config_colors(xtcf);
225   else if(!strncasecmp(xtcf->ln, "timer.", 6))
226     xitk_config_timers(xtcf);
227   else if(!strncasecmp(xtcf->ln, "menus.", 6))
228     xitk_config_menus(xtcf);
229   else if(!strncasecmp(xtcf->ln, "font.", 5))
230     xitk_config_fonts(xtcf);
231 
232 }
233 
234 /*
235  * Cleanup the EOL ('\n','\r',' ')
236  */
xitk_config_clean_eol(xitk_config_t * xtcf)237 static void xitk_config_clean_eol(xitk_config_t *xtcf) {
238   char *p;
239 
240   ABORT_IF_NULL(xtcf);
241 
242   p = xtcf->ln;
243 
244   if(p) {
245     while(*p != '\0') {
246       if(*p == '\n' || *p == '\r') {
247 	*p = '\0';
248 	break;
249       }
250       p++;
251     }
252 
253     while(p > xtcf->ln) {
254       --p;
255 
256       if(*p == ' ')
257 	*p = '\0';
258       else
259 	break;
260     }
261   }
262 }
263 
264 /*
265  * Read next line from file.
266  */
xitk_config_get_next_line(xitk_config_t * xtcf)267 static void xitk_config_get_next_line(xitk_config_t *xtcf) {
268 
269   ABORT_IF_NULL(xtcf);
270   ABORT_IF_NULL(xtcf->fd);
271 
272  __get_next_line:
273 
274   xtcf->ln = fgets(xtcf->buf, 255, xtcf->fd);
275 
276   while(xtcf->ln && (*xtcf->ln == ' ' || *xtcf->ln == '\t')) ++xtcf->ln;
277 
278   if(xtcf->ln) {
279     if((strncmp(xtcf->ln, "//", 2) == 0) ||
280        (strncmp(xtcf->ln, "/*", 2) == 0) || /**/
281        (strncmp(xtcf->ln, ";", 1) == 0) ||
282        (strncmp(xtcf->ln, "#", 1) == 0)) {
283       goto __get_next_line;
284     }
285   }
286 
287   xitk_config_clean_eol(xtcf);
288 }
289 
290 /*
291  * load config file.
292  */
xitk_config_load_configfile(xitk_config_t * xtcf)293 static void xitk_config_load_configfile(xitk_config_t *xtcf) {
294   ABORT_IF_NULL(xtcf);
295 
296   xitk_config_get_next_line(xtcf);
297 
298   while(xtcf->ln != NULL) {
299 
300     xitk_config_store_entry(xtcf);
301 
302     xitk_config_get_next_line(xtcf);
303   }
304 
305   fclose(xtcf->fd);
306 
307 }
308 
309 /*
310  * Initialiaze values to default.
311  */
xitk_config_init_default_values(xitk_config_t * xtcf)312 static void xitk_config_init_default_values(xitk_config_t *xtcf) {
313   ABORT_IF_NULL(xtcf);
314 
315   xtcf->fonts.system           = strdup("fixed");
316   xtcf->fonts.fallback         = NULL;
317 #ifdef WITH_XMB
318   xtcf->fonts.xmb              = 1;
319 #else
320   xtcf->fonts.xmb              = 0;
321 #endif
322   xtcf->colors.black           = -1;
323   xtcf->colors.white           = -1;
324   xtcf->colors.background      = -1;
325   xtcf->colors.focus           = -1;
326   xtcf->colors.select          = -1;
327   xtcf->colors.warn_foreground = -1;
328   xtcf->colors.warn_background = -1;
329   xtcf->timers.label_anim      = 50000;
330   xtcf->timers.dbl_click       = 400;
331 #ifdef DISABLE_SHM_DEFAULT
332   xtcf->features.shm           = 0;
333 #else
334   xtcf->features.shm           = 1;
335 #endif
336   xtcf->features.oldbarstyle   = 0;
337   xtcf->features.checkstyle    = CHECK_STYLE_CHECK;
338   xtcf->features.cursors       = 0;
339   xtcf->menus.shortcuts        = 1;
340 }
341 
342 /*
343  * Get stored values.
344  */
xitk_config_get_barstyle_feature(xitk_config_t * xtcf)345 int xitk_config_get_barstyle_feature(xitk_config_t *xtcf) {
346 
347   if(!xtcf)
348     return -1;
349 
350   return (xtcf->features.oldbarstyle > 0) ? 1 : 0;
351 }
xitk_config_get_checkstyle_feature(xitk_config_t * xtcf)352 int xitk_config_get_checkstyle_feature(xitk_config_t *xtcf) {
353 
354   if(!xtcf)
355     return -1;
356 
357   return xtcf->features.checkstyle;
358 }
xitk_config_get_shm_feature(xitk_config_t * xtcf)359 int xitk_config_get_shm_feature(xitk_config_t *xtcf) {
360 
361   if(!xtcf)
362     return -1;
363 
364   return (xtcf->features.shm > 0) ? 1 : 0;
365 }
xitk_config_get_cursors_feature(xitk_config_t * xtcf)366 int xitk_config_get_cursors_feature(xitk_config_t *xtcf) {
367 
368   if(!xtcf)
369     return -1;
370 
371   return (xtcf->features.cursors > 0) ? 1 : 0;
372 }
xitk_config_get_system_font(xitk_config_t * xtcf)373 const char *xitk_config_get_system_font(xitk_config_t *xtcf) {
374 
375   if(!xtcf)
376     return NULL;
377 
378   return xtcf->fonts.system;
379 }
xitk_config_get_default_font(xitk_config_t * xtcf)380 const char *xitk_config_get_default_font(xitk_config_t *xtcf) {
381 
382   if(!xtcf)
383     return NULL;
384 
385   return xtcf->fonts.fallback;
386 }
xitk_config_get_xmb_enability(xitk_config_t * xtcf)387 int xitk_config_get_xmb_enability(xitk_config_t *xtcf) {
388 
389   if(!xtcf)
390     return -1;
391 
392   return xtcf->fonts.xmb;
393 }
xitk_config_set_xmb_enability(xitk_config_t * xtcf,int value)394 void xitk_config_set_xmb_enability(xitk_config_t *xtcf, int value) {
395 
396   if(xtcf)
397     xtcf->fonts.xmb = (value >= 1) ? 1 : 0;
398 }
xitk_config_get_black_color(xitk_config_t * xtcf)399 int xitk_config_get_black_color(xitk_config_t *xtcf) {
400 
401   if(!xtcf)
402     return -1;
403 
404   return xtcf->colors.black;
405 }
xitk_config_get_white_color(xitk_config_t * xtcf)406 int xitk_config_get_white_color(xitk_config_t *xtcf) {
407 
408   if(!xtcf)
409     return -1;
410 
411   return xtcf->colors.white;
412 }
xitk_config_get_background_color(xitk_config_t * xtcf)413 int xitk_config_get_background_color(xitk_config_t *xtcf) {
414 
415   if(!xtcf)
416     return -1;
417 
418   return xtcf->colors.background;
419 }
xitk_config_get_focus_color(xitk_config_t * xtcf)420 int xitk_config_get_focus_color(xitk_config_t *xtcf) {
421 
422   if(!xtcf)
423     return -1;
424 
425   return xtcf->colors.focus;
426 }
xitk_config_get_select_color(xitk_config_t * xtcf)427 int xitk_config_get_select_color(xitk_config_t *xtcf) {
428 
429   if(!xtcf)
430     return -1;
431 
432   return xtcf->colors.select;
433 }
xitk_config_get_timer_label_animation(xitk_config_t * xtcf)434 unsigned long xitk_config_get_timer_label_animation(xitk_config_t *xtcf) {
435 
436   if(!xtcf)
437     return 5000;
438 
439   return xtcf->timers.label_anim;
440 }
xitk_config_get_timer_dbl_click(xitk_config_t * xtcf)441 long xitk_config_get_timer_dbl_click(xitk_config_t *xtcf) {
442 
443   if(!xtcf)
444     return 200;
445 
446   return xtcf->timers.dbl_click;
447 }
xitk_config_get_warning_foreground(xitk_config_t * xtcf)448 unsigned long xitk_config_get_warning_foreground(xitk_config_t *xtcf) {
449 
450   if(!xtcf)
451     return -1;
452 
453   return xtcf->colors.warn_foreground;
454 }
xitk_config_get_warning_background(xitk_config_t * xtcf)455 unsigned long xitk_config_get_warning_background(xitk_config_t *xtcf) {
456 
457   if(!xtcf)
458     return -1;
459 
460   return xtcf->colors.warn_background;
461 }
xitk_config_get_menu_shortcuts_enability(xitk_config_t * xtcf)462 int xitk_config_get_menu_shortcuts_enability(xitk_config_t *xtcf) {
463 
464   if(!xtcf)
465     return -1;
466 
467   return xtcf->menus.shortcuts;
468 }
469 
470 #define SYSTEM_RC  "/etc/xitkrc"
471 /*
472  * Initialize config stuff.
473  */
xitk_config_init(void)474 xitk_config_t *xitk_config_init(void) {
475   xitk_config_t *xtcf;
476   char          *rcfile;
477   const char    *user_rc = "xitkrc";
478 
479   xtcf = (xitk_config_t *) xitk_xmalloc(sizeof(xitk_config_t));
480 
481   rcfile = (char *) xitk_xmalloc(strlen(xine_get_homedir()) + strlen(user_rc) + 3);
482   sprintf(rcfile, "%s/.%s", xine_get_homedir(), user_rc);
483 
484   if((xtcf->fd = fopen(rcfile, "r")) == NULL) {
485     rcfile = (char *) realloc(rcfile, strlen(rcfile) + 6);
486     sprintf(rcfile, "%s/.xine/%s", xine_get_homedir(), user_rc);
487     if((xtcf->fd = fopen(rcfile, "r")) == NULL) {
488       rcfile = (char *) realloc(rcfile, (strlen(SYSTEM_RC) + 1));
489       strcpy(rcfile, SYSTEM_RC);
490       if((xtcf->fd = fopen(rcfile, "r")) == NULL) {
491         XITK_FREE(rcfile);
492         rcfile = NULL;
493       }
494     }
495   }
496 
497   xtcf->cfgfilename = rcfile;
498 
499   xitk_config_init_default_values(xtcf);
500 
501   if(rcfile)
502     xitk_config_load_configfile(xtcf);
503 
504   return xtcf;
505 }
506 
507 /*
508  * Release memory from config object.
509  */
xitk_config_deinit(xitk_config_t * xtcf)510 void xitk_config_deinit(xitk_config_t *xtcf) {
511 
512   if(!xtcf)
513     return;
514 
515   XITK_FREE(xtcf->cfgfilename);
516   XITK_FREE(xtcf->fonts.fallback);
517   XITK_FREE(xtcf->fonts.system);
518   XITK_FREE(xtcf);
519 }
520