Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 
 

578 rader
14 KiB

  1. /*
  2. * neercs console-based window manager
  3. * Copyright (c) 2006-2010 Sam Hocevar <sam@hocevar.net>
  4. * 2008-2010 Jean-Yves Lamoureux <jylam@lnxscene.org>
  5. * All Rights Reserved
  6. *
  7. * This program is free software. It comes without any warranty, to
  8. * the extent permitted by applicable law. You can redistribute it
  9. * and/or modify it under the terms of the Do What The Fuck You Want
  10. * To Public License, Version 2, as published by Sam Hocevar. See
  11. * http://www.wtfpl.net/ for more details.
  12. */
  13. #if defined HAVE_CONFIG_H
  14. # include "config.h"
  15. #endif
  16. #if !defined _WIN32
  17. #include <fcntl.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <sys/types.h>
  21. #include <sys/stat.h>
  22. #include <unistd.h>
  23. #include <errno.h>
  24. #include <string.h>
  25. #include "neercs.h"
  26. struct config_line *get_config(const char *name);
  27. int set_window_manager(const char *argv, struct screen_list *screen_list);
  28. int set_cube_duration(const char *argv, struct screen_list *screen_list);
  29. int set_thumbnails(const char *argv, struct screen_list *screen_list);
  30. int set_status_bar(const char *argv, struct screen_list *screen_list);
  31. int set_screensaver_timeout(const char *argv, struct screen_list *screen_list);
  32. int set_autolock_timeout(const char *argv, struct screen_list *screen_list);
  33. int set_lock_on_detach(const char *argv, struct screen_list *screen_list);
  34. int set_socket_dir(const char *argv, struct screen_list *screen_list);
  35. int set_delay(const char *argv, struct screen_list *screen_list);
  36. int set_eyecandy(const char *argv, struct screen_list *screen_list);
  37. int set_border(const char *argv, struct screen_list *screen_list);
  38. char *get_window_manager(struct screen_list *screen_list);
  39. char *get_cube_duration(struct screen_list *screen_list);
  40. char *get_thumbnails(struct screen_list *screen_list);
  41. char *get_status_bar(struct screen_list *screen_list);
  42. char *get_screensaver_timeout(struct screen_list *screen_list);
  43. char *get_autolock_timeout(struct screen_list *screen_list);
  44. char *get_lock_on_detach(struct screen_list *screen_list);
  45. char *get_socket_dir(struct screen_list *screen_list);
  46. char *get_delay(struct screen_list *screen_list);
  47. char *get_eyecandy(struct screen_list *screen_list);
  48. char *get_border(struct screen_list *screen_list);
  49. /* Options definition and associated function pointer */
  50. struct config_line config_option[] = {
  51. {.name = "window_manager",.set = set_window_manager,.get =
  52. get_window_manager},
  53. {.name = "eyecandy",.set = set_eyecandy,.get = get_eyecandy},
  54. {.name = "borders",.set = set_border,.get = get_border},
  55. {.name = "cube_duration",.set = set_cube_duration,.get =
  56. get_cube_duration},
  57. {.name = "thumbnails",.set = set_thumbnails,.get = get_thumbnails},
  58. {.name = "status_bar",.set = set_status_bar,.get = get_status_bar},
  59. {.name = "screensaver_timeout",.set = set_screensaver_timeout,.get =
  60. get_screensaver_timeout},
  61. {.name = "autolock_timeout",.set = set_autolock_timeout,.get =
  62. get_autolock_timeout},
  63. {.name = "lock_on_detach",.set = set_lock_on_detach,.get =
  64. get_lock_on_detach},
  65. {.name = "socket_dir",.set = set_socket_dir,.get = get_socket_dir},
  66. {.name = "delay",.set = set_delay,.get = get_delay},
  67. {.name = "last",.set = NULL},
  68. };
  69. int read_configuration_file(char *filename, struct screen_list *screen_list)
  70. {
  71. FILE *fp;
  72. struct stat st;
  73. int size = 0, i = 0, total = 0, offset = 0, l = 1;
  74. char *buffer = NULL;
  75. screen_list->config = NULL;
  76. /* Check if file exist */
  77. if (stat(filename, &st) < 0)
  78. {
  79. return -1;
  80. }
  81. /* Get its size */
  82. size = st.st_size;
  83. if (!size)
  84. {
  85. fprintf(stderr, "File too short\n");
  86. return -1;
  87. }
  88. /* Open it */
  89. fp = fopen(filename, "r");
  90. if (!fp)
  91. {
  92. return -1;
  93. }
  94. buffer = malloc(size + 1);
  95. if (!buffer)
  96. {
  97. fclose(fp);
  98. fprintf(stderr, "Can't allocate memory at %s:%d\n", __FUNCTION__,
  99. __LINE__);
  100. return -1;
  101. }
  102. /* Read it */
  103. while ((i = fread(buffer + total, 1, size, fp)) > 0)
  104. {
  105. total += i;
  106. }
  107. buffer[total] = '\n';
  108. fclose(fp);
  109. /* Parse it */
  110. while ((i =
  111. parse_conf_line(buffer + offset, total - offset, screen_list)) > 0)
  112. {
  113. offset += i;
  114. l++;
  115. }
  116. free(buffer);
  117. /* Fill neercs configuration with it */
  118. fill_config(screen_list);
  119. return 1;
  120. }
  121. struct config_line *get_config_option(void)
  122. {
  123. return config_option;
  124. }
  125. int parse_conf_line(char *buf, int size, struct screen_list *screen_list)
  126. {
  127. int i, s = 0, c = 0;
  128. char *line = NULL;
  129. int l = 0;
  130. int in_quote = 0, end_spaces = 0;
  131. static struct option *prev = NULL;
  132. if (size <= 0)
  133. return -1;
  134. /* Find EOL */
  135. for (i = 0; i < size; i++)
  136. {
  137. if (buf[i] == '\n')
  138. {
  139. s = i + 1;
  140. break;
  141. }
  142. }
  143. /* Strip comments and trailing spaces */
  144. for (i = 0; i < s; i++)
  145. {
  146. if (buf[i] == ';' && !in_quote)
  147. {
  148. break;
  149. }
  150. else if (buf[i] == '\n')
  151. {
  152. break;
  153. }
  154. else if (buf[i] == ' ' && !c)
  155. {
  156. }
  157. else
  158. {
  159. if (line == NULL)
  160. {
  161. line = malloc(2);
  162. if (!line)
  163. {
  164. fprintf(stderr, "Can't allocate memory at %s:%d\n",
  165. __FUNCTION__, __LINE__);
  166. return -1;
  167. }
  168. }
  169. else
  170. {
  171. line = realloc(line, l + 2);
  172. if (!line)
  173. {
  174. fprintf(stderr, "Can't allocate memory at %s:%d\n",
  175. __FUNCTION__, __LINE__);
  176. return -1;
  177. }
  178. }
  179. if (buf[i] == '"')
  180. in_quote = !in_quote;
  181. if (buf[i] == ' ')
  182. end_spaces++;
  183. else
  184. end_spaces = 0;
  185. line[l] = buf[i];
  186. line[l + 1] = 0;
  187. l++;
  188. c = 1;
  189. }
  190. }
  191. if (c == 0)
  192. {
  193. /* This line is empty, do nothing */
  194. }
  195. else
  196. {
  197. struct option *option = malloc(sizeof(struct option));
  198. if (!option)
  199. {
  200. fprintf(stderr, "Can't allocate memory at %s:%d\n",
  201. __FUNCTION__, __LINE__);
  202. return -1;
  203. }
  204. option->next = NULL;
  205. l -= end_spaces;
  206. line = realloc(line, l + 1);
  207. line[l] = 0;
  208. get_key_value(line, option);
  209. if (!screen_list->config)
  210. screen_list->config = option;
  211. if (prev)
  212. prev->next = option;
  213. prev = option;
  214. }
  215. free(line);
  216. return s;
  217. }
  218. int get_key_value(char *line, struct option *option)
  219. {
  220. unsigned int i, o = 0, b = 0, end_spaces = 0;
  221. char *cur = NULL;
  222. option->value = NULL;
  223. option->key = NULL;
  224. /* Line is a section delimiter */
  225. if (line[0] == '[')
  226. {
  227. option->value = malloc(strlen(line) - 1);
  228. if (!option->value)
  229. {
  230. fprintf(stderr, "Can't allocate memory at %s:%d\n",
  231. __FUNCTION__, __LINE__);
  232. return -1;
  233. }
  234. memcpy(option->value, line + 1, strlen(line) - 1);
  235. option->value[strlen(line) - 2] = 0;
  236. return 0;
  237. }
  238. cur = malloc(1);
  239. if (!cur)
  240. {
  241. fprintf(stderr, "Can't allocate memory at %s:%d\n",
  242. __FUNCTION__, __LINE__);
  243. return -1;
  244. }
  245. cur[0] = 0;
  246. for (i = 0; i < strlen(line); i++)
  247. {
  248. if (line[i] == ' ' && !b)
  249. continue;
  250. if (line[i] == '=')
  251. {
  252. b = 0;
  253. cur[o - end_spaces] = 0;
  254. cur = realloc(cur, (o - end_spaces) + 1);
  255. if (!cur)
  256. {
  257. fprintf(stderr, "Can't allocate memory at %s:%d\n",
  258. __FUNCTION__, __LINE__);
  259. return -1;
  260. }
  261. o = 0;
  262. option->key = cur;
  263. cur = malloc(1);
  264. }
  265. else
  266. {
  267. if (line[i] == ' ')
  268. end_spaces++;
  269. else
  270. end_spaces = 0;
  271. cur = realloc(cur, o + 2);
  272. if (!cur)
  273. {
  274. fprintf(stderr, "Can't allocate memory at %s:%d\n",
  275. __FUNCTION__, __LINE__);
  276. return -1;
  277. }
  278. cur[o] = line[i];
  279. o++;
  280. b = 1;
  281. }
  282. }
  283. cur[o] = 0;
  284. option->value = cur;
  285. return 0;
  286. }
  287. struct config_line *get_config(const char *name)
  288. {
  289. int i = 0;
  290. debug("Looking for '%s'\n", name);
  291. while (strncmp(config_option[i].name, "last", strlen("last")))
  292. {
  293. debug("%d Testing against '%s'\n", i, config_option[i].name);
  294. if (!strncmp(name, config_option[i].name, strlen(name)))
  295. {
  296. debug("Found\n");
  297. return &config_option[i];
  298. }
  299. i++;
  300. }
  301. return NULL;
  302. }
  303. int fill_config(struct screen_list *screen_list)
  304. {
  305. int i = 0;
  306. struct option *option = screen_list->config;
  307. while (option)
  308. {
  309. if (option->key == NULL)
  310. {
  311. option = option->next;
  312. continue;
  313. }
  314. struct config_line *c = get_config(option->key);
  315. if (c)
  316. {
  317. c->set((const char *)option->value, screen_list);
  318. }
  319. option = option->next;
  320. }
  321. return i;
  322. }
  323. /*
  324. * Options setters
  325. */
  326. #define IS_OPTION(t) (!strncmp(argv, t, strlen(argv)))
  327. #define IS_OPTION_TRUE (IS_OPTION("true") || IS_OPTION("True") || IS_OPTION("1"))
  328. int set_window_manager(const char *argv, struct screen_list *screen_list)
  329. {
  330. if (IS_OPTION("full"))
  331. screen_list->wm_type = WM_FULL;
  332. else if (IS_OPTION("hsplit"))
  333. screen_list->wm_type = WM_HSPLIT;
  334. else if (IS_OPTION("vsplit"))
  335. screen_list->wm_type = WM_VSPLIT;
  336. else if (IS_OPTION("card"))
  337. screen_list->wm_type = WM_CARD;
  338. else
  339. {
  340. fprintf(stderr, "Unknown window manager '%s'\n", argv);
  341. return -1;
  342. }
  343. return 0;
  344. }
  345. int set_cube_duration(const char *argv, struct screen_list *screen_list)
  346. {
  347. screen_list->cube.duration = atoi(argv) * 1000000;
  348. return 0;
  349. }
  350. int set_thumbnails(const char *argv, struct screen_list *screen_list)
  351. {
  352. if (IS_OPTION_TRUE)
  353. screen_list->modals.mini = 1;
  354. else
  355. screen_list->modals.mini = 0;
  356. return 0;
  357. }
  358. int set_status_bar(const char *argv, struct screen_list *screen_list)
  359. {
  360. if (IS_OPTION_TRUE)
  361. screen_list->modals.status = 1;
  362. else
  363. screen_list->modals.status = 0;
  364. return 0;
  365. }
  366. int set_screensaver_timeout(const char *argv, struct screen_list *screen_list)
  367. {
  368. screen_list->screensaver.timeout = atoi(argv) * 1000000;
  369. /* if timeout is 0, set it to 0xFFFFFFFFFFFFFFFF */
  370. if (!screen_list->screensaver.timeout)
  371. screen_list->screensaver.timeout -= 1;
  372. return 0;
  373. }
  374. int set_autolock_timeout(const char *argv, struct screen_list *screen_list)
  375. {
  376. if (screen_list->lock.autolock_timeout == 0 ||
  377. screen_list->lock.autolock_timeout == ((long long unsigned int)0) - 1)
  378. {
  379. screen_list->lock.autolock_timeout = atoi(argv) * 1000000;
  380. /* if timeout is 0, set it to 0xFFFFFFFFFFFFFFFF */
  381. if (!screen_list->lock.autolock_timeout)
  382. screen_list->lock.autolock_timeout -= 1;
  383. }
  384. return 0;
  385. }
  386. int set_lock_on_detach(const char *argv, struct screen_list *screen_list)
  387. {
  388. if (IS_OPTION_TRUE)
  389. screen_list->lock.lock_on_detach = 1;
  390. else
  391. screen_list->lock.lock_on_detach = 0;
  392. return 0;
  393. }
  394. int set_eyecandy(const char *argv, struct screen_list *screen_list)
  395. {
  396. if (IS_OPTION_TRUE)
  397. screen_list->eyecandy = 1;
  398. else
  399. screen_list->eyecandy = 0;
  400. return 0;
  401. }
  402. int set_border(const char *argv, struct screen_list *screen_list)
  403. {
  404. if (IS_OPTION_TRUE)
  405. screen_list->border_size = 1;
  406. else
  407. screen_list->border_size = 0;
  408. return 0;
  409. }
  410. int set_socket_dir(const char *argv, struct screen_list *screen_list)
  411. {
  412. screen_list->comm.socket_dir = strdup(argv);
  413. return 0;
  414. }
  415. int set_delay(const char *argv, struct screen_list *screen_list)
  416. {
  417. screen_list->requested_delay = atoi(argv);
  418. screen_list->delay = atoi(argv);
  419. return 0;
  420. }
  421. char *get_window_manager(struct screen_list *screen_list)
  422. {
  423. debug("Window manager is %d", screen_list->wm_type);
  424. switch (screen_list->wm_type)
  425. {
  426. case WM_FULL:
  427. return "full";
  428. case WM_CARD:
  429. return "card";
  430. case WM_VSPLIT:
  431. return "vsplit";
  432. case WM_HSPLIT:
  433. return "hsplit";
  434. default:
  435. return "invalid window manager";
  436. }
  437. return NULL; /* Not reached */
  438. }
  439. char *get_cube_duration(struct screen_list *screen_list)
  440. {
  441. char *r = malloc(100);
  442. sprintf(r, "%f", (float)screen_list->cube.duration / 1000000.0f);
  443. return r;
  444. }
  445. char *get_thumbnails(struct screen_list *screen_list)
  446. {
  447. if (screen_list->modals.mini)
  448. return "true";
  449. return "false";
  450. }
  451. char *get_status_bar(struct screen_list *screen_list)
  452. {
  453. if (screen_list->modals.status)
  454. return "true";
  455. return "false";
  456. }
  457. char *get_eyecandy(struct screen_list *screen_list)
  458. {
  459. if (screen_list->eyecandy)
  460. return "true";
  461. return "false";
  462. }
  463. char *get_border(struct screen_list *screen_list)
  464. {
  465. if (screen_list->border_size)
  466. return "true";
  467. return "false";
  468. }
  469. char *get_screensaver_timeout(struct screen_list *screen_list)
  470. {
  471. char *r = malloc(100);
  472. sprintf(r, "%f", (float)screen_list->screensaver.timeout / 1000000.0f);
  473. return r;
  474. }
  475. char *get_autolock_timeout(struct screen_list *screen_list)
  476. {
  477. char *r = malloc(100);
  478. sprintf(r, "%f", (float)screen_list->lock.autolock_timeout / 1000000.0f);
  479. return r;
  480. }
  481. char *get_lock_on_detach(struct screen_list *screen_list)
  482. {
  483. if (screen_list->lock.lock_on_detach)
  484. return "true";
  485. else
  486. return "false";
  487. }
  488. char *get_socket_dir(struct screen_list *screen_list)
  489. {
  490. return screen_list->comm.socket_dir;
  491. }
  492. char *get_delay(struct screen_list *screen_list)
  493. {
  494. char *r = malloc(100);
  495. sprintf(r, "%d", screen_list->requested_delay);
  496. return r;
  497. }
  498. #endif