source: neercs/trunk/src/configuration.c

Last change on this file was 4366, checked in by Sam Hocevar, 13 years ago

Clean up source code, copyright information, author names, SVN keywords...

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