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

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