1 #include "private.h"
2 
3 #include <Elementary.h>
4 #include <Efreet.h>
5 #include "config.h"
6 #include "main.h"
7 #include "colors.h"
8 #include "theme.h"
9 
10 #define CONF_VER 26
11 #define CONFIG_KEY "config"
12 
13 #define LIM(v, min, max) {if (v >= max) v = max; else if (v <= min) v = min;}
14 
15 static Eet_Data_Descriptor *edd_base = NULL;
16 static Eet_Data_Descriptor *edd_color = NULL;
17 static Eet_Data_Descriptor *edd_keys = NULL;
18 
19 static const char *
_config_home_get(void)20 _config_home_get(void)
21 {
22    return efreet_config_home_get();
23 }
24 
25 void
config_init(void)26 config_init(void)
27 {
28    Eet_Data_Descriptor_Class eddc;
29    Eet_Data_Descriptor_Class eddkc;
30    char path[PATH_MAX] = {};
31 
32    elm_need_efreet();
33    efreet_init();
34 
35    snprintf(path, sizeof(path) -1, "%s/terminology/themes",
36             _config_home_get());
37    ecore_file_mkpath(path);
38 
39 
40    eet_eina_stream_data_descriptor_class_set
41      (&eddc, sizeof(eddc), "Config_Color", sizeof(Color));
42    edd_color = eet_data_descriptor_stream_new(&eddc);
43 
44    EET_DATA_DESCRIPTOR_ADD_BASIC
45      (edd_color, Color, "r", r, EET_T_UCHAR);
46    EET_DATA_DESCRIPTOR_ADD_BASIC
47      (edd_color, Color, "g", g, EET_T_UCHAR);
48    EET_DATA_DESCRIPTOR_ADD_BASIC
49      (edd_color, Color, "b", b, EET_T_UCHAR);
50    EET_DATA_DESCRIPTOR_ADD_BASIC
51      (edd_color, Color, "a", a, EET_T_UCHAR);
52 
53 
54    eet_eina_stream_data_descriptor_class_set
55      (&eddkc, sizeof(eddkc), "Config_Keys", sizeof(Config_Keys));
56    edd_keys = eet_data_descriptor_stream_new(&eddkc);
57 
58    EET_DATA_DESCRIPTOR_ADD_BASIC
59      (edd_keys, Config_Keys, "keyname", keyname, EET_T_STRING);
60    EET_DATA_DESCRIPTOR_ADD_BASIC
61      (edd_keys, Config_Keys, "ctrl", ctrl, EET_T_UCHAR);
62    EET_DATA_DESCRIPTOR_ADD_BASIC
63      (edd_keys, Config_Keys, "alt", alt, EET_T_UCHAR);
64    EET_DATA_DESCRIPTOR_ADD_BASIC
65      (edd_keys, Config_Keys, "shift", shift, EET_T_UCHAR);
66    EET_DATA_DESCRIPTOR_ADD_BASIC
67      (edd_keys, Config_Keys, "win", win, EET_T_UCHAR);
68    EET_DATA_DESCRIPTOR_ADD_BASIC
69      (edd_keys, Config_Keys, "meta", meta, EET_T_UCHAR);
70    EET_DATA_DESCRIPTOR_ADD_BASIC
71      (edd_keys, Config_Keys, "hyper", hyper, EET_T_UCHAR);
72    EET_DATA_DESCRIPTOR_ADD_BASIC
73      (edd_keys, Config_Keys, "cb", cb, EET_T_STRING);
74 
75 
76    eet_eina_stream_data_descriptor_class_set
77      (&eddc, sizeof(eddc), "Config", sizeof(Config));
78    edd_base = eet_data_descriptor_stream_new(&eddc);
79 
80    EET_DATA_DESCRIPTOR_ADD_BASIC
81      (edd_base, Config, "version", version, EET_T_INT);
82    EET_DATA_DESCRIPTOR_ADD_BASIC
83      (edd_base, Config, "font.name", font.name, EET_T_STRING);
84    EET_DATA_DESCRIPTOR_ADD_BASIC
85      (edd_base, Config, "font.size", font.size, EET_T_INT);
86    EET_DATA_DESCRIPTOR_ADD_BASIC
87      (edd_base, Config, "font.bitmap", font.bitmap, EET_T_UCHAR);
88    EET_DATA_DESCRIPTOR_ADD_BASIC
89      (edd_base, Config, "font.bolditalic", font.bolditalic, EET_T_UCHAR);
90    EET_DATA_DESCRIPTOR_ADD_BASIC
91      (edd_base, Config, "helper.email", helper.email, EET_T_STRING);
92    EET_DATA_DESCRIPTOR_ADD_BASIC
93      (edd_base, Config, "helper.url.general", helper.url.general, EET_T_STRING);
94    EET_DATA_DESCRIPTOR_ADD_BASIC
95      (edd_base, Config, "helper.url.video", helper.url.video, EET_T_STRING);
96    EET_DATA_DESCRIPTOR_ADD_BASIC
97      (edd_base, Config, "helper.url.image", helper.url.image, EET_T_STRING);
98    EET_DATA_DESCRIPTOR_ADD_BASIC
99      (edd_base, Config, "helper.local.general", helper.local.general, EET_T_STRING);
100    EET_DATA_DESCRIPTOR_ADD_BASIC
101      (edd_base, Config, "helper.local.video", helper.local.video, EET_T_STRING);
102    EET_DATA_DESCRIPTOR_ADD_BASIC
103      (edd_base, Config, "helper.local.image", helper.local.image, EET_T_STRING);
104    EET_DATA_DESCRIPTOR_ADD_BASIC
105      (edd_base, Config, "helper.inline_please", helper.inline_please, EET_T_UCHAR);
106    EET_DATA_DESCRIPTOR_ADD_BASIC
107      (edd_base, Config, "theme", theme, EET_T_STRING);
108    EET_DATA_DESCRIPTOR_ADD_BASIC
109      (edd_base, Config, "color_scheme_name", color_scheme_name, EET_T_STRING);
110    EET_DATA_DESCRIPTOR_ADD_BASIC
111      (edd_base, Config, "background", background, EET_T_STRING);
112    EET_DATA_DESCRIPTOR_ADD_BASIC
113      (edd_base, Config, "scrollback", scrollback, EET_T_INT);
114    EET_DATA_DESCRIPTOR_ADD_BASIC
115      (edd_base, Config, "tab_zoom", tab_zoom, EET_T_DOUBLE);
116    EET_DATA_DESCRIPTOR_ADD_BASIC
117      (edd_base, Config, "vidmod", _vidmod, EET_T_INT); /* DEPRECATED */
118    EET_DATA_DESCRIPTOR_ADD_BASIC
119      (edd_base, Config, "jump_on_change", jump_on_change, EET_T_UCHAR);
120    EET_DATA_DESCRIPTOR_ADD_BASIC
121      (edd_base, Config, "jump_on_keypress", jump_on_keypress, EET_T_UCHAR);
122    EET_DATA_DESCRIPTOR_ADD_BASIC
123      (edd_base, Config, "flicker_on_key", flicker_on_key, EET_T_UCHAR);
124    EET_DATA_DESCRIPTOR_ADD_BASIC
125      (edd_base, Config, "disable_cursor_blink", disable_cursor_blink, EET_T_UCHAR);
126    EET_DATA_DESCRIPTOR_ADD_BASIC
127      (edd_base, Config, "cursor_shape", cursor_shape, EET_T_INT);
128    EET_DATA_DESCRIPTOR_ADD_BASIC
129      (edd_base, Config, "disable_visual_bell", disable_visual_bell, EET_T_UCHAR);
130    EET_DATA_DESCRIPTOR_ADD_BASIC /* DEPRECATED */
131      (edd_base, Config, "active_links", active_links, EET_T_UCHAR);
132    EET_DATA_DESCRIPTOR_ADD_BASIC
133      (edd_base, Config, "active_links_email", active_links_email, EET_T_UCHAR);
134    EET_DATA_DESCRIPTOR_ADD_BASIC
135      (edd_base, Config, "active_links_file", active_links_file, EET_T_UCHAR);
136    EET_DATA_DESCRIPTOR_ADD_BASIC
137      (edd_base, Config, "active_links_url", active_links_url, EET_T_UCHAR);
138    EET_DATA_DESCRIPTOR_ADD_BASIC
139      (edd_base, Config, "active_links_escape", active_links_escape, EET_T_UCHAR);
140    EET_DATA_DESCRIPTOR_ADD_BASIC
141      (edd_base, Config, "active_links_color", active_links_color, EET_T_UCHAR);
142    EET_DATA_DESCRIPTOR_ADD_BASIC
143      (edd_base, Config, "translucent", translucent, EET_T_UCHAR);
144    EET_DATA_DESCRIPTOR_ADD_BASIC
145      (edd_base, Config, "opacity", opacity, EET_T_INT);
146    EET_DATA_DESCRIPTOR_ADD_BASIC
147      (edd_base, Config, "mute", mute, EET_T_UCHAR);
148    EET_DATA_DESCRIPTOR_ADD_BASIC
149      (edd_base, Config, "visualize", visualize, EET_T_UCHAR);
150    EET_DATA_DESCRIPTOR_ADD_BASIC
151      (edd_base, Config, "urg_bell", urg_bell, EET_T_UCHAR);
152    EET_DATA_DESCRIPTOR_ADD_BASIC
153      (edd_base, Config, "multi_instance", multi_instance, EET_T_UCHAR);
154    EET_DATA_DESCRIPTOR_ADD_BASIC
155      (edd_base, Config, "xterm_256color", xterm_256color, EET_T_UCHAR);
156    EET_DATA_DESCRIPTOR_ADD_BASIC
157      (edd_base, Config, "erase_is_del", erase_is_del, EET_T_UCHAR);
158    EET_DATA_DESCRIPTOR_ADD_BASIC
159      (edd_base, Config, "custom_geometry", custom_geometry, EET_T_UCHAR);
160    EET_DATA_DESCRIPTOR_ADD_BASIC
161      (edd_base, Config, "cg_width", cg_width, EET_T_INT);
162    EET_DATA_DESCRIPTOR_ADD_BASIC
163      (edd_base, Config, "cg_height", cg_height, EET_T_INT);
164    EET_DATA_DESCRIPTOR_ADD_BASIC
165      (edd_base, Config, "drag_links", drag_links, EET_T_UCHAR);
166    EET_DATA_DESCRIPTOR_ADD_BASIC
167      (edd_base, Config, "login_shell", login_shell, EET_T_UCHAR);
168    EET_DATA_DESCRIPTOR_ADD_BASIC
169      (edd_base, Config, "mouse_over_focus",
170       mouse_over_focus, EET_T_UCHAR);
171    EET_DATA_DESCRIPTOR_ADD_BASIC
172      (edd_base, Config, "disable_focus_visuals",
173       disable_focus_visuals, EET_T_UCHAR);
174    EET_DATA_DESCRIPTOR_ADD_BASIC
175      (edd_base, Config, "colors_use", colors_use, EET_T_UCHAR);
176    EET_DATA_DESCRIPTOR_ADD_ARRAY
177      (edd_base, Config, "colors", colors, edd_color);
178    EET_DATA_DESCRIPTOR_ADD_BASIC
179      (edd_base, Config, "bell_rings", bell_rings, EET_T_UCHAR);
180    EET_DATA_DESCRIPTOR_ADD_LIST
181      (edd_base, Config, "keys", keys, edd_keys);
182    EET_DATA_DESCRIPTOR_ADD_BASIC
183      (edd_base, Config, "gravatar", gravatar, EET_T_UCHAR);
184    EET_DATA_DESCRIPTOR_ADD_BASIC /* DEPRECATED, NO LONGER USED */
185      (edd_base, Config, "notabs", notabs, EET_T_UCHAR);
186    EET_DATA_DESCRIPTOR_ADD_BASIC
187      (edd_base, Config, "show_tabs", show_tabs, EET_T_UCHAR);
188    EET_DATA_DESCRIPTOR_ADD_BASIC
189      (edd_base, Config, "mv_always_show", mv_always_show, EET_T_UCHAR);
190    EET_DATA_DESCRIPTOR_ADD_BASIC
191      (edd_base, Config, "ty_escapes", ty_escapes, EET_T_UCHAR);
192    EET_DATA_DESCRIPTOR_ADD_BASIC
193      (edd_base, Config, "changedir_to_current", changedir_to_current, EET_T_UCHAR);
194    EET_DATA_DESCRIPTOR_ADD_BASIC
195      (edd_base, Config, "emoji_dbl_width", emoji_dbl_width, EET_T_UCHAR);
196    EET_DATA_DESCRIPTOR_ADD_BASIC
197      (edd_base, Config, "shine", shine, EET_T_INT);
198    EET_DATA_DESCRIPTOR_ADD_BASIC
199      (edd_base, Config, "hide_cursor", hide_cursor, EET_T_DOUBLE);
200    EET_DATA_DESCRIPTOR_ADD_BASIC
201      (edd_base, Config, "group_all", group_all, EET_T_UCHAR);
202 }
203 
204 void
config_shutdown(void)205 config_shutdown(void)
206 {
207    eet_data_descriptor_free(edd_base);
208    edd_base = NULL;
209 
210    eet_data_descriptor_free(edd_color);
211    edd_color = NULL;
212 
213    efreet_shutdown();
214 }
215 
216 void
config_save(Config * config)217 config_save(Config *config)
218 {
219    Eet_File *ef;
220    char buf[PATH_MAX], buf2[PATH_MAX];
221    const char *cfgdir;
222    int ok;
223    Eet_Error err;
224 
225    EINA_SAFETY_ON_NULL_RETURN(config);
226 
227    if (config->temporary)
228      {
229         main_config_sync(config);
230         return;
231      }
232    config->font.orig_size = config->font.size;
233    eina_stringshare_del(config->font.orig_name);
234    config->font.orig_name = NULL;
235    if (config->font.name) config->font.orig_name = eina_stringshare_add(config->font.name);
236    config->font.orig_bitmap = config->font.bitmap;
237 
238    cfgdir = _config_home_get();
239    snprintf(buf, sizeof(buf), "%s/terminology/config/standard", cfgdir);
240    ecore_file_mkpath(buf);
241    snprintf(buf, sizeof(buf), "%s/terminology/config/standard/base.cfg.tmp", cfgdir);
242    snprintf(buf2, sizeof(buf2), "%s/terminology/config/standard/base.cfg", cfgdir);
243    ef = eet_open(buf, EET_FILE_MODE_WRITE);
244    if (!ef)
245      {
246         ERR("error opening file '%s' for writing", buf);
247         return;
248      }
249    ok = eet_data_write(ef, edd_base, CONFIG_KEY, config, 1);
250    if (!ok)
251      {
252         eet_close(ef);
253         ERR("error writing to file '%s'", buf);
254         return;
255      }
256    err = eet_close(ef);
257    if (err != EET_ERROR_NONE)
258      {
259         ERR("error #%d closing file '%s'", err, buf);
260         return;
261      }
262    if (!ecore_file_mv(buf, buf2))
263      {
264         ERR("error moving file '%s' to '%s'", buf, buf2);
265         return;
266      }
267    main_config_sync(config);
268 }
269 
270 void
config_sync(const Config * config_src,Config * config)271 config_sync(const Config *config_src, Config *config)
272 {
273    // SOME fields have to be consistent between configs
274    config->font.size = config_src->font.size;
275    eina_stringshare_replace(&(config->font.name), config_src->font.name);
276    config->font.bitmap = config_src->font.bitmap;
277    config->font.bolditalic = config_src->font.bolditalic;
278    config->helper.inline_please = config_src->helper.inline_please;
279    eina_stringshare_replace(&(config->helper.email), config_src->helper.email);
280    eina_stringshare_replace(&(config->helper.url.general), config_src->helper.url.general);
281    eina_stringshare_replace(&(config->helper.url.video), config_src->helper.url.video);
282    eina_stringshare_replace(&(config->helper.url.image), config_src->helper.url.image);
283    eina_stringshare_replace(&(config->helper.local.general), config_src->helper.local.general);
284    eina_stringshare_replace(&(config->helper.local.video), config_src->helper.local.video);
285    eina_stringshare_replace(&(config->helper.local.image), config_src->helper.local.image);
286    eina_stringshare_replace(&(config->theme), config_src->theme);
287    eina_stringshare_replace(&(config->color_scheme_name), config_src->color_scheme_name);
288    config->scrollback = config_src->scrollback;
289    config->tab_zoom = config_src->tab_zoom;
290    config->hide_cursor = config_src->hide_cursor;
291    config->jump_on_keypress = config_src->jump_on_keypress;
292    config->jump_on_change = config_src->jump_on_change;
293    config->flicker_on_key = config_src->flicker_on_key;
294    config->disable_cursor_blink = config_src->disable_cursor_blink;
295    config->cursor_shape = config_src->cursor_shape;
296    config->disable_visual_bell = config_src->disable_visual_bell;
297    config->bell_rings = config_src->bell_rings;
298    config->active_links_email = config_src->active_links_email;
299    config->active_links_file = config_src->active_links_file;
300    config->active_links_url = config_src->active_links_url;
301    config->active_links_escape = config_src->active_links_escape;
302    config->active_links_color = config_src->active_links_color;
303    config->mute = config_src->mute;
304    config->visualize = config_src->visualize;
305    config->urg_bell = config_src->urg_bell;
306    config->multi_instance = config_src->multi_instance;
307    config->xterm_256color = config_src->xterm_256color;
308    config->erase_is_del = config_src->erase_is_del;
309    config->temporary = config_src->temporary;
310    config->custom_geometry = config_src->custom_geometry;
311    config->login_shell = config_src->login_shell;
312    config->cg_width = config_src->cg_width;
313    config->cg_height = config_src->cg_height;
314    config->colors_use = config_src->colors_use;
315    memcpy(config->colors, config_src->colors, sizeof(config->colors));
316    config->mouse_over_focus = config_src->mouse_over_focus;
317    config->disable_focus_visuals = config_src->disable_focus_visuals;
318    /* TODO: config->keys */
319    config->gravatar = config_src->gravatar;
320    config->show_tabs = config_src->show_tabs;
321    config->mv_always_show = config_src->mv_always_show;
322    config->ty_escapes = config_src->ty_escapes;
323    config->changedir_to_current = config_src->changedir_to_current;
324    config->emoji_dbl_width = config_src->emoji_dbl_width;
325    config->shine = config_src->shine;
326    config->translucent = config_src->translucent;
327    config->opacity = config_src->opacity;
328    config->group_all = config_src->group_all;
329 }
330 
331 static void
_config_upgrade_to_v2(Config * config)332 _config_upgrade_to_v2(Config *config)
333 {
334    int i, j;
335 
336    /* Colors */
337    config->colors_use = EINA_FALSE;
338    for (j = 0; j < 4; j++)
339      {
340         for (i = 0; i < 12; i++)
341           {
342              unsigned char rr = 0, gg = 0, bb = 0, aa = 0;
343 
344              colors_standard_get(j, i, &rr, &gg, &bb, &aa);
345              config->colors[(j * 12) + i].r = rr;
346              config->colors[(j * 12) + i].g = gg;
347              config->colors[(j * 12) + i].b = bb;
348              config->colors[(j * 12) + i].a = aa;
349           }
350      }
351    config->version = 2;
352 }
353 
354 #define ADD_KB(Name, Ctrl, Alt, Shift, Win, Cb)                   \
355    kb = calloc(1, sizeof(Config_Keys));                           \
356    if (!kb) return;                                               \
357    kb->keyname = eina_stringshare_add_length(Name, strlen(Name)); \
358    kb->ctrl = Ctrl;                                               \
359    kb->alt = Alt;                                                 \
360    kb->shift = Shift;                                             \
361    kb->win = Win;                                                 \
362    kb->cb = eina_stringshare_add_length(Cb, strlen(Cb));          \
363    config->keys = eina_list_append(config->keys, kb)
364 
365 static void
_add_default_keys(Config * config)366 _add_default_keys(Config *config)
367 {
368    Config_Keys *kb;
369 
370    ADD_KB("F11", 0, 0, 0, 0, "win_fullscreen");
371 
372    /* Ctrl- */
373    ADD_KB("Prior", 1, 0, 0, 0, "term_prev");
374    ADD_KB("Next", 1, 0, 0, 0, "term_next");
375    ADD_KB("0", 1, 0, 0, 0, "tab_10");
376    ADD_KB("1", 1, 0, 0, 0, "tab_1");
377    ADD_KB("2", 1, 0, 0, 0, "tab_2");
378    ADD_KB("3", 1, 0, 0, 0, "tab_3");
379    ADD_KB("4", 1, 0, 0, 0, "tab_4");
380    ADD_KB("5", 1, 0, 0, 0, "tab_5");
381    ADD_KB("6", 1, 0, 0, 0, "tab_6");
382    ADD_KB("7", 1, 0, 0, 0, "tab_7");
383    ADD_KB("8", 1, 0, 0, 0, "tab_8");
384    ADD_KB("9", 1, 0, 0, 0, "tab_9");
385 
386    /* Alt- */
387    ADD_KB("Home", 0, 1, 0, 0, "cmd_box");
388    ADD_KB("w", 0, 1, 0, 0, "copy_primary");
389    ADD_KB("Return", 0, 1, 0, 0, "paste_primary");
390    ADD_KB("Up", 0, 1, 0, 0, "term_up");
391    ADD_KB("Down", 0, 1, 0, 0, "term_down");
392    ADD_KB("Left", 0, 1, 0, 0, "term_left");
393    ADD_KB("Right", 0, 1, 0, 0, "term_right");
394    ADD_KB("g", 0, 1, 0, 0, "visible_group");
395 
396    /* Ctrl-Shift- */
397    ADD_KB("Prior", 1, 0, 1, 0, "split_h");
398    ADD_KB("Next", 1, 0, 1, 0, "split_v");
399    ADD_KB("t", 1, 0, 1, 0, "tab_new");
400    ADD_KB("End", 1, 0, 1, 0, "exited");
401    ADD_KB("Home", 1, 0, 1, 0, "tab_select");
402    ADD_KB("c", 1, 0, 1, 0, "copy_clipboard");
403    ADD_KB("v", 1, 0, 1, 0, "paste_clipboard");
404    ADD_KB("h", 1, 0, 1, 0, "miniview");
405    ADD_KB("Insert", 1, 0, 1, 0, "paste_clipboard");
406    ADD_KB("n", 1, 0, 1, 0, "term_new");
407 
408    /* Ctrl-Alt- */
409    ADD_KB("equal", 1, 1, 0, 0, "increase_font_size");
410    ADD_KB("minus", 1, 1, 0, 0, "decrease_font_size");
411    ADD_KB("0", 1, 1, 0, 0, "reset_font_size");
412    ADD_KB("9", 1, 1, 0, 0, "big_font_size");
413    ADD_KB("t", 1, 1, 0, 0, "tab_title");
414 
415    /* Shift- */
416    ADD_KB("Prior", 0, 0, 1, 0, "one_page_up");
417    ADD_KB("Next", 0, 0, 1, 0, "one_page_down");
418    ADD_KB("Up", 0, 0, 1, 0, "one_line_up");
419    ADD_KB("Down", 0, 0, 1, 0, "one_line_down");
420    ADD_KB("Insert", 0, 0, 1, 0, "paste_primary");
421    ADD_KB("KP_Add", 0, 0, 1, 0, "increase_font_size");
422    ADD_KB("KP_Subtract", 0, 0, 1, 0, "decrease_font_size");
423    ADD_KB("KP_Multiply", 0, 0, 1, 0, "reset_font_size");
424    ADD_KB("KP_Divide", 0, 0, 1, 0, "copy_clipboard");
425    ADD_KB("Left", 0, 0, 1, 0, "term_prev");
426    ADD_KB("Right", 0, 0, 1, 0, "term_next");
427    ADD_KB("Home", 0, 0, 1, 0, "top_backlog");
428    ADD_KB("End", 0, 0, 1, 0, "reset_scroll");
429 
430    /* Alt-Shift */
431    ADD_KB("g", 0, 1, 1, 0, "all_group");
432 }
433 
434 void
config_reset_keys(Config * config)435 config_reset_keys(Config *config)
436 {
437    Config_Keys *key;
438 
439    EINA_LIST_FREE(config->keys, key)
440      {
441         eina_stringshare_del(key->keyname);
442         eina_stringshare_del(key->cb);
443         free(key);
444      }
445    _add_default_keys(config);
446 }
447 
448 
449 static void
_add_key(Config * config,const char * name,int ctrl,int alt,int shift,int win,const char * cb_name)450 _add_key(Config *config, const char *name, int ctrl, int alt, int shift,
451          int win, const char *cb_name)
452 {
453    Config_Keys *kb;
454 
455    ADD_KB(name, ctrl, alt, shift, win, cb_name);
456 }
457 
458 #undef ADD_KB
459 
460 void
config_default_font_set(Config * config,Evas * evas)461 config_default_font_set(Config *config, Evas *evas)
462 {
463    Eina_List *fontlist, *l;
464    const char *fname;
465    Eina_Bool dejavu_found = EINA_FALSE,
466              bitstream_found = EINA_FALSE,
467              droid_found = EINA_FALSE,
468              liberation_found = EINA_FALSE;
469 
470    if (config->font_set) return;
471 
472 #define FONT_DEJAVU     "DejaVu Sans Mono:style=Book"
473 #define FONT_LIBERATION "Liberation Mono:style=Regular"
474 #define FONT_DROID      "Droid Sans Mono:style=Regular"
475 #define FONT_BITSTREAM  "Bitstream Vera Sans Mono:style=Roman"
476 
477    fontlist = evas_font_available_list(evas);
478    if (!fontlist) return;
479 
480    EINA_LIST_FOREACH(fontlist, l, fname)
481      {
482         if (strncmp(fname, FONT_DEJAVU, strlen(FONT_DEJAVU)) == 0)
483           dejavu_found = EINA_TRUE;
484         else if (strncmp(fname, FONT_LIBERATION, strlen(FONT_LIBERATION)) == 0)
485           liberation_found = EINA_TRUE;
486         else if (strncmp(fname, FONT_DROID, strlen(FONT_DROID)) == 0)
487           droid_found = EINA_TRUE;
488         else if (strncmp(fname, FONT_BITSTREAM, strlen(FONT_BITSTREAM)) == 0)
489           bitstream_found = EINA_TRUE;
490      }
491 
492    evas_font_available_list_free(evas, fontlist);
493 
494    fname = config->font.name;
495    config->font_set = EINA_TRUE;
496    if (dejavu_found)
497      {
498         config->font.name = eina_stringshare_add(FONT_DEJAVU);
499      }
500    else if (liberation_found)
501      {
502         config->font.name = eina_stringshare_add(FONT_LIBERATION);
503      }
504    else if (droid_found)
505      {
506         config->font.name = eina_stringshare_add(FONT_DROID);
507      }
508    else if (bitstream_found)
509      {
510         config->font.name = eina_stringshare_add(FONT_BITSTREAM);
511      }
512    else
513      {
514         config->font_set = EINA_FALSE;
515      }
516 
517    if (config->font_set)
518      {
519         config->font.bitmap = EINA_FALSE;
520         config->font.size = 10;
521         config->font.bolditalic = EINA_TRUE;
522         eina_stringshare_del(fname);
523      }
524 #undef FONT_DEJAVU
525 #undef FONT_LIBERATION
526 #undef FONT_DROID
527 #undef FONT_BITSTREAM
528 }
529 
530 Config *
config_new(void)531 config_new(void)
532 {
533    Config *config;
534    config = calloc(1, sizeof(Config));
535    if (config)
536      {
537         int i, j;
538 
539         config->version = CONF_VER;
540         config->font.bitmap = EINA_TRUE;
541         config->font.name = eina_stringshare_add("nexus.pcf");
542         config->font.size = 10;
543         config->font.bolditalic = EINA_TRUE;
544         config->helper.email = eina_stringshare_add("xdg-email");
545         config->helper.url.general = eina_stringshare_add("xdg-open");
546         config->helper.url.video = eina_stringshare_add("xdg-open");
547         config->helper.url.image = eina_stringshare_add("xdg-open");
548         config->helper.local.general = eina_stringshare_add("xdg-open");
549         config->helper.local.video = eina_stringshare_add("xdg-open");
550         config->helper.local.image = eina_stringshare_add("xdg-open");
551         config->helper.inline_please = EINA_TRUE;
552         config->scrollback = 2000;
553         config->theme = eina_stringshare_add("default.edj");
554         config->color_scheme_name = eina_stringshare_add("Default");
555         config->background = NULL;
556         config->tab_zoom = 0.5;
557         config->opacity = 50;
558         config->cg_width = 80;
559         config->cg_height = 24;
560         config->jump_on_change = EINA_FALSE;
561         config->jump_on_keypress = EINA_TRUE;
562         config->flicker_on_key = EINA_FALSE;
563         config->disable_cursor_blink = EINA_FALSE;
564         config->cursor_shape = CURSOR_SHAPE_BLOCK;
565         config->disable_visual_bell = EINA_FALSE;
566         config->bell_rings = EINA_TRUE;
567         config->active_links_email = EINA_TRUE;
568         config->active_links_file = EINA_TRUE;
569         config->active_links_url = EINA_TRUE;
570         config->active_links_escape = EINA_TRUE;
571         config->active_links_color = EINA_TRUE;
572         config->translucent = EINA_FALSE;
573         config->mute = EINA_FALSE;
574         config->visualize = EINA_TRUE;
575         config->urg_bell = EINA_TRUE;
576         config->multi_instance = EINA_FALSE;
577         config->xterm_256color = EINA_TRUE;
578         config->erase_is_del = EINA_FALSE;
579         config->custom_geometry = EINA_FALSE;
580         config->drag_links = EINA_FALSE;
581         config->login_shell = EINA_FALSE;
582         config->mouse_over_focus = EINA_TRUE;
583         config->disable_focus_visuals = EINA_FALSE;
584         config->colors_use = EINA_FALSE;
585         config->gravatar = EINA_TRUE;
586         config->show_tabs = EINA_TRUE;
587         config->mv_always_show = EINA_FALSE;
588         config->ty_escapes = EINA_TRUE;
589         config->changedir_to_current = EINA_TRUE;
590         config->emoji_dbl_width = EINA_TRUE;
591         for (j = 0; j < 4; j++)
592           {
593              for (i = 0; i < 12; i++)
594                {
595                   unsigned char rr = 0, gg = 0, bb = 0, aa = 0;
596 
597                   colors_standard_get(j, i, &rr, &gg, &bb, &aa);
598                   config->colors[(j * 12) + i].r = rr;
599                   config->colors[(j * 12) + i].g = gg;
600                   config->colors[(j * 12) + i].b = bb;
601                   config->colors[(j * 12) + i].a = aa;
602                }
603           }
604         _add_default_keys(config);
605         config->shine = 255;
606         config->hide_cursor = 5.0;
607         config->group_all = EINA_FALSE;
608         config_compute_color_scheme(config);
609      }
610    return config;
611 }
612 
613 Config *
config_load(void)614 config_load(void)
615 {
616    Eet_File *ef;
617    char buf[PATH_MAX];
618    const char *cfgdir;
619    Config *config = NULL;
620 
621    cfgdir = _config_home_get();
622    snprintf(buf, sizeof(buf), "%s/terminology/config/standard/base.cfg", cfgdir);
623    ef = eet_open(buf, EET_FILE_MODE_READ);
624    if (ef)
625      {
626         config = eet_data_read(ef, edd_base, CONFIG_KEY);
627         eet_close(ef);
628         if (config)
629           {
630              config->font.orig_size = config->font.size;
631              if (config->font.name) config->font.orig_name = eina_stringshare_add(config->font.name);
632              config->font.orig_bitmap = config->font.bitmap;
633              switch (config->version)
634                {
635                 case 0:
636                 case 1:
637                    _config_upgrade_to_v2(config);
638                   EINA_FALLTHROUGH;
639                   /*pass through*/
640                 case 2:
641                   LIM(config->font.size, 3, 400);
642                   LIM(config->scrollback, 0, 131072);
643                   LIM(config->tab_zoom, 0.0, 1.0);
644                   LIM(config->_vidmod, 0, 4)
645 
646                   /* upgrade to v3 */
647                   config->active_links = EINA_TRUE;
648                   config->bell_rings = EINA_TRUE;
649                   EINA_FALLTHROUGH;
650                   /*pass through*/
651                 case 3:
652                   if (eina_list_count(config->keys) == 0)
653                     {
654                        _add_default_keys(config);
655                     }
656                   config->gravatar = EINA_TRUE;
657                   EINA_FALLTHROUGH;
658                   /*pass through*/
659                 case 4:
660                   EINA_FALLTHROUGH;
661                   /*pass through*/
662                 case 5:
663                   config->ty_escapes = EINA_TRUE;
664                   EINA_FALLTHROUGH;
665                   /*pass through*/
666                 case 6:
667                   config->changedir_to_current = EINA_TRUE;
668                   EINA_FALLTHROUGH;
669                   /*pass through*/
670                 case 7:
671                   _add_key(config, "n", 1, 0, 1, 0, "term_new");
672                   EINA_FALLTHROUGH;
673                   /*pass through*/
674                 case 8:
675                   _add_key(config, "t", 1, 1, 0, 0, "tab_title");
676                   EINA_FALLTHROUGH;
677                   /*pass through*/
678                 case 9:
679                   /* actually do nothing */
680                   EINA_FALLTHROUGH;
681                   /*pass through*/
682                 case 10:
683                   config->font.bolditalic = EINA_TRUE;
684                   EINA_FALLTHROUGH;
685                   /*pass through*/
686                 case 11:
687                   _add_key(config, "Left", 0, 0, 1, 0, "term_prev");
688                   _add_key(config, "Right", 0, 0, 1, 0, "term_next");
689                   EINA_FALLTHROUGH;
690                   /*pass through*/
691                 case 12:
692                   _add_key(config, "Home", 0, 0, 1, 0, "top_backlog");
693                   EINA_FALLTHROUGH;
694                   /*pass through*/
695                 case 13:
696                   _add_key(config, "End", 0, 0, 1, 0, "reset_scroll");
697                   EINA_FALLTHROUGH;
698                   /*pass through*/
699                 case 14:
700                   config->disable_focus_visuals = EINA_FALSE;
701                   EINA_FALLTHROUGH;
702                   /*pass through*/
703                 case 15:
704                   _add_key(config, "Up",    0, 1, 0, 0, "term_up");
705                   _add_key(config, "Down",  0, 1, 0, 0, "term_down");
706                   _add_key(config, "Left",  0, 1, 0, 0, "term_left");
707                   _add_key(config, "Right", 0, 1, 0, 0, "term_right");
708                   EINA_FALLTHROUGH;
709                   /*pass through*/
710                 case 16:
711                   config->shine = 255;
712                   EINA_FALLTHROUGH;
713                   /*pass through*/
714                 case 17:
715                   _add_key(config, "g", 0, 1, 0, 0, "visible_group");
716                   _add_key(config, "g", 0, 1, 1, 0, "all_group");
717                   EINA_FALLTHROUGH;
718                   /*pass through*/
719                 case 18:
720                   config->cursor_shape = CURSOR_SHAPE_BLOCK;
721                   EINA_FALLTHROUGH;
722                   /*pass through*/
723                 case 19:
724                   config->active_links_email = config->active_links;
725                   config->active_links_file = config->active_links;
726                   config->active_links_url = config->active_links;
727                   config->active_links_escape = config->active_links;
728                   EINA_FALLTHROUGH;
729                   /*pass through*/
730                 case 20:
731                   config->emoji_dbl_width = EINA_TRUE;
732                   EINA_FALLTHROUGH;
733                   /*pass through*/
734                 case 21:
735                   config->hide_cursor = 5.0;
736                   EINA_FALLTHROUGH;
737                   /*pass through*/
738                 case 22:
739                   config->show_tabs = !config->notabs;
740                   EINA_FALLTHROUGH;
741                 case 23:
742                   config->group_all = EINA_FALSE;
743                   EINA_FALLTHROUGH;
744                   /*pass through*/
745                 case 24:
746                   config->active_links_color = (
747                      config->active_links_email ||
748                      config->active_links_file ||
749                      config->active_links_url ||
750                      config->active_links_escape);
751                   EINA_FALLTHROUGH;
752                   /*pass through*/
753                 case 25:
754                   #define THEME_TO_COLORSCHEME(_Theme, _Base, _ColorSheme)   \
755                   do {                                                       \
756                        if (!strncmp(config->theme, _Theme, sizeof(_Theme)-1)) \
757                          {                                                   \
758                             eina_stringshare_replace(&config->theme,         \
759                                                      _Base);                 \
760                             eina_stringshare_replace(                        \
761                                &config->color_scheme_name,                   \
762                                _ColorSheme);                                 \
763                          }                                                   \
764                   } while (0)
765 
766                   THEME_TO_COLORSCHEME("mild.edj", "mild.edj", "Mild");
767                   THEME_TO_COLORSCHEME("black.edj", "mild.edj", "Black");
768                   THEME_TO_COLORSCHEME("solarized.edj", "default.edj", "Solarized");
769                   THEME_TO_COLORSCHEME("solarized_light.edj", "default.edj", "Solarized Light");
770                   THEME_TO_COLORSCHEME("mustang.edj", "mild.edj", "Mustang");
771                   THEME_TO_COLORSCHEME("base16_ocean_dark.edj", "mild.edj", "Ocean Dark");
772                   THEME_TO_COLORSCHEME("smyck.edj", "mild.edj", "Smyck");
773                   THEME_TO_COLORSCHEME("nord.edj", "default.edj", "Nord");
774                   THEME_TO_COLORSCHEME("papercolor.edj", "default.edj", "PaperColor");
775 
776                   #undef THEME_TO_COLORSCHEME
777 
778                   config_compute_color_scheme(config);
779                   EINA_FALLTHROUGH;
780                   /*pass through*/
781                 case CONF_VER: /* 26 */
782                   config->version = CONF_VER;
783                   break;
784                 default:
785                   if (config->version < CONF_VER)
786                     {
787                        // currently no upgrade path so reset config.
788                        ERR("config is from a newer Terminology, discard it");
789                        config_del(config);
790                        config = config_new();
791                        config->temporary = EINA_TRUE;
792                     }
793                   /* do nothing in case the config is from a newer
794                    * terminology, we don't want to remove it. */
795                }
796           }
797      }
798    if (!config)
799      {
800         config = config_new();
801      }
802    else
803      {
804         config_compute_color_scheme(config);
805         config->font_set = 1;
806      }
807 
808    return config;
809 }
810 
811 Config *
config_fork(const Config * config)812 config_fork(const Config *config)
813 {
814    Config_Keys *key;
815    Eina_List *l;
816    Config *config2;
817 
818    config2 = calloc(1, sizeof(Config));
819    if (!config2) return NULL;
820 #define CPY(fld) config2->fld = config->fld;
821 #define SCPY(fld) if (config->fld) config2->fld = eina_stringshare_add(config->fld)
822 #define SLSTCPY(fld) \
823    do { Eina_List *__l; const char *__s; \
824      EINA_LIST_FOREACH(config->fld, __l, __s) \
825        config2->fld = eina_list_append \
826          (config2->fld, eina_stringshare_add(__s)); } while (0)
827 
828    CPY(version);
829    SCPY(font.name);
830    CPY(font.size);
831    CPY(font.bitmap);
832    SCPY(font.orig_name);
833    CPY(font.orig_size);
834    CPY(font.orig_bitmap);
835    CPY(font.bolditalic);
836    SCPY(helper.email);
837    SCPY(helper.url.general);
838    SCPY(helper.url.video);
839    SCPY(helper.url.image);
840    SCPY(helper.local.general);
841    SCPY(helper.local.video);
842    SCPY(helper.local.image);
843    CPY(helper.inline_please);
844    SCPY(theme);
845    SCPY(color_scheme_name);
846    config2->color_scheme = color_scheme_dup(config->color_scheme);
847    SCPY(background);
848    CPY(scrollback);
849    CPY(tab_zoom);
850    CPY(hide_cursor);
851    CPY(jump_on_change);
852    CPY(jump_on_keypress);
853    CPY(flicker_on_key);
854    CPY(disable_cursor_blink);
855    CPY(cursor_shape);
856    CPY(disable_visual_bell);
857    CPY(bell_rings);
858    CPY(active_links_email);
859    CPY(active_links_file);
860    CPY(active_links_url);
861    CPY(active_links_escape);
862    CPY(active_links_color);
863    CPY(translucent);
864    CPY(opacity);
865    CPY(mute);
866    CPY(visualize);
867    CPY(urg_bell);
868    CPY(multi_instance);
869    CPY(xterm_256color);
870    CPY(erase_is_del);
871    CPY(custom_geometry);
872    CPY(login_shell);
873    CPY(cg_width);
874    CPY(cg_height);
875    CPY(colors_use);
876    memcpy(config2->colors, config->colors, sizeof(config->colors));
877    CPY(mouse_over_focus);
878    CPY(disable_focus_visuals);
879    CPY(temporary);
880    CPY(font_set);
881    CPY(gravatar);
882    CPY(show_tabs);
883    CPY(mv_always_show);
884    CPY(ty_escapes);
885    CPY(changedir_to_current);
886    CPY(emoji_dbl_width);
887    CPY(shine);
888    CPY(group_all);
889 
890    EINA_LIST_FOREACH(config->keys, l, key)
891      {
892         Config_Keys *key2 = calloc(1, sizeof(Config_Keys));
893         if (!key2) break;
894         key2->keyname = key->keyname;
895         eina_stringshare_ref(key->keyname);
896         key2->ctrl = key->ctrl;
897         key2->alt = key->alt;
898         key2->shift = key->shift;
899         key2->win = key->win;
900         key2->cb = key->cb;
901         eina_stringshare_ref(key->cb);
902         config2->keys = eina_list_append(config2->keys, key2);
903      }
904 
905    return config2;
906 }
907 
908 void
config_del(Config * config)909 config_del(Config *config)
910 {
911    Config_Keys *key;
912 
913    if (!config) return;
914 
915    eina_stringshare_del(config->font.name);
916    eina_stringshare_del(config->font.orig_name);
917    eina_stringshare_del(config->theme);
918    eina_stringshare_del(config->color_scheme_name);
919    free((void*)config->color_scheme);
920    eina_stringshare_del(config->background);
921    eina_stringshare_del(config->helper.email);
922    eina_stringshare_del(config->helper.url.general);
923    eina_stringshare_del(config->helper.url.video);
924    eina_stringshare_del(config->helper.url.image);
925    eina_stringshare_del(config->helper.local.general);
926    eina_stringshare_del(config->helper.local.video);
927    eina_stringshare_del(config->helper.local.image);
928 
929    EINA_LIST_FREE(config->keys, key)
930      {
931         eina_stringshare_del(key->keyname);
932         eina_stringshare_del(key->cb);
933         free(key);
934      }
935    free(config);
936 }
937 
938