source: neercs/trunk/src/configuration.c @ 4022

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