123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636 |
- /*
- * config.c
- * Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of the nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include "wmfs.h"
- /* local function definition */
- static void conf_section(void (*)(char*), char *, char *);
- func_name_list_t tmp_func_list[] =
- {
- {"spawn", uicb_spawn },
- {"client_kill", uicb_client_kill },
- {"client_prev", uicb_client_prev },
- {"client_next", uicb_client_next },
- {"client_swap_next", uicb_client_swap_next },
- {"client_swap_prev", uicb_client_swap_prev },
- {"client_screen_next", uicb_client_screen_next },
- {"client_screen_prev", uicb_client_screen_prev },
- {"client_move", uicb_client_move },
- {"client_resize", uicb_client_resize },
- {"toggle_max", uicb_togglemax },
- {"layout_next", uicb_layout_next },
- {"layout_prev", uicb_layout_prev },
- {"tag", uicb_tag },
- {"tag_next", uicb_tag_next },
- {"tag_prev", uicb_tag_prev },
- {"tag_transfert", uicb_tagtransfert },
- {"set_mwfact", uicb_set_mwfact },
- {"set_nmaster", uicb_set_nmaster },
- {"quit", uicb_quit },
- {"toggle_infobar_position", uicb_infobar_togglepos },
- {"toggle_resizehint", uicb_toggle_resizehint },
- {"mouse_move", uicb_mouse_move },
- {"mouse_resize", uicb_mouse_resize },
- {"client_raise", uicb_client_raise },
- {"toggle_free", uicb_togglefree },
- {"toggle_abovefc", uicb_toggle_abovefc },
- {"screen_select", uicb_screen_select },
- {"screen_next", uicb_screen_next },
- {"screen_prev", uicb_screen_prev },
- {"reload", uicb_reload },
- {"launcher", uicb_launcher },
- {"set_layout", uicb_set_layout },
- {"menu", uicb_menu },
- {"set_client_layer", uicb_set_client_layer },
- {"set_layer", uicb_set_layer }
- };
- key_name_list_t key_list[] =
- {
- {"Control", ControlMask },
- {"Shift", ShiftMask },
- {"Lock", LockMask },
- {"Alt", Mod1Mask },
- {"Mod2", Mod2Mask },
- {"Mod3", Mod3Mask },
- {"Mod4", Mod4Mask },
- {"Super", Mod4Mask },
- {"Mod5", Mod5Mask },
- {NULL, NoSymbol }
- };
- name_to_uint_t mouse_button_list[] =
- {
- {"Button1", Button1 },
- {"Button2", Button2 },
- {"Button3", Button3 },
- {"Button4", Button4 },
- {"Button5", Button5 },
- {"1", Button1 },
- {"2", Button2 },
- {"3", Button3 },
- {"4", Button4 },
- {"5", Button5 },
- };
- void
- mouse_section(MouseBinding mb[], char *src, int ns)
- {
- int i;
- char *tmp;
- for(i = 0; i < ns; ++i)
- {
- tmp = get_nsec(src, "mouse", i);
- cfg_set_sauv(tmp);
- mb[i].tag = get_opt(tmp, "-1", "tag").num;
- mb[i].screen = get_opt(tmp, "-1", "screen").num;
- mb[i].button = char_to_button(get_opt(tmp, "1", "button").str, mouse_button_list);
- mb[i].func = name_to_func(get_opt(tmp, "", "func").str, func_list);
- mb[i].cmd = get_opt(tmp, "", "cmd").str;
- cfg_set_sauv(src);
- }
- return;
- }
- void
- conf_misc_section(char *src)
- {
- int pad = 12;
- cfg_set_sauv(src);
- conf.font = get_opt(src, "sans-9", "font").str;
- conf.raisefocus = get_opt(src, "false", "raisefocus").bool;
- conf.raiseswitch = get_opt(src, "false", "raiseswitch").bool;
- conf.focus_fmouse = get_opt(src, "true", "focus_follow_mouse").bool;
- conf.status_timing = get_opt(src, "1", "status_timing").num;
- pad = get_opt(src, "12", "pad").num;
- if(pad > 24 || pad < 1)
- {
- warnx("configuration : pad value (%d) incorrect.", pad);
- pad = 12;
- }
- conf.pad = pad;
- if(conf.status_timing <= 0)
- {
- warnx("configuration : status_timing value (%d) incorrect.", conf.status_timing);
- conf.status_timing = 1;
- }
- return;
- }
- void
- conf_bar_section(char *src)
- {
- cfg_set_sauv(src);
- conf.border.bar = get_opt(src, "false", "border").bool;
- conf.bars.height = get_opt(src, "-1", "height").num;
- conf.colors.bar = getcolor(get_opt(src, "#000000", "bg").str);
- conf.colors.text = get_opt(src, "#ffffff", "fg").str;
- if((conf.bars.nmouse = get_size_sec(src, "mouse")))
- {
- conf.bars.mouse = emalloc(conf.bars.nmouse, sizeof(MouseBinding));
- mouse_section(conf.bars.mouse, src, conf.bars.nmouse);
- }
- return;
- }
- void
- conf_root_section(char *src)
- {
- cfg_set_sauv(src);
- conf.root.background_command = get_opt(src, "", "background_command").str;
- if((conf.root.nmouse = get_size_sec(src, "mouse")))
- {
- conf.root.mouse = emalloc(conf.root.nmouse, sizeof(MouseBinding));
- mouse_section(conf.root.mouse, src, conf.root.nmouse);
- }
- return;
- }
- void
- conf_client_section(char *src)
- {
- int i, j, d;
- char *tmp, *tmp2, *tmp3, *p;
- opt_type *buf;
- /* Client misc */
- cfg_set_sauv(src);
- conf.client.borderheight = (get_opt(src, "1", "border_height").num) ? get_opt(src, "1", "border_height").num : 1;
- conf.client.border_shadow = get_opt(src, "false", "border_shadow").bool;
- conf.client.place_at_mouse = get_opt(src, "false", "place_at_mouse").bool;
- conf.client.bordernormal = getcolor(get_opt(src, "#000000", "border_normal").str);
- conf.client.borderfocus = getcolor(get_opt(src, "#ffffff", "border_focus").str);
- conf.client.resizecorner_normal = getcolor(get_opt(src, "#222222", "resize_corner_normal").str);
- conf.client.resizecorner_focus = getcolor(get_opt(src, "#DDDDDD", "resize_corner_focus").str);
- conf.client.mod |= char_to_modkey(get_opt(src, "Alt", "modifier").str, key_list);
- conf.client.set_new_win_master = get_opt(src, "true", "set_new_win_master").bool;
- if((conf.client.nmouse = get_size_sec(src, "mouse")))
- {
- conf.client.mouse = emalloc(conf.client.nmouse, sizeof(MouseBinding));
- mouse_section(conf.client.mouse, src, conf.client.nmouse);
- }
- /* Titlebar part {{ */
- tmp = get_sec(src, "titlebar");
- cfg_set_sauv(tmp);
- conf.titlebar.height = get_opt(tmp, "0", "height").num;
- conf.titlebar.fg_normal = get_opt(tmp, "#ffffff", "fg_normal").str;
- conf.titlebar.fg_focus = get_opt(tmp, "#000000", "fg_focus").str;
- /* Stipple */
- conf.titlebar.stipple.active = get_opt(tmp, "false", "stipple").bool;
- if(!strcmp((p = get_opt(tmp, "-1", "stipple_normal").str), "-1"))
- conf.titlebar.stipple.colors.normal = getcolor(conf.titlebar.fg_normal);
- else
- conf.titlebar.stipple.colors.normal = getcolor(p);
- if(!strcmp((p = get_opt(tmp, "-1", "stipple_focus").str), "-1"))
- conf.titlebar.stipple.colors.focus = getcolor(conf.titlebar.fg_focus);
- else
- conf.titlebar.stipple.colors.focus = getcolor(p);
- if((conf.titlebar.nmouse = get_size_sec(tmp, "mouse")))
- {
- conf.titlebar.mouse = emalloc(conf.titlebar.nmouse, sizeof(MouseBinding));
- mouse_section(conf.titlebar.mouse, tmp, conf.titlebar.nmouse);
- }
- /* Multi button part */
- if((conf.titlebar.nbutton = get_size_sec(tmp, "button")))
- {
- conf.titlebar.button = emalloc(conf.titlebar.nbutton, sizeof(Button));
- for(i = 0; i < conf.titlebar.nbutton; ++i)
- {
- tmp2 = get_nsec(tmp, "button", i);
- cfg_set_sauv(tmp2);
- /* Multi mouse section */
- if((conf.titlebar.button[i].nmouse = get_size_sec(tmp2, "mouse")))
- {
- conf.titlebar.button[i].mouse = emalloc(conf.titlebar.button[i].nmouse, sizeof(MouseBinding));
- mouse_section(conf.titlebar.button[i].mouse, tmp2, conf.titlebar.button[i].nmouse);
- }
- /* Multi line section */
- if((conf.titlebar.button[i].nlines = get_size_sec(tmp2, "line")))
- {
- conf.titlebar.button[i].linecoord = emalloc(conf.titlebar.button[i].nlines, sizeof(XSegment));
- for(j = 0; j < conf.titlebar.button[i].nlines; ++j)
- {
- tmp3 = get_nsec(tmp2, "line", j);
- cfg_set_sauv(tmp3);
- buf = get_list_opt(tmp3, "{0, 0, 0, 0}", "coord", &d);
- conf.titlebar.button[i].linecoord[j].x1 = buf[0].num;
- conf.titlebar.button[i].linecoord[j].y1 = buf[1].num;
- conf.titlebar.button[i].linecoord[j].x2 = buf[2].num;
- conf.titlebar.button[i].linecoord[j].y2 = buf[3].num;
- cfg_set_sauv(tmp2);
- }
- }
- cfg_set_sauv(tmp);
- }
- }
- /* }} */
- return;
- }
- void
- conf_layout_section(char *src)
- {
- int i;
- char *tmp = NULL, *p;
- /* Set conf.layout NULL for conf reload */
- for(i = 0; i < NUM_OF_LAYOUT; ++i)
- {
- conf.layout[i].symbol = NULL;
- conf.layout[i].func = NULL;
- }
- cfg_set_sauv(src);
- conf.border.layout = get_opt(src, "false", "border").bool;
- conf.colors.layout_fg = get_opt(src, "#ffffff", "fg").str;
- conf.colors.layout_bg = getcolor((get_opt(src, "#000000", "bg").str));
- if((tmp = get_opt(src, "menu", "system").str) && !strcmp(tmp, "menu"))
- conf.layout_system = True;
- conf.nlayout = get_size_sec(src, "layout");
- if(conf.nlayout > NUM_OF_LAYOUT || !(conf.nlayout))
- {
- warnx("configuration : Too many or no layouts (%d).", conf.nlayout);
- conf.nlayout = 1;
- conf.layout[0].symbol = _strdup("TILE");
- conf.layout[0].func = tile;
- }
- if(conf.layout_system && conf.nlayout > 1)
- {
- menu_init(&menulayout, "menulayout", conf.nlayout,
- /* Colors */
- conf.colors.layout_bg,
- conf.colors.layout_fg,
- conf.colors.bar,
- conf.colors.text);
- }
- if(!conf.layout[0].symbol
- && !conf.layout[0].func)
- {
- for(i = 0; i < conf.nlayout; ++i)
- {
- tmp = get_nsec(src, "layout", i);
- cfg_set_sauv(tmp);
- if(!name_to_func((p = get_opt(tmp, "tile", "type").str), layout_list))
- warnx("configuration : Unknown Layout type : \"%s\".", p);
- else
- {
- if(conf.layout_system && conf.nlayout > 1)
- menu_new_item(&menulayout.item[i], get_opt(tmp, "", "symbol").str,
- uicb_set_layout, p);
- conf.layout[i].symbol = get_opt(tmp, "TILE (default)", "symbol").str;
- conf.layout[i].func = name_to_func(p, layout_list);
- }
- cfg_set_sauv(src);
- }
- }
- return;
- }
- void
- conf_tag_section(char *src)
- {
- int i, j, k, l = 0, m, n, sc;
- char *cfgtmp, *tmp;
- opt_type *buf;
- /* If there is no tag in the conf or more than
- * MAXTAG (32) print an error and create only one.
- */
- Tag default_tag = { "WMFS", NULL, 0, 1,
- 0.50, 1, False, False, False, IB_Top,
- layout_name_to_struct(conf.layout, "tile_right", conf.nlayout, layout_list) };
- cfg_set_sauv(src);
- conf.tag_round = get_opt(src, "false", "tag_round").bool;
- conf.colors.tagselfg = get_opt(src, "#ffffff", "sel_fg").str;
- conf.colors.tagselbg = getcolor(get_opt(src, "#000000", "sel_bg").str);
- conf.colors.tag_occupied_bg = getcolor(get_opt(src, "#222222", "occupied_bg").str);
- conf.border.tag = get_opt(src, "false", "border").bool;
- sc = screen_count();
- /* Alloc all */
- conf.ntag = emalloc(sc, sizeof(int));
- tags = emalloc(sc, sizeof(Tag*));
- seltag = emalloc(sc, sizeof(int));
- for(i = 0; i < sc; ++i)
- seltag[i] = 1;
- for(i = 0; i < sc; ++i)
- tags[i] = emalloc(get_size_sec(src, "tag") + 2, sizeof(Tag));
- for(i = 0; i < get_size_sec(src, "tag"); ++i)
- {
- /* printf("%d -> %s\n", i, (cfgtmp = get_nsec(src, "tag", i)));*/
- cfgtmp = get_nsec(src, "tag", i);
- cfg_set_sauv(cfgtmp);
- j = get_opt(cfgtmp, "-1", "screen").num;
- if(j < 0 || j > sc - 1)
- j = -1;
- for(k = ((j == -1) ? 0 : j);
- ((j == -1) ? (k < sc) : !l);
- ((j == -1) ? ++k : --l))
- {
- ++conf.ntag[k];
- tags[k][conf.ntag[k]].name = get_opt(cfgtmp, "", "name").str;
- tags[k][conf.ntag[k]].mwfact = get_opt(cfgtmp, "0.65", "mwfact").fnum;
- tags[k][conf.ntag[k]].nmaster = get_opt(cfgtmp, "1", "nmaster").num;
- tags[k][conf.ntag[k]].resizehint = get_opt(cfgtmp, "false", "resizehint").bool;
- tags[k][conf.ntag[k]].abovefc = get_opt(cfgtmp, "false", "abovefc").bool;
- tags[k][conf.ntag[k]].layers = 1;
- tmp = _strdup(get_opt(cfgtmp, "top", "infobar_position").str);
- if(!strcmp(tmp ,"none") || !strcmp(tmp, "hide") || !strcmp(tmp, "hidden"))
- tags[k][conf.ntag[k]].barpos = IB_Hide;
- else if(!strcmp(tmp, "bottom") || !strcmp(tmp, "down"))
- tags[k][conf.ntag[k]].barpos = IB_Bottom;
- else
- tags[k][conf.ntag[k]].barpos = IB_Top;
- tags[k][conf.ntag[k]].layout = layout_name_to_struct(conf.layout,
- get_opt(cfgtmp, "tile_right", "layout").str,
- conf.nlayout,
- layout_list);
- /* Clients list */
- buf = get_list_opt(cfgtmp, "", "clients", &n);
- if(n)
- {
- tags[k][conf.ntag[k]].nclients = n;
- tags[k][conf.ntag[k]].clients = emalloc(n, sizeof(char *));
- for(m = 0; m < n; ++m)
- tags[k][conf.ntag[k]].clients[m] = (buf[m].str) ? buf[m].str : NULL;
- }
- }
- l = 0;
- cfg_set_sauv(src);
- }
- for(i = 0; i < sc; ++i)
- if(!conf.ntag[i] || conf.ntag[i] > MAXTAG)
- {
- warnx("configuration : Too many or no tag (%d) in the screen %d.", conf.ntag[i], i);
- conf.ntag[i] = 1;
- tags[i][1] = default_tag;
- }
- return;
- }
- void
- conf_menu_section(char *src)
- {
- char *tmp, *tmp2;
- int i, j;
- cfg_set_sauv(src);
- CHECK((conf.nmenu = get_size_sec(src, "set_menu")));
- conf.menu = calloc(conf.nmenu, sizeof(Menu));
- for(i = 0; i < conf.nmenu; ++i)
- {
- tmp = get_nsec(src, "set_menu", i);
- cfg_set_sauv(tmp);
- conf.menu[i].name = get_opt(tmp, "menu_wname", "name").str;
- if(!(conf.menu[i].place_at_mouse = get_opt(tmp, "true", "place_at_mouse").bool))
- {
- conf.menu[i].x = get_opt(tmp, "0", "x").num;
- conf.menu[i].y = get_opt(tmp, "0", "y").num;
- }
- conf.menu[i].colors.focus.bg = getcolor(get_opt(tmp, "#000000", "bg_focus").str);
- conf.menu[i].colors.focus.fg = get_opt(tmp, "#ffffff", "fg_focus").str;
- conf.menu[i].colors.normal.bg = getcolor(get_opt(tmp, "#000000", "bg_normal").str);
- conf.menu[i].colors.normal.fg = get_opt(tmp, "#ffffff", "fg_normal").str;
- if((conf.menu[i].nitem = get_size_sec(tmp, "item")))
- {
- conf.menu[i].item = emalloc(conf.menu[i].nitem, sizeof(MenuItem));
- for(j = 0; j < get_size_sec(tmp, "item"); ++j)
- {
- tmp2 = get_nsec(tmp, "item", j);
- cfg_set_sauv(tmp2);
- conf.menu[i].item[j].name = get_opt(tmp2, "item_wname", "name").str;
- conf.menu[i].item[j].func = name_to_func(get_opt(tmp2, "", "func").str, func_list);
- conf.menu[i].item[j].cmd = (!get_opt(tmp2, "", "cmd").str) ? NULL : get_opt(tmp2, "", "cmd").str;
- cfg_set_sauv(tmp);
- }
- }
- cfg_set_sauv(src);
- }
- return;
- }
- void
- conf_launcher_section(char *src)
- {
- int i;
- char *tmp;
- cfg_set_sauv(src);
- CHECK((conf.nlauncher = get_size_sec(src, "set_launcher")));
- conf.launcher = emalloc(conf.nlauncher, sizeof(Launcher));
- for(i = 0; i < conf.nlauncher; ++i)
- {
- tmp = get_nsec(src, "set_launcher", i);
- cfg_set_sauv(tmp);
- conf.launcher[i].name = get_opt(tmp, "launcher", "name").str;
- conf.launcher[i].prompt = get_opt(tmp, "Exec:", "prompt").str;
- conf.launcher[i].command = get_opt(tmp, "exec", "command").str;
- cfg_set_sauv(src);
- }
- return;
- }
- void
- conf_keybind_section(char *src)
- {
- int i, j, n = 0;
- char *tmp;
- opt_type *buf;
- cfg_set_sauv(src);
- conf.nkeybind = get_size_sec(src, "key");
- keys = emalloc(conf.nkeybind, sizeof(Key));
- for(i = 0; i < conf.nkeybind; ++i)
- {
- tmp = get_nsec(src, "key", i);
- cfg_set_sauv(tmp);
- buf = get_list_opt(tmp, "", "mod", &n);
- for(j = 0; j < n; ++j)
- keys[i].mod |= char_to_modkey(buf[j].str, key_list);
- keys[i].keysym = XStringToKeysym(get_opt(tmp, "None", "key").str);
- keys[i].func = name_to_func(get_opt(tmp, "", "func").str, func_list);
- if(keys[i].func == NULL)
- {
- warnx("configuration : Unknown Function \"%s\".", get_opt(tmp, "", "func").str);
- keys[i].func = uicb_spawn;
- }
- keys[i].cmd = (!get_opt(tmp, "", "cmd").str) ? NULL : get_opt(tmp, "", "cmd").str;
- cfg_set_sauv(src);
- }
- return;
- }
- /** Configuration initialization
- */
- void
- init_conf(void)
- {
- char *file;
- if(!(file = file_to_str(conf.confpath)))
- {
- warnx("parsing configuration file (%s) failed.", conf.confpath);
- sprintf(conf.confpath, "%s/wmfs/wmfsrc", XDG_CONFIG_DIR);
- warnx("Use the default configuration (%s).", conf.confpath);
- file = file_to_str(conf.confpath);
- }
- /* Set func_list */
- func_list = emalloc(LEN(tmp_func_list), sizeof(func_name_list_t));
- memcpy(func_list, tmp_func_list, LEN(tmp_func_list) * sizeof(func_name_list_t));
- conf_section(conf_misc_section, file, "misc");
- conf_section(conf_bar_section, file, "bar");
- conf_section(conf_root_section, file, "root");
- conf_section(conf_client_section, file, "client");
- conf_section(conf_layout_section, file, "layouts");
- conf_section(conf_tag_section, file, "tags");
- conf_section(conf_menu_section, file, "menu");
- conf_section(conf_launcher_section, file, "launcher");
- conf_section(conf_keybind_section, file, "keys");
- free(file);
- return;
- }
- /** Simple wrapper for calling functions and free pointer
- */
- static void
- conf_section(void (*func)(char*), char *src, char *name)
- {
- char *sec;
- sec = get_sec(src, name);
- func(sec);
- IFREE(sec);
- return;
- }
|