/* * config.c * Copyright © 2008, 2009 Martin Duquesnoy * 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" const func_name_list_t func_list[] = { {"spawn", uicb_spawn }, {"client_kill", uicb_client_kill }, {"client_prev", uicb_client_focus_prev }, {"client_next", uicb_client_focus_next }, {"client_swap_next", uicb_client_swapsel_next }, {"client_swap_prev", uicb_client_swapsel_prev }, {"client_swap_right", uicb_client_swapsel_Right }, {"client_swap_left", uicb_client_swapsel_Left }, {"client_swap_top", uicb_client_swapsel_Top }, {"client_swap_bottom", uicb_client_swapsel_Bottom }, {"client_screen_next", uicb_client_screen_next }, {"client_screen_prev", uicb_client_screen_prev }, {"client_screen_set", uicb_client_screen_set }, {"client_focus_right", uicb_client_focus_Right }, {"client_focus_left" , uicb_client_focus_Left }, {"client_focus_top", uicb_client_focus_Top }, {"client_focus_bottom", uicb_client_focus_Bottom }, {"client_move", uicb_client_move }, {"client_resize", uicb_client_resize }, {"client_ignore_tag", uicb_client_ignore_tag }, {"client_set_master", uicb_client_set_master }, {"client_resize_right", uicb_client_resize_Right }, {"client_resize_left", uicb_client_resize_Left }, {"client_resize_top", uicb_client_resize_Top }, {"client_resize_bottom", uicb_client_resize_Bottom }, {"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_next_visible", uicb_tag_next_visible }, {"tag_prev_visible", uicb_tag_prev_visible }, {"tag_prev_sel", uicb_tag_prev_sel }, {"tag_transfert", uicb_tagtransfert }, {"tag_transfert_next", uicb_tagtransfert_next }, {"tag_transfert_prev", uicb_tagtransfert_prev }, {"tag_urgent", uicb_tag_urgent }, {"tag_toggle_additional", uicb_tag_toggle_additional }, {"tag_swap", uicb_tag_swap }, {"tag_swap_next", uicb_tag_swap_next }, {"tag_swap_prev", uicb_tag_swap_previous }, {"tag_new", uicb_tag_new }, {"tag_del", uicb_tag_del }, {"tag_rename", uicb_tag_rename }, {"tag_last", uicb_tag_last }, {"tag_stay_last", uicb_tag_stay_last }, {"set_mwfact", uicb_set_mwfact }, {"set_nmaster", uicb_set_nmaster }, {"quit", uicb_quit }, {"toggle_infobar_position", uicb_infobar_togglepos }, {"toggle_infobar_display", uicb_infobar_toggledisplay }, {"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 }, {"screen_prev_sel", uicb_screen_prev_sel}, {"reload", uicb_reload }, {"launcher", uicb_launcher }, {"set_layout", uicb_set_layout }, {"menu", uicb_menu }, {"ignore_next_client_rules", uicb_ignore_next_client_rules }, {"check_max", uicb_checkmax }, {"check_free", uicb_checkfree }, {"check_layout", uicb_checklayout }, {"clientlist", uicb_clientlist }, {"check_clist", uicb_checkclist }, {"toggle_tagautohide", uicb_toggle_tagautohide }, {"toggle_tag_expose", uicb_tag_toggle_expose}, {"split_toggle", uicb_split_toggle }, {"split_move_right", uicb_split_move_Right }, {"split_move_left", uicb_split_move_Left }, {"split_move_top", uicb_split_move_Top }, {"split_move_bottom", uicb_split_move_Bottom }, /*{"split_client_vertical" uicb_split_client_vertical }, {"split_client_horizontal", uicb_split_client_horizontal }, */ {NULL, NULL} }; static key_name_list_t key_list[] = { {"Control", ControlMask }, {"Shift", ShiftMask }, {"Lock", LockMask }, {"Alt", Mod1Mask }, {"Mod2", Mod2Mask }, {"Mod3", Mod3Mask }, {"Mod4", Mod4Mask }, {"Super", Mod4Mask }, {"Home", Mod4Mask }, {"Mod5", Mod5Mask }, {NULL, NoSymbol } }; static 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 }, {NULL, NoSymbol} }; static void mouse_section(MouseBinding mb[], struct conf_sec **sec) { int n; for (n = 0; sec[n]; n++) { mb[n].tag = fetch_opt_first(sec[n], "-1", "tag").num; mb[n].screen = fetch_opt_first(sec[n], "-1", "screen").num; mb[n].button = char_to_button(fetch_opt_first(sec[n], "1", "button").str, mouse_button_list); mb[n].func = name_to_func(fetch_opt_first(sec[n], "", "func").str, func_list); mb[n].cmd = fetch_opt_first(sec[n], "", "cmd").str; } } static void conf_misc_section(void) { bool xft = False; int pad = 12; uint opacity = 255; struct conf_sec *sec; sec = fetch_section_first(NULL, "misc"); #ifdef HAVE_XFT xft = True; #endif /* HAVE_XFT */ conf.font = fetch_opt_first(sec, "sans-9", "font").str; conf.use_xft = fetch_opt_first(sec, (xft ? "true" : "false"), "use_xft").boolean; conf.raisefocus = fetch_opt_first(sec, "false", "raisefocus").boolean; conf.focus_fmouse = fetch_opt_first(sec, "true", "focus_follow_mouse").boolean; conf.focus_fmov = fetch_opt_first(sec, "false", "focus_follow_movement").boolean; conf.focus_pclick = fetch_opt_first(sec, "true", "focus_pointer_click").boolean; conf.status_timing = fetch_opt_first(sec, "1", "status_timing").num; conf.status_path = fetch_opt_first(sec, "", "status_path").str; conf.autostart_path = fetch_opt_first(sec, "", "autostart_path").str; conf.autostart_command = fetch_opt_first(sec, "", "autostart_command").str; pad = fetch_opt_first(sec, "12", "pad").num; opacity = fetch_opt_first(sec, "255", "opacity").num; if(opacity > 255) opacity = 255; conf.opacity = opacity << 24; 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; } static void conf_bar_section(void) { struct conf_sec *bar, **mouse, *selbar, *systray; char *barbg; int sc = screen_count(); bar = fetch_section_first(NULL, "bar"); conf.border.bar = fetch_opt_first(bar, "false", "border").boolean; conf.bars.height = fetch_opt_first(bar, "-1", "height").num; conf.colors.bar = getcolor((barbg = fetch_opt_first(bar, "#000000", "bg").str)); conf.colors.text = fetch_opt_first(bar, "#ffffff", "fg").str; conf.colors.bar_light_shade = fetch_opt_first(bar, "0.25", "light_shade").fnum; conf.colors.bar_dark_shade = fetch_opt_first(bar, "-0.25", "dark_shade").fnum; mouse = fetch_section(bar, "mouse"); if ((conf.bars.nmouse = fetch_section_count(mouse)) > 0) { conf.bars.mouse = xcalloc(conf.bars.nmouse, sizeof(MouseBinding)); mouse_section(conf.bars.mouse, mouse); } free(mouse); if((systray = fetch_section_first(bar, "systray"))) { conf.systray.active = fetch_opt_first(systray, "true", "active").boolean; if((conf.systray.screen = fetch_opt_first(systray, "0", "screen").num) < 0 || conf.systray.screen >= sc) conf.systray.screen = 0; if((conf.systray.spacing = fetch_opt_first(systray, "3", "spacing").num) < 0) conf.systray.spacing = 0; } else conf.systray.active = False; selbar = fetch_section_first(bar, "selbar"); conf.bars.selbar = selbar ? True : False; conf.selbar.bg = getcolor(fetch_opt_first(selbar, barbg, "bg").str); conf.selbar.fg = fetch_opt_first(selbar, conf.colors.text, "fg").str; conf.selbar.maxlength = fetch_opt_first(selbar, "-1", "max_length").num; mouse = fetch_section(selbar, "mouse"); if ((conf.selbar.nmouse = fetch_section_count(mouse))) { conf.selbar.mouse = xcalloc(conf.selbar.nmouse, sizeof(MouseBinding)); mouse_section(conf.selbar.mouse, mouse); } free(mouse); return; } static void conf_root_section(void) { struct conf_sec *root, **mouse; root = fetch_section_first(NULL, "root"); conf.root.background_command = fetch_opt_first(root, "", "background_command").str; mouse = fetch_section(root, "mouse"); if ((conf.root.nmouse = fetch_section_count(mouse)) > 0) { conf.root.mouse = xcalloc(conf.root.nmouse, sizeof(MouseBinding)); mouse_section(conf.root.mouse, mouse); } free(mouse); return; } static void conf_client_section(void) { int i, j; char *flags, *p; struct conf_sec *sec, **mouse, *titlebar, **button, **line; struct opt_type *opt; sec = fetch_section_first(NULL, "client"); conf.client_round = fetch_opt_first(sec, "true", "client_round").boolean; conf.client_auto_center = fetch_opt_first(sec, "false", "client_auto_center").boolean; conf.client_tile_raise = fetch_opt_first(sec, "false", "client_tile_raise").boolean; if ((conf.client.borderheight = fetch_opt_first(sec, "1", "border_height").num) < 1) conf.client.borderheight = 1; conf.client.border_shadow = fetch_opt_first(sec, "false", "border_shadow").boolean; conf.client.place_at_mouse = fetch_opt_first(sec, "false", "place_at_mouse").boolean; conf.client.bordernormal = getcolor(fetch_opt_first(sec, "#000000", "border_normal").str); conf.client.borderfocus = getcolor(fetch_opt_first(sec, "#ffffff", "border_focus").str); conf.client.resizecorner_normal = getcolor(fetch_opt_first(sec, "#222222", "resize_corner_normal").str); conf.client.resizecorner_focus = getcolor(fetch_opt_first(sec, "#DDDDDD", "resize_corner_focus").str); conf.client.mod |= char_to_modkey(fetch_opt_first(sec, "Alt", "modifier").str, key_list); conf.client.set_new_win_master = fetch_opt_first(sec, "true", "set_new_win_master").boolean; conf.client.padding = fetch_opt_first(sec, "0", "padding").num; conf.client.autofree = fetch_opt_first(sec, "", "autofree").str; conf.client.automax = fetch_opt_first(sec, "", "automax").str; conf.client.default_open_tag = fetch_opt_first(sec, "0", "default_open_tag").num; conf.client.default_open_screen = fetch_opt_first(sec, "-1", "default_open_screen").num; conf.client.new_client_get_mouse = fetch_opt_first(sec, "false", "new_client_get_mouse").boolean; conf.colors.client_light_shade = fetch_opt_first(sec, "0.25", "light_shade").fnum; conf.colors.client_dark_shade = fetch_opt_first(sec, "-0.25", "dark_shade").fnum; mouse = fetch_section(sec, "mouse"); if((conf.client.nmouse = fetch_section_count(mouse)) > 0) { conf.client.mouse = xcalloc(conf.client.nmouse, sizeof(MouseBinding)); mouse_section(conf.client.mouse, mouse); } free(mouse); titlebar = fetch_section_first(sec, "titlebar"); conf.titlebar.height = fetch_opt_first(titlebar, "0", "height").num; conf.titlebar.fg_normal = fetch_opt_first(titlebar, "#ffffff", "fg_normal").str; conf.titlebar.fg_focus = fetch_opt_first(titlebar, "#000000", "fg_focus").str; conf.titlebar.stipple.active = fetch_opt_first(titlebar, "false", "stipple").boolean; if(!strcmp((p = fetch_opt_first(titlebar, "-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 = fetch_opt_first(titlebar, "-1", "stipple_focus").str), "-1")) conf.titlebar.stipple.colors.focus = getcolor(conf.titlebar.fg_focus); else conf.titlebar.stipple.colors.focus = getcolor(p); mouse = fetch_section(titlebar, "mouse"); if((conf.titlebar.nmouse = fetch_section_count(mouse)) > 0) { conf.titlebar.mouse = xcalloc(conf.titlebar.nmouse, sizeof(MouseBinding)); mouse_section(conf.titlebar.mouse, mouse); } free(mouse); /* Multi button part */ button = fetch_section(titlebar, "button"); if((conf.titlebar.nbutton = fetch_section_count(button)) > 0) { conf.titlebar.button = xcalloc(conf.titlebar.nbutton, sizeof(Button)); for(i = 0; i < conf.titlebar.nbutton; ++i) { flags = fetch_opt_first(button[i], "none", "flags").str; conf.titlebar.button[i].flags = 0; if(strstr(flags, "free")) conf.titlebar.button[i].flags |= FreeFlag; if(strstr(flags, "max")) conf.titlebar.button[i].flags |= MaxFlag; if(strstr(flags, "tile")) conf.titlebar.button[i].flags |= TileFlag; /* Multi mouse section */ mouse = fetch_section(button[i], "mouse"); if((conf.titlebar.button[i].nmouse = fetch_section_count(mouse)) > 0) { conf.titlebar.button[i].mouse = xcalloc(conf.titlebar.button[i].nmouse, sizeof(MouseBinding)); mouse_section(conf.titlebar.button[i].mouse, mouse); } free(mouse); /* Multi line section */ line = fetch_section(button[i], "line"); if((conf.titlebar.button[i].nlines = fetch_section_count(line)) > 0) { conf.titlebar.button[i].linecoord = xcalloc(conf.titlebar.button[i].nlines, sizeof(XSegment)); for(j = 0; j < conf.titlebar.button[i].nlines; ++j) { opt = fetch_opt(line[j], "0", "coord"); conf.titlebar.button[i].linecoord[j].x1 = opt[0].num; conf.titlebar.button[i].linecoord[j].y1 = opt[1].num; conf.titlebar.button[i].linecoord[j].x2 = opt[2].num; conf.titlebar.button[i].linecoord[j].y2 = opt[3].num; free(opt); } } free(line); } } free(button); return; } static void conf_layout_section(void) { int i; char *tmp = NULL, *p; struct conf_sec *layouts, **layout; /* 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; } layouts = fetch_section_first(NULL, "layouts"); conf.layout_button_width = fetch_opt_first(layouts, "O", "layout_button_width").num; conf.border.layout = fetch_opt_first(layouts, "false", "border").boolean; conf.colors.layout_fg = fetch_opt_first(layouts, "#ffffff", "fg").str; conf.colors.layout_bg = getcolor((fetch_opt_first(layouts, "#000000", "bg").str)); conf.keep_layout_geo = fetch_opt_first(layouts, "false", "keep_layout_geo").boolean; conf.selected_layout_symbol = fetch_opt_first(layouts, "*", "selected_layout_symbol").str; conf.cfactor_enable_split = fetch_opt_first(layouts, "false", "cfactor_enable_split").boolean; if((tmp = fetch_opt_first(layouts, "menu", "system").str) && !strcmp(tmp, "menu")) conf.layout_system = True; if((tmp = fetch_opt_first(layouts, "right", "placement").str) && !strcmp(tmp, "left")) conf.layout_placement = True; layout = fetch_section(layouts, "layout"); conf.nlayout = fetch_section_count(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 = xstrdup("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) { if(!name_to_func((p = fetch_opt_first(layout[i], "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], fetch_opt_first(layout[i], "", "symbol").str, uicb_set_layout, p); menulayout.item[i].check = name_to_func("check_layout", func_list); } conf.layout[i].symbol = fetch_opt_first(layout[i], "TILE (default)", "symbol").str; conf.layout[i].func = name_to_func(p, layout_list); conf.layout[i].type = p; } } } free(layout); return; } static void conf_tag_section(void) { int i, j, k, l = 0, n, sc, bar_pos; char *tmp; char *position; struct conf_sec *sec, *def_tag, **tag, **mouse; sec = fetch_section_first(NULL, "tags"); conf.tag_round = fetch_opt_first(sec, "false", "tag_round").boolean; conf.tag_auto_prev = fetch_opt_first(sec, "true", "tag_auto_prev").boolean; conf.colors.tagselfg = fetch_opt_first(sec, "#ffffff", "sel_fg").str; conf.colors.tagselbg = getcolor(fetch_opt_first(sec, "#000000", "sel_bg").str); conf.colors.tagurfg = fetch_opt_first(sec, "#000000", "urgent_fg").str; conf.colors.tagurbg = getcolor(fetch_opt_first(sec, "#DD1111", "urgent_bg").str); conf.colors.tag_occupied_bg = getcolor(fetch_opt_first(sec, "#222222", "occupied_bg").str); conf.colors.tag_occupied_fg = fetch_opt_first(sec, conf.colors.text, "occupied_fg").str; conf.border.tag = fetch_opt_first(sec, "false", "border").boolean; conf.tagautohide = fetch_opt_first(sec, "false", "autohide").boolean; conf.tagnamecount = fetch_opt_first(sec, "false", "name_count").boolean; conf.tag_expose_name = fetch_opt_first(sec, "EXPOSE", "expose_name").str; conf.expose_layout = fetch_opt_first(sec, "tile_grid_vertical", "expose_layout").str; def_tag = fetch_section_first(sec, "default_tag"); position = fetch_opt_first(def_tag, "top", "infobar_position").str; if(!strcmp(position, "none") || !strcmp(position, "hide") || !strcmp(position, "hidden")) bar_pos = IB_Hide; else if(!strcmp(position, "bottom") || !strcmp(position, "down")) bar_pos = IB_Bottom; else bar_pos = IB_Top; /* If there is no tag in the conf or more than * MAXTAG (36) print an error and create only one. */ Tag default_tag = { fetch_opt_first(def_tag, "new tag", "name").str, NULL, 1, fetch_opt_first(def_tag, "0.6", "mwfact").fnum, fetch_opt_first(def_tag, "1", "nmaster").num, 0, bar_pos, bar_pos, layout_name_to_struct(conf.layout, fetch_opt_first(def_tag, "tile", "layout").str, conf.nlayout, layout_list), 0, NULL, 0 }; FLAGAPPLY(default_tag.flags, fetch_opt_first(def_tag, "false", "resizehint").boolean, ResizeHintFlag); FLAGAPPLY(default_tag.flags, fetch_opt_first(def_tag, "false", "split").boolean, (SplitFlag | FirstArrangeFlag)); conf.default_tag = default_tag; /* Mouse button action on tag */ conf.mouse_tag_action[TagSel] = char_to_button(fetch_opt_first(sec, "1", "mouse_button_tag_sel").str, mouse_button_list); conf.mouse_tag_action[TagTransfert] = char_to_button(fetch_opt_first(sec, "2", "mouse_button_tag_transfert").str, mouse_button_list); conf.mouse_tag_action[TagAdd] = char_to_button(fetch_opt_first(sec, "3", "mouse_button_tag_add").str, mouse_button_list); conf.mouse_tag_action[TagNext] = char_to_button(fetch_opt_first(sec, "4", "mouse_button_tag_next").str, mouse_button_list); conf.mouse_tag_action[TagPrev] = char_to_button(fetch_opt_first(sec, "5", "mouse_button_tag_prev").str, mouse_button_list); sc = screen_count(); /* Alloc all */ conf.ntag = xcalloc(sc, sizeof(*conf.ntag)); tags = xcalloc(sc, sizeof(*tags)); seltag = xcalloc(sc, sizeof(*seltag)); prevseltag = xcalloc(sc, sizeof(*prevseltag)); for(i = 0; i < sc; ++i) seltag[i] = 1; tag = fetch_section(sec, "tag"); n = fetch_section_count(tag); for(i = 0; i < sc; ++i) tags[i] = xcalloc(n + 2, sizeof(Tag)); for(i = 0; i < n; i++) { j = fetch_opt_first(tag[i], "-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 = fetch_opt_first(tag[i], fetch_opt_first(def_tag, "", "name").str, "name").str; tags[k][conf.ntag[k]].mwfact = fetch_opt_first(tag[i], fetch_opt_first(def_tag, "0.65", "mwfact").str, "mwfact").fnum; tags[k][conf.ntag[k]].nmaster = fetch_opt_first(tag[i], fetch_opt_first(def_tag, "1", "nmaster").str, "nmaster").num; FLAGAPPLY(tags[k][conf.ntag[k]].flags, fetch_opt_first(tag[i], fetch_opt_first(def_tag, "false", "resizehint").str, "resizehint").boolean, ResizeHintFlag); FLAGAPPLY(tags[k][conf.ntag[k]].flags, fetch_opt_first(tag[i], "false", "abovefc").boolean, AboveFCFlag); FLAGAPPLY(tags[k][conf.ntag[k]].flags, fetch_opt_first(tag[i], "false", "split").boolean, (SplitFlag | FirstArrangeFlag)); tmp = fetch_opt_first(tag[i], fetch_opt_first(def_tag, "top", "infobar_position").str, "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, fetch_opt_first(tag[i], fetch_opt_first(def_tag, "tile", "layout").str, "layout").str, conf.nlayout, layout_list); /* Multi mouse sections */ mouse = fetch_section(tag[i], "mouse"); if((tags[k][conf.ntag[k]].nmouse = fetch_section_count(mouse))) { tags[k][conf.ntag[k]].mouse = xcalloc(tags[k][conf.ntag[k]].nmouse, sizeof(MouseBinding)); mouse_section(tags[k][conf.ntag[k]].mouse, mouse); } free(mouse); } l = 0; } 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; } free(tag); return; } static void conf_rule_section(void) { int i; struct conf_sec *rules, **rule; if ((rules = fetch_section_first(NULL, "rules")) == NULL) return; rule = fetch_section(rules, "rule"); CHECK((conf.nrule = fetch_section_count(rule))); conf.rule = xcalloc(conf.nrule, sizeof(Rule)); for(i = 0; i < conf.nrule; ++i) { conf.rule[i].class = fetch_opt_first(rule[i], "", "class").str; conf.rule[i].instance = fetch_opt_first(rule[i], "", "instance").str; conf.rule[i].role = fetch_opt_first(rule[i], "", "role").str; conf.rule[i].screen = fetch_opt_first(rule[i], "-1", "screen").num; conf.rule[i].tag = fetch_opt_first(rule[i], "-1", "tag").num; conf.rule[i].free = fetch_opt_first(rule[i], "false", "free").boolean; conf.rule[i].max = fetch_opt_first(rule[i], "false", "max").boolean; conf.rule[i].ignoretags = fetch_opt_first(rule[i], "false", "ignoretags").boolean; conf.rule[i].follow_client = fetch_opt_first(rule[i], "false", "follow_client").boolean; } free(rule); return; } static void conf_menu_section(void) { char *tmp2; int i, j; struct conf_sec *menu, **set_menu, **item; menu = fetch_section_first(NULL, "menu"); set_menu = fetch_section(menu, "set_menu"); CHECK((conf.nmenu = fetch_section_count(set_menu))); conf.menu = xcalloc(conf.nmenu, sizeof(Menu)); for(i = 0; i < conf.nmenu; ++i) { conf.menu[i].name = fetch_opt_first(set_menu[i], "menu_wname", "name").str; if(!(conf.menu[i].place_at_mouse = fetch_opt_first(set_menu[i], "true", "place_at_mouse").boolean)) { conf.menu[i].x = fetch_opt_first(set_menu[i], "0", "x").num; conf.menu[i].y = fetch_opt_first(set_menu[i], "0", "y").num; } tmp2 = fetch_opt_first(set_menu[i], "center", "align").str; if(!strcmp(tmp2 ,"left")) conf.menu[i].align = MA_Left; else if(!strcmp(tmp2, "right")) conf.menu[i].align = MA_Right; else conf.menu[i].align = MA_Center; conf.menu[i].colors.focus.bg = getcolor(fetch_opt_first(set_menu[i], "#000000", "bg_focus").str); conf.menu[i].colors.focus.fg = fetch_opt_first(set_menu[i], "#ffffff", "fg_focus").str; conf.menu[i].colors.normal.bg = getcolor(fetch_opt_first(set_menu[i], "#000000", "bg_normal").str); conf.menu[i].colors.normal.fg = fetch_opt_first(set_menu[i], "#ffffff", "fg_normal").str; item = fetch_section(set_menu[i], "item"); if((conf.menu[i].nitem = fetch_section_count(item))) { conf.menu[i].item = xcalloc(conf.menu[i].nitem, sizeof(MenuItem)); for(j = 0; j < conf.menu[i].nitem; ++j) { conf.menu[i].item[j].name = fetch_opt_first(item[j], "item_wname", "name").str; conf.menu[i].item[j].func = name_to_func(fetch_opt_first(item[j], "", "func").str, func_list); conf.menu[i].item[j].cmd = fetch_opt_first(item[j], "", "cmd").str; conf.menu[i].item[j].check = name_to_func(fetch_opt_first(item[j], "", "check").str, func_list); conf.menu[i].item[j].submenu = fetch_opt_first(item[j], "", "submenu").str; } } free(item); } free(set_menu); return; } static void conf_launcher_section(void) { int i; struct conf_sec *launcher, **set_launcher; launcher = fetch_section_first(NULL, "launcher"); set_launcher = fetch_section(launcher, "set_launcher"); CHECK((conf.nlauncher = fetch_section_count(set_launcher))); conf.launcher = xcalloc(conf.nlauncher, sizeof(Launcher)); for(i = 0; i < conf.nlauncher; ++i) { conf.launcher[i].name = fetch_opt_first(set_launcher[i], "launcher", "name").str; conf.launcher[i].prompt = fetch_opt_first(set_launcher[i], "Exec:", "prompt").str; conf.launcher[i].command = fetch_opt_first(set_launcher[i], "exec", "command").str; conf.launcher[i].width = fetch_opt_first(set_launcher[i], "0", "width_limit").num; conf.launcher[i].nhisto = 1; } free(set_launcher); return; } static void conf_keybind_section(void) { int i; size_t j; struct conf_sec *sec, **ks; struct opt_type *opt; sec = fetch_section_first(NULL, "keys"); ks = fetch_section(sec, "key"); conf.nkeybind = fetch_section_count(ks); keys = xcalloc(conf.nkeybind, sizeof(Key)); for(i = 0; i < conf.nkeybind; ++i) { opt = fetch_opt(ks[i], "", "mod"); for(j = 0; j < fetch_opt_count(opt); ++j) keys[i].mod |= char_to_modkey(opt[j].str, key_list); free(opt); keys[i].keysym = XStringToKeysym(fetch_opt_first(ks[i], "None", "key").str); keys[i].func = name_to_func(fetch_opt_first(ks[i], "", "func").str, func_list); if(keys[i].func == NULL) { warnx("configuration : Unknown Function \"%s\".", fetch_opt_first(ks[i], "", "func").str); keys[i].func = uicb_spawn; } keys[i].cmd = fetch_opt_first(ks[i], "", "cmd").str; } free(ks); return; } /** Configuration initialization */ void init_conf(void) { if(get_conf(conf.confpath) == -1) { 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); if(get_conf(conf.confpath) == -1) errx(1, "parsing configuration file (%s) failed.", conf.confpath); } conf_misc_section(); conf_bar_section(); conf_root_section(); conf_client_section(); conf_layout_section(); conf_tag_section(); conf_rule_section(); conf_menu_section(); conf_launcher_section(); conf_keybind_section(); print_unused(NULL); return; }