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

Last change on this file since 4038 was 4038, checked in by Jean-Yves Lamoureux, 10 years ago
  • Better python command handling
  • Added get(str) to neercs python module, doesn't work as I would like to
  • Avoid redefining everything while including neercs.h several times
  • Property svn:keywords set to Id
File size: 13.8 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 4038 2009-11-25 15:07:46Z jylam $
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 = get_delay},
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   
325    debug("Looking for '%s'\n", name);
326   
327    while (strncmp(config_option[i].name, "last", strlen("last")))
328    {
329        debug("%d Testing against '%s'\n", i, config_option[i].name);
330        if (!strncmp(name, config_option[i].name, strlen(name)))
331        {
332            debug("Found\n");
333            return &config_option[i];
334        }
335        i++;
336    }
337    return NULL;
338}
339
340
341
342int fill_config(struct screen_list *screen_list)
343{
344    int i = 0;
345    struct option *option = screen_list->config;
346
347    while (option)
348    {
349        if (option->key == NULL)
350        {
351            option = option->next;
352            continue;
353        }
354
355        struct config_line *c = get_config(option->key);
356        if (c)
357        {
358            c->set((const char *)option->value, screen_list);
359        }
360        option = option->next;
361    }
362
363    return i;
364}
365
366
367
368/*
369 * Options setters
370 */
371
372#define IS_OPTION(t) (!strncmp(argv, t, strlen(argv)))
373#define IS_OPTION_TRUE (IS_OPTION("true") || IS_OPTION("1"))
374
375int set_window_manager(const char *argv, struct screen_list *screen_list)
376{
377    if (IS_OPTION("full"))
378        screen_list->wm_type = WM_FULL;
379    else if (IS_OPTION("hsplit"))
380        screen_list->wm_type = WM_HSPLIT;
381    else if (IS_OPTION("vsplit"))
382        screen_list->wm_type = WM_VSPLIT;
383    else if (IS_OPTION("card"))
384        screen_list->wm_type = WM_CARD;
385    else
386    {
387        fprintf(stderr, "Unknown window manager '%s'\n", argv);
388        return -1;
389    }
390    return 0;
391}
392
393int set_cube_duration(const char *argv, struct screen_list *screen_list)
394{
395    screen_list->cube.duration = atoi(argv) * 1000000;
396    return 0;
397}
398
399int set_thumbnails(const char *argv, struct screen_list *screen_list)
400{
401    if (IS_OPTION_TRUE)
402        screen_list->mini = 1;
403    else
404        screen_list->mini = 0;
405    return 0;
406
407}
408
409int set_status_bar(const char *argv, struct screen_list *screen_list)
410{
411    if (IS_OPTION_TRUE)
412        screen_list->status = 1;
413    else
414        screen_list->status = 0;
415    return 0;
416}
417
418int set_screensaver_timeout(const char *argv, struct screen_list *screen_list)
419{
420    screen_list->screensaver_timeout = atoi(argv) * 1000000;
421    /* if timeout is 0, set it to 0xFFFFFFFFFFFFFFFF */
422    if (!screen_list->screensaver_timeout)
423        screen_list->screensaver_timeout -= 1;
424    return 0;
425}
426
427int set_autolock_timeout(const char *argv, struct screen_list *screen_list)
428{
429    if (screen_list->autolock_timeout == 0 ||
430        screen_list->autolock_timeout == ((long long unsigned int)0) - 1)
431    {
432        screen_list->autolock_timeout = atoi(argv) * 1000000;
433        /* if timeout is 0, set it to 0xFFFFFFFFFFFFFFFF */
434        if (!screen_list->autolock_timeout)
435            screen_list->autolock_timeout -= 1;
436    }
437    return 0;
438}
439
440int set_lock_on_detach(const char *argv, struct screen_list *screen_list)
441{
442    if (IS_OPTION_TRUE)
443        screen_list->lock_on_detach = 1;
444    else
445        screen_list->lock_on_detach = 0;
446    return 0;
447}
448
449int set_eyecandy(const char *argv, struct screen_list *screen_list)
450{
451    if (IS_OPTION_TRUE)
452        screen_list->eyecandy = 1;
453    else
454        screen_list->eyecandy = 0;
455    return 0;
456}
457
458int set_border(const char *argv, struct screen_list *screen_list)
459{
460    if (IS_OPTION_TRUE)
461        screen_list->border_size = 1;
462    else
463        screen_list->border_size = 0;
464    return 0;
465}
466
467int set_socket_dir(const char *argv, struct screen_list *screen_list)
468{
469    screen_list->socket_dir = strdup(argv);
470    return 0;
471}
472
473int set_delay(const char *argv, struct screen_list *screen_list)
474{
475    screen_list->requested_delay = atoi(argv);
476    screen_list->delay = atoi(argv);
477    return 0;
478}
479
480char *get_window_manager(struct screen_list *screen_list)
481{
482    debug("Window manager is %d\n", screen_list->wm_type);
483    switch (screen_list->wm_type)
484    {
485    case WM_FULL:
486        return "full";
487    case WM_CARD:
488        return "card";
489    case WM_VSPLIT:
490        return "vsplit";
491    case WM_HSPLIT:
492        return "hsplit";
493    default:
494        return "invalid window manager";
495    }
496    return NULL;                /* Not reached */
497}
498
499char *get_cube_duration(struct screen_list *screen_list)
500{
501    char *r = malloc(100);
502    sprintf(r, "%f", (float)screen_list->cube.duration / 1000000.0f);
503    return r;
504}
505
506char *get_thumbnails(struct screen_list *screen_list)
507{
508    if (screen_list->mini)
509        return "yes";
510    return "no";
511}
512
513char *get_status_bar(struct screen_list *screen_list)
514{
515    if (screen_list->status)
516        return "yes";
517    return "no";
518}
519
520char *get_eyecandy(struct screen_list *screen_list)
521{
522    if (screen_list->eyecandy)
523        return "yes";
524    return "no";
525}
526
527char *get_border(struct screen_list *screen_list)
528{
529    if (screen_list->border_size)
530        return "yes";
531    return "no";
532}
533
534char *get_screensaver_timeout(struct screen_list *screen_list)
535{
536    char *r = malloc(100);
537    sprintf(r, "%f", (float)screen_list->screensaver_timeout / 1000000.0f);
538    return r;
539}
540
541char *get_autolock_timeout(struct screen_list *screen_list)
542{
543    char *r = malloc(100);
544    sprintf(r, "%f", (float)screen_list->autolock_timeout / 1000000.0f);
545    return r;
546}
547
548char *get_lock_on_detach(struct screen_list *screen_list)
549{
550    if (screen_list->lock_on_detach)
551        return "yes";
552    else
553        return "no";
554}
555
556char *get_socket_dir(struct screen_list *screen_list)
557{
558    return screen_list->socket_dir;
559}
560
561char *get_delay(struct screen_list *screen_list)
562{
563    char *r = malloc(100);
564    sprintf(r, "%d", screen_list->requested_delay);
565    return r;
566}
Note: See TracBrowser for help on using the repository browser.