config.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654
  1. /*
  2. * config.c
  3. * Copyright © 2008, 2009 Martin Duquesnoy <xorg62@gmail.com>
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are
  8. * met:
  9. *
  10. * * Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * * Redistributions in binary form must reproduce the above
  13. * copyright notice, this list of conditions and the following disclaimer
  14. * in the documentation and/or other materials provided with the
  15. * distribution.
  16. * * Neither the name of the nor the names of its
  17. * contributors may be used to endorse or promote products derived from
  18. * this software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. */
  32. #include "wmfs.h"
  33. /* local function definition */
  34. static void conf_section(void (*)(char*), char *, char *);
  35. func_name_list_t tmp_func_list[] =
  36. {
  37. {"spawn", uicb_spawn },
  38. {"client_kill", uicb_client_kill },
  39. {"client_prev", uicb_client_prev },
  40. {"client_next", uicb_client_next },
  41. {"client_swap_next", uicb_client_swap_next },
  42. {"client_swap_prev", uicb_client_swap_prev },
  43. {"client_screen_next", uicb_client_screen_next },
  44. {"client_screen_prev", uicb_client_screen_prev },
  45. {"client_move", uicb_client_move },
  46. {"client_resize", uicb_client_resize },
  47. {"toggle_max", uicb_togglemax },
  48. {"layout_next", uicb_layout_next },
  49. {"layout_prev", uicb_layout_prev },
  50. {"tag", uicb_tag },
  51. {"tag_next", uicb_tag_next },
  52. {"tag_prev", uicb_tag_prev },
  53. {"tag_prev_sel", uicb_tag_prev_sel },
  54. {"tag_transfert", uicb_tagtransfert },
  55. {"tag_transfert_next", uicb_tagtransfert_next },
  56. {"tag_transfert_prev", uicb_tagtransfert_prev },
  57. {"set_mwfact", uicb_set_mwfact },
  58. {"set_nmaster", uicb_set_nmaster },
  59. {"quit", uicb_quit },
  60. {"toggle_infobar_position", uicb_infobar_togglepos },
  61. {"toggle_resizehint", uicb_toggle_resizehint },
  62. {"mouse_move", uicb_mouse_move },
  63. {"mouse_resize", uicb_mouse_resize },
  64. {"client_raise", uicb_client_raise },
  65. {"toggle_free", uicb_togglefree },
  66. {"toggle_abovefc", uicb_toggle_abovefc },
  67. {"screen_select", uicb_screen_select },
  68. {"screen_next", uicb_screen_next },
  69. {"screen_prev", uicb_screen_prev },
  70. {"screen_prev_sel", uicb_screen_prev_sel},
  71. {"reload", uicb_reload },
  72. {"launcher", uicb_launcher },
  73. {"set_layout", uicb_set_layout },
  74. {"menu", uicb_menu },
  75. {"set_client_layer", uicb_set_client_layer },
  76. {"set_layer", uicb_set_layer },
  77. {"ignore_next_client_rules", uicb_ignore_next_client_rules }
  78. };
  79. key_name_list_t key_list[] =
  80. {
  81. {"Control", ControlMask },
  82. {"Shift", ShiftMask },
  83. {"Lock", LockMask },
  84. {"Alt", Mod1Mask },
  85. {"Mod2", Mod2Mask },
  86. {"Mod3", Mod3Mask },
  87. {"Mod4", Mod4Mask },
  88. {"Super", Mod4Mask },
  89. {"Mod5", Mod5Mask },
  90. {NULL, NoSymbol }
  91. };
  92. name_to_uint_t mouse_button_list[] =
  93. {
  94. {"Button1", Button1 },
  95. {"Button2", Button2 },
  96. {"Button3", Button3 },
  97. {"Button4", Button4 },
  98. {"Button5", Button5 },
  99. {"1", Button1 },
  100. {"2", Button2 },
  101. {"3", Button3 },
  102. {"4", Button4 },
  103. {"5", Button5 },
  104. };
  105. void
  106. mouse_section(MouseBinding mb[], char *src, int ns)
  107. {
  108. int i;
  109. char *tmp;
  110. for(i = 0; i < ns; ++i)
  111. {
  112. tmp = get_nsec(src, "mouse", i);
  113. cfg_set_sauv(tmp);
  114. mb[i].tag = get_opt(tmp, "-1", "tag").num;
  115. mb[i].screen = get_opt(tmp, "-1", "screen").num;
  116. mb[i].button = char_to_button(get_opt(tmp, "1", "button").str, mouse_button_list);
  117. mb[i].func = name_to_func(get_opt(tmp, "", "func").str, func_list);
  118. mb[i].cmd = get_opt(tmp, "", "cmd").str;
  119. cfg_set_sauv(src);
  120. }
  121. return;
  122. }
  123. void
  124. conf_misc_section(char *src)
  125. {
  126. int pad = 12;
  127. cfg_set_sauv(src);
  128. conf.font = get_opt(src, "sans-9", "font").str;
  129. conf.raisefocus = get_opt(src, "false", "raisefocus").bool;
  130. conf.raiseswitch = get_opt(src, "false", "raiseswitch").bool;
  131. conf.focus_fmouse = get_opt(src, "true", "focus_follow_mouse").bool;
  132. conf.status_timing = get_opt(src, "1", "status_timing").num;
  133. conf.status_path = get_opt(src, "", "status_path").str;
  134. pad = get_opt(src, "12", "pad").num;
  135. if(pad > 24 || pad < 1)
  136. {
  137. warnx("configuration : pad value (%d) incorrect.", pad);
  138. pad = 12;
  139. }
  140. conf.pad = pad;
  141. if(conf.status_timing <= 0)
  142. {
  143. warnx("configuration : status_timing value (%d) incorrect.", conf.status_timing);
  144. conf.status_timing = 1;
  145. }
  146. return;
  147. }
  148. void
  149. conf_bar_section(char *src)
  150. {
  151. cfg_set_sauv(src);
  152. conf.border.bar = get_opt(src, "false", "border").bool;
  153. conf.bars.height = get_opt(src, "-1", "height").num;
  154. conf.colors.bar = getcolor(get_opt(src, "#000000", "bg").str);
  155. conf.colors.text = get_opt(src, "#ffffff", "fg").str;
  156. conf.bars.selbar = get_opt(src, "false", "selbar").bool;
  157. if((conf.bars.nmouse = get_size_sec(src, "mouse")))
  158. {
  159. conf.bars.mouse = emalloc(conf.bars.nmouse, sizeof(MouseBinding));
  160. mouse_section(conf.bars.mouse, src, conf.bars.nmouse);
  161. }
  162. return;
  163. }
  164. void
  165. conf_root_section(char *src)
  166. {
  167. cfg_set_sauv(src);
  168. conf.root.background_command = get_opt(src, "", "background_command").str;
  169. if((conf.root.nmouse = get_size_sec(src, "mouse")))
  170. {
  171. conf.root.mouse = emalloc(conf.root.nmouse, sizeof(MouseBinding));
  172. mouse_section(conf.root.mouse, src, conf.root.nmouse);
  173. }
  174. return;
  175. }
  176. void
  177. conf_client_section(char *src)
  178. {
  179. int i, j, d;
  180. char *tmp, *tmp2, *tmp3, *p;
  181. opt_type *buf;
  182. /* Client misc */
  183. cfg_set_sauv(src);
  184. conf.client.borderheight = (get_opt(src, "1", "border_height").num) ? get_opt(src, "1", "border_height").num : 1;
  185. conf.client.border_shadow = get_opt(src, "false", "border_shadow").bool;
  186. conf.client.place_at_mouse = get_opt(src, "false", "place_at_mouse").bool;
  187. conf.client.bordernormal = getcolor(get_opt(src, "#000000", "border_normal").str);
  188. conf.client.borderfocus = getcolor(get_opt(src, "#ffffff", "border_focus").str);
  189. conf.client.resizecorner_normal = getcolor(get_opt(src, "#222222", "resize_corner_normal").str);
  190. conf.client.resizecorner_focus = getcolor(get_opt(src, "#DDDDDD", "resize_corner_focus").str);
  191. conf.client.mod |= char_to_modkey(get_opt(src, "Alt", "modifier").str, key_list);
  192. conf.client.set_new_win_master = get_opt(src, "true", "set_new_win_master").bool;
  193. if((conf.client.nmouse = get_size_sec(src, "mouse")))
  194. {
  195. conf.client.mouse = emalloc(conf.client.nmouse, sizeof(MouseBinding));
  196. mouse_section(conf.client.mouse, src, conf.client.nmouse);
  197. }
  198. /* Titlebar part {{ */
  199. tmp = get_sec(src, "titlebar");
  200. cfg_set_sauv(tmp);
  201. conf.titlebar.height = get_opt(tmp, "0", "height").num;
  202. conf.titlebar.fg_normal = get_opt(tmp, "#ffffff", "fg_normal").str;
  203. conf.titlebar.fg_focus = get_opt(tmp, "#000000", "fg_focus").str;
  204. /* Stipple */
  205. conf.titlebar.stipple.active = get_opt(tmp, "false", "stipple").bool;
  206. if(!strcmp((p = get_opt(tmp, "-1", "stipple_normal").str), "-1"))
  207. conf.titlebar.stipple.colors.normal = getcolor(conf.titlebar.fg_normal);
  208. else
  209. conf.titlebar.stipple.colors.normal = getcolor(p);
  210. if(!strcmp((p = get_opt(tmp, "-1", "stipple_focus").str), "-1"))
  211. conf.titlebar.stipple.colors.focus = getcolor(conf.titlebar.fg_focus);
  212. else
  213. conf.titlebar.stipple.colors.focus = getcolor(p);
  214. if((conf.titlebar.nmouse = get_size_sec(tmp, "mouse")))
  215. {
  216. conf.titlebar.mouse = emalloc(conf.titlebar.nmouse, sizeof(MouseBinding));
  217. mouse_section(conf.titlebar.mouse, tmp, conf.titlebar.nmouse);
  218. }
  219. /* Multi button part */
  220. if((conf.titlebar.nbutton = get_size_sec(tmp, "button")))
  221. {
  222. conf.titlebar.button = emalloc(conf.titlebar.nbutton, sizeof(Button));
  223. for(i = 0; i < conf.titlebar.nbutton; ++i)
  224. {
  225. tmp2 = get_nsec(tmp, "button", i);
  226. cfg_set_sauv(tmp2);
  227. tmp3 = get_opt(tmp2, "none", "flags").str;
  228. conf.titlebar.button[i].flags = 0;
  229. if(strstr(tmp3, "free"))
  230. conf.titlebar.button[i].flags |= FreeFlag;
  231. if(strstr(tmp3, "max"))
  232. conf.titlebar.button[i].flags |= MaxFlag;
  233. if(strstr(tmp3, "tile"))
  234. conf.titlebar.button[i].flags |= TileFlag;
  235. /* Multi mouse section */
  236. if((conf.titlebar.button[i].nmouse = get_size_sec(tmp2, "mouse")))
  237. {
  238. conf.titlebar.button[i].mouse = emalloc(conf.titlebar.button[i].nmouse, sizeof(MouseBinding));
  239. mouse_section(conf.titlebar.button[i].mouse, tmp2, conf.titlebar.button[i].nmouse);
  240. }
  241. /* Multi line section */
  242. if((conf.titlebar.button[i].nlines = get_size_sec(tmp2, "line")))
  243. {
  244. conf.titlebar.button[i].linecoord = emalloc(conf.titlebar.button[i].nlines, sizeof(XSegment));
  245. for(j = 0; j < conf.titlebar.button[i].nlines; ++j)
  246. {
  247. tmp3 = get_nsec(tmp2, "line", j);
  248. cfg_set_sauv(tmp3);
  249. buf = get_list_opt(tmp3, "{0, 0, 0, 0}", "coord", &d);
  250. conf.titlebar.button[i].linecoord[j].x1 = buf[0].num;
  251. conf.titlebar.button[i].linecoord[j].y1 = buf[1].num;
  252. conf.titlebar.button[i].linecoord[j].x2 = buf[2].num;
  253. conf.titlebar.button[i].linecoord[j].y2 = buf[3].num;
  254. cfg_set_sauv(tmp2);
  255. }
  256. }
  257. cfg_set_sauv(tmp);
  258. }
  259. }
  260. /* }} */
  261. return;
  262. }
  263. void
  264. conf_layout_section(char *src)
  265. {
  266. int i;
  267. char *tmp = NULL, *p;
  268. /* Set conf.layout NULL for conf reload */
  269. for(i = 0; i < NUM_OF_LAYOUT; ++i)
  270. {
  271. conf.layout[i].symbol = NULL;
  272. conf.layout[i].func = NULL;
  273. }
  274. cfg_set_sauv(src);
  275. conf.border.layout = get_opt(src, "false", "border").bool;
  276. conf.colors.layout_fg = get_opt(src, "#ffffff", "fg").str;
  277. conf.colors.layout_bg = getcolor((get_opt(src, "#000000", "bg").str));
  278. if((tmp = get_opt(src, "menu", "system").str) && !strcmp(tmp, "menu"))
  279. conf.layout_system = True;
  280. if((tmp = get_opt(src, "right", "placement").str) && !strcmp(tmp, "left"))
  281. conf.layout_placement = True;
  282. conf.nlayout = get_size_sec(src, "layout");
  283. if(conf.nlayout > NUM_OF_LAYOUT || !(conf.nlayout))
  284. {
  285. warnx("configuration : Too many or no layouts (%d).", conf.nlayout);
  286. conf.nlayout = 1;
  287. conf.layout[0].symbol = _strdup("TILE");
  288. conf.layout[0].func = tile;
  289. }
  290. if(conf.layout_system && conf.nlayout > 1)
  291. {
  292. menu_init(&menulayout, "menulayout", conf.nlayout,
  293. /* Colors */
  294. conf.colors.layout_bg,
  295. conf.colors.layout_fg,
  296. conf.colors.bar,
  297. conf.colors.text);
  298. }
  299. if(!conf.layout[0].symbol
  300. && !conf.layout[0].func)
  301. {
  302. for(i = 0; i < conf.nlayout; ++i)
  303. {
  304. tmp = get_nsec(src, "layout", i);
  305. cfg_set_sauv(tmp);
  306. if(!name_to_func((p = get_opt(tmp, "tile", "type").str), layout_list))
  307. warnx("configuration : Unknown Layout type : \"%s\".", p);
  308. else
  309. {
  310. if(conf.layout_system && conf.nlayout > 1)
  311. menu_new_item(&menulayout.item[i], get_opt(tmp, "", "symbol").str,
  312. uicb_set_layout, p);
  313. conf.layout[i].symbol = get_opt(tmp, "TILE (default)", "symbol").str;
  314. conf.layout[i].func = name_to_func(p, layout_list);
  315. }
  316. cfg_set_sauv(src);
  317. }
  318. }
  319. return;
  320. }
  321. void
  322. conf_tag_section(char *src)
  323. {
  324. int i, j, k, l = 0, m, n, sc;
  325. char *cfgtmp, *tmp;
  326. opt_type *buf;
  327. /* If there is no tag in the conf or more than
  328. * MAXTAG (32) print an error and create only one.
  329. */
  330. Tag default_tag = { "WMFS", NULL, 0, 1,
  331. 0.50, 1, False, False, False, IB_Top,
  332. layout_name_to_struct(conf.layout, "tile_right", conf.nlayout, layout_list) };
  333. cfg_set_sauv(src);
  334. conf.tag_round = get_opt(src, "false", "tag_round").bool;
  335. conf.colors.tagselfg = get_opt(src, "#ffffff", "sel_fg").str;
  336. conf.colors.tagselbg = getcolor(get_opt(src, "#000000", "sel_bg").str);
  337. conf.colors.tag_occupied_bg = getcolor(get_opt(src, "#222222", "occupied_bg").str);
  338. conf.border.tag = get_opt(src, "false", "border").bool;
  339. sc = screen_count();
  340. /* Alloc all */
  341. conf.ntag = emalloc(sc, sizeof(int));
  342. tags = emalloc(sc, sizeof(Tag*));
  343. seltag = emalloc(sc, sizeof(int));
  344. prevseltag = emalloc(sc, sizeof(int));
  345. for(i = 0; i < sc; ++i)
  346. seltag[i] = 1;
  347. for(i = 0; i < sc; ++i)
  348. tags[i] = emalloc(get_size_sec(src, "tag") + 2, sizeof(Tag));
  349. for(i = 0; i < get_size_sec(src, "tag"); ++i)
  350. {
  351. /* printf("%d -> %s\n", i, (cfgtmp = get_nsec(src, "tag", i)));*/
  352. cfgtmp = get_nsec(src, "tag", i);
  353. cfg_set_sauv(cfgtmp);
  354. j = get_opt(cfgtmp, "-1", "screen").num;
  355. if(j < 0 || j > sc - 1)
  356. j = -1;
  357. for(k = ((j == -1) ? 0 : j);
  358. ((j == -1) ? (k < sc) : !l);
  359. ((j == -1) ? ++k : --l))
  360. {
  361. ++conf.ntag[k];
  362. tags[k][conf.ntag[k]].name = get_opt(cfgtmp, "", "name").str;
  363. tags[k][conf.ntag[k]].mwfact = get_opt(cfgtmp, "0.65", "mwfact").fnum;
  364. tags[k][conf.ntag[k]].nmaster = get_opt(cfgtmp, "1", "nmaster").num;
  365. tags[k][conf.ntag[k]].resizehint = get_opt(cfgtmp, "false", "resizehint").bool;
  366. tags[k][conf.ntag[k]].abovefc = get_opt(cfgtmp, "false", "abovefc").bool;
  367. tags[k][conf.ntag[k]].layers = 1;
  368. tmp = _strdup(get_opt(cfgtmp, "top", "infobar_position").str);
  369. if(!strcmp(tmp ,"none") || !strcmp(tmp, "hide") || !strcmp(tmp, "hidden"))
  370. tags[k][conf.ntag[k]].barpos = IB_Hide;
  371. else if(!strcmp(tmp, "bottom") || !strcmp(tmp, "down"))
  372. tags[k][conf.ntag[k]].barpos = IB_Bottom;
  373. else
  374. tags[k][conf.ntag[k]].barpos = IB_Top;
  375. tags[k][conf.ntag[k]].layout = layout_name_to_struct(conf.layout,
  376. get_opt(cfgtmp, "tile_right", "layout").str,
  377. conf.nlayout,
  378. layout_list);
  379. /* Clients list */
  380. buf = get_list_opt(cfgtmp, "", "clients", &n);
  381. if(n)
  382. {
  383. tags[k][conf.ntag[k]].nclients = n;
  384. tags[k][conf.ntag[k]].clients = emalloc(n, sizeof(char *));
  385. for(m = 0; m < n; ++m)
  386. tags[k][conf.ntag[k]].clients[m] = (buf[m].str) ? buf[m].str : NULL;
  387. }
  388. }
  389. l = 0;
  390. cfg_set_sauv(src);
  391. }
  392. for(i = 0; i < sc; ++i)
  393. if(!conf.ntag[i] || conf.ntag[i] > MAXTAG)
  394. {
  395. warnx("configuration : Too many or no tag (%d) in the screen %d.", conf.ntag[i], i);
  396. conf.ntag[i] = 1;
  397. tags[i][1] = default_tag;
  398. }
  399. return;
  400. }
  401. void
  402. conf_menu_section(char *src)
  403. {
  404. char *tmp, *tmp2;
  405. int i, j;
  406. cfg_set_sauv(src);
  407. CHECK((conf.nmenu = get_size_sec(src, "set_menu")));
  408. conf.menu = calloc(conf.nmenu, sizeof(Menu));
  409. for(i = 0; i < conf.nmenu; ++i)
  410. {
  411. tmp = get_nsec(src, "set_menu", i);
  412. cfg_set_sauv(tmp);
  413. conf.menu[i].name = get_opt(tmp, "menu_wname", "name").str;
  414. if(!(conf.menu[i].place_at_mouse = get_opt(tmp, "true", "place_at_mouse").bool))
  415. {
  416. conf.menu[i].x = get_opt(tmp, "0", "x").num;
  417. conf.menu[i].y = get_opt(tmp, "0", "y").num;
  418. }
  419. conf.menu[i].colors.focus.bg = getcolor(get_opt(tmp, "#000000", "bg_focus").str);
  420. conf.menu[i].colors.focus.fg = get_opt(tmp, "#ffffff", "fg_focus").str;
  421. conf.menu[i].colors.normal.bg = getcolor(get_opt(tmp, "#000000", "bg_normal").str);
  422. conf.menu[i].colors.normal.fg = get_opt(tmp, "#ffffff", "fg_normal").str;
  423. if((conf.menu[i].nitem = get_size_sec(tmp, "item")))
  424. {
  425. conf.menu[i].item = emalloc(conf.menu[i].nitem, sizeof(MenuItem));
  426. for(j = 0; j < get_size_sec(tmp, "item"); ++j)
  427. {
  428. tmp2 = get_nsec(tmp, "item", j);
  429. cfg_set_sauv(tmp2);
  430. conf.menu[i].item[j].name = get_opt(tmp2, "item_wname", "name").str;
  431. conf.menu[i].item[j].func = name_to_func(get_opt(tmp2, "", "func").str, func_list);
  432. conf.menu[i].item[j].cmd = (!get_opt(tmp2, "", "cmd").str) ? NULL : get_opt(tmp2, "", "cmd").str;
  433. cfg_set_sauv(tmp);
  434. }
  435. }
  436. cfg_set_sauv(src);
  437. }
  438. return;
  439. }
  440. void
  441. conf_launcher_section(char *src)
  442. {
  443. int i;
  444. char *tmp;
  445. cfg_set_sauv(src);
  446. CHECK((conf.nlauncher = get_size_sec(src, "set_launcher")));
  447. conf.launcher = emalloc(conf.nlauncher, sizeof(Launcher));
  448. for(i = 0; i < conf.nlauncher; ++i)
  449. {
  450. tmp = get_nsec(src, "set_launcher", i);
  451. cfg_set_sauv(tmp);
  452. conf.launcher[i].name = get_opt(tmp, "launcher", "name").str;
  453. conf.launcher[i].prompt = get_opt(tmp, "Exec:", "prompt").str;
  454. conf.launcher[i].command = get_opt(tmp, "exec", "command").str;
  455. cfg_set_sauv(src);
  456. }
  457. return;
  458. }
  459. void
  460. conf_keybind_section(char *src)
  461. {
  462. int i, j, n = 0;
  463. char *tmp;
  464. opt_type *buf;
  465. cfg_set_sauv(src);
  466. conf.nkeybind = get_size_sec(src, "key");
  467. keys = emalloc(conf.nkeybind, sizeof(Key));
  468. for(i = 0; i < conf.nkeybind; ++i)
  469. {
  470. tmp = get_nsec(src, "key", i);
  471. cfg_set_sauv(tmp);
  472. buf = get_list_opt(tmp, "", "mod", &n);
  473. for(j = 0; j < n; ++j)
  474. keys[i].mod |= char_to_modkey(buf[j].str, key_list);
  475. keys[i].keysym = XStringToKeysym(get_opt(tmp, "None", "key").str);
  476. keys[i].func = name_to_func(get_opt(tmp, "", "func").str, func_list);
  477. if(keys[i].func == NULL)
  478. {
  479. warnx("configuration : Unknown Function \"%s\".", get_opt(tmp, "", "func").str);
  480. keys[i].func = uicb_spawn;
  481. }
  482. keys[i].cmd = (!get_opt(tmp, "", "cmd").str) ? NULL : get_opt(tmp, "", "cmd").str;
  483. cfg_set_sauv(src);
  484. }
  485. return;
  486. }
  487. /** Configuration initialization
  488. */
  489. void
  490. init_conf(void)
  491. {
  492. char *file;
  493. if(!(file = file_to_str(conf.confpath)))
  494. {
  495. warnx("parsing configuration file (%s) failed.", conf.confpath);
  496. sprintf(conf.confpath, "%s/wmfs/wmfsrc", XDG_CONFIG_DIR);
  497. warnx("Use the default configuration (%s).", conf.confpath);
  498. file = file_to_str(conf.confpath);
  499. }
  500. /* Set func_list */
  501. func_list = emalloc(LEN(tmp_func_list), sizeof(func_name_list_t));
  502. memcpy(func_list, tmp_func_list, LEN(tmp_func_list) * sizeof(func_name_list_t));
  503. conf_section(conf_misc_section, file, "misc");
  504. conf_section(conf_bar_section, file, "bar");
  505. conf_section(conf_root_section, file, "root");
  506. conf_section(conf_client_section, file, "client");
  507. conf_section(conf_layout_section, file, "layouts");
  508. conf_section(conf_tag_section, file, "tags");
  509. conf_section(conf_menu_section, file, "menu");
  510. conf_section(conf_launcher_section, file, "launcher");
  511. conf_section(conf_keybind_section, file, "keys");
  512. free(file);
  513. return;
  514. }
  515. /** Simple wrapper for calling functions and free pointer
  516. */
  517. static void
  518. conf_section(void (*func)(char*), char *src, char *name)
  519. {
  520. char *sec;
  521. sec = get_sec(src, name);
  522. func(sec);
  523. IFREE(sec);
  524. return;
  525. }