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

Last change on this file since 4063 was 4063, checked in by jylam, 5 years ago
  • Moved modal windows flags to struct modal
  • Property svn:keywords set to Id
File size: 14.0 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 4063 2009-11-29 12:48:53Z 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_cube_duration},
60    {.name = "thumbnails",.set = set_thumbnails,.get = get_thumbnails},
61    {.name = "status_bar",.set = set_status_bar,.get = get_status_bar},
62    {.name = "screensaver_timeout",.set = set_screensaver_timeout,.get =
63     get_screensaver_timeout},
64    {.name = "autolock_timeout",.set = set_autolock_timeout,.get =
65     get_autolock_timeout},
66    {.name = "lock_on_detach",.set = set_lock_on_detach,.get =
67     get_lock_on_detach},
68    {.name = "socket_dir",.set = set_socket_dir,.get = get_socket_dir},
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
138struct config_line *get_config_option(void)
139{
140        return config_option;   
141}
142
143int parse_conf_line(char *buf, int size, struct screen_list *screen_list)
144{
145    int i, s = 0, c = 0;
146    char *line = NULL;
147    int l = 0;
148    int in_quote = 0, end_spaces = 0;
149    static struct option *prev = NULL;
150
151    if (size <= 0)
152        return -1;
153
154    /* Find EOL */
155    for (i = 0; i < size; i++)
156    {
157        if (buf[i] == '\n')
158        {
159            s = i + 1;
160            break;
161        }
162    }
163
164    /* Strip comments and trailing spaces */
165    for (i = 0; i < s; i++)
166    {
167        if (buf[i] == ';' && !in_quote)
168        {
169            break;
170        }
171        else if (buf[i] == '\n')
172        {
173            break;
174        }
175        else if (buf[i] == ' ' && !c)
176        {
177        }
178        else
179        {
180            if (line == NULL)
181            {
182                line = malloc(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            else
191            {
192                line = realloc(line, l + 2);
193                if (!line)
194                {
195                    fprintf(stderr, "Can't allocate memory at %s:%d\n",
196                            __FUNCTION__, __LINE__);
197                    return -1;
198                }
199            }
200            if (buf[i] == '"')
201                in_quote = !in_quote;
202            if (buf[i] == ' ')
203                end_spaces++;
204            else
205                end_spaces = 0;
206
207            line[l] = buf[i];
208            line[l + 1] = 0;
209            l++;
210            c = 1;
211        }
212    }
213
214    if (c == 0)
215    {
216        /* This line is empty, do nothing */
217    }
218    else
219    {
220        struct option *option = malloc(sizeof(struct option));
221        if (!option)
222        {
223            fprintf(stderr, "Can't allocate memory at %s:%d\n",
224                    __FUNCTION__, __LINE__);
225            return -1;
226        }
227        option->next = NULL;
228        l -= end_spaces;
229        line = realloc(line, l + 1);
230        line[l] = 0;
231
232        get_key_value(line, option);
233
234        if (!screen_list->config)
235            screen_list->config = option;
236
237        if (prev)
238            prev->next = option;
239
240        prev = option;
241    }
242    free(line);
243    return s;
244}
245
246int get_key_value(char *line, struct option *option)
247{
248    unsigned int i, o = 0, b = 0, end_spaces = 0;
249    char *cur = NULL;
250    option->value = NULL;
251    option->key = NULL;
252
253    /* Line is a section delimiter */
254    if (line[0] == '[')
255    {
256        option->value = malloc(strlen(line) - 1);
257        if (!option->value)
258        {
259            fprintf(stderr, "Can't allocate memory at %s:%d\n",
260                    __FUNCTION__, __LINE__);
261            return -1;
262        }
263        memcpy(option->value, line + 1, strlen(line) - 1);
264        option->value[strlen(line) - 2] = 0;
265        return 0;
266    }
267
268    cur = malloc(1);
269    if (!cur)
270    {
271        fprintf(stderr, "Can't allocate memory at %s:%d\n",
272                __FUNCTION__, __LINE__);
273        return -1;
274    }
275    cur[0] = 0;
276
277    for (i = 0; i < strlen(line); i++)
278    {
279        if (line[i] == ' ' && !b)
280            continue;
281
282
283        if (line[i] == '=')
284        {
285            b = 0;
286            cur[o - end_spaces] = 0;
287            cur = realloc(cur, (o - end_spaces) + 1);
288            if (!cur)
289            {
290                fprintf(stderr, "Can't allocate memory at %s:%d\n",
291                        __FUNCTION__, __LINE__);
292                return -1;
293            }
294            o = 0;
295            option->key = cur;
296            cur = malloc(1);
297        }
298        else
299        {
300            if (line[i] == ' ')
301                end_spaces++;
302            else
303                end_spaces = 0;
304
305            cur = realloc(cur, o + 2);
306            if (!cur)
307            {
308                fprintf(stderr, "Can't allocate memory at %s:%d\n",
309                        __FUNCTION__, __LINE__);
310                return -1;
311            }
312            cur[o] = line[i];
313            o++;
314            b = 1;
315
316        }
317    }
318    cur[o] = 0;
319    option->value = cur;
320    return 0;
321}
322
323
324
325struct config_line *get_config(const char *name)
326{
327    int i = 0;
328   
329    debug("Looking for '%s'\n", name);
330   
331    while (strncmp(config_option[i].name, "last", strlen("last")))
332    {
333        debug("%d Testing against '%s'\n", i, config_option[i].name);
334        if (!strncmp(name, config_option[i].name, strlen(name)))
335        {
336            debug("Found\n");
337            return &config_option[i];
338        }
339        i++;
340    }
341    return NULL;
342}
343
344
345
346int fill_config(struct screen_list *screen_list)
347{
348    int i = 0;
349    struct option *option = screen_list->config;
350
351    while (option)
352    {
353        if (option->key == NULL)
354        {
355            option = option->next;
356            continue;
357        }
358
359        struct config_line *c = get_config(option->key);
360        if (c)
361        {
362            c->set((const char *)option->value, screen_list);
363        }
364        option = option->next;
365    }
366
367    return i;
368}
369
370
371
372/*
373 * Options setters
374 */
375
376#define IS_OPTION(t) (!strncmp(argv, t, strlen(argv)))
377#define IS_OPTION_TRUE (IS_OPTION("true") || IS_OPTION("True") || IS_OPTION("1"))
378
379int set_window_manager(const char *argv, struct screen_list *screen_list)
380{
381    if (IS_OPTION("full"))
382        screen_list->wm_type = WM_FULL;
383    else if (IS_OPTION("hsplit"))
384        screen_list->wm_type = WM_HSPLIT;
385    else if (IS_OPTION("vsplit"))
386        screen_list->wm_type = WM_VSPLIT;
387    else if (IS_OPTION("card"))
388        screen_list->wm_type = WM_CARD;
389    else
390    {
391        fprintf(stderr, "Unknown window manager '%s'\n", argv);
392        return -1;
393    }
394    return 0;
395}
396
397int set_cube_duration(const char *argv, struct screen_list *screen_list)
398{
399    screen_list->cube.duration = atoi(argv) * 1000000;
400    return 0;
401}
402
403int set_thumbnails(const char *argv, struct screen_list *screen_list)
404{
405    if (IS_OPTION_TRUE)
406        screen_list->modals.mini = 1;
407    else
408        screen_list->modals.mini = 0;
409    return 0;
410
411}
412
413int set_status_bar(const char *argv, struct screen_list *screen_list)
414{
415    if (IS_OPTION_TRUE)
416        screen_list->modals.status = 1;
417    else
418        screen_list->modals.status = 0;
419    return 0;
420}
421
422int set_screensaver_timeout(const char *argv, struct screen_list *screen_list)
423{
424    screen_list->screensaver.timeout = atoi(argv) * 1000000;
425    /* if timeout is 0, set it to 0xFFFFFFFFFFFFFFFF */
426    if (!screen_list->screensaver.timeout)
427        screen_list->screensaver.timeout -= 1;
428    return 0;
429}
430
431int set_autolock_timeout(const char *argv, struct screen_list *screen_list)
432{
433    if (screen_list->lock.autolock_timeout == 0 ||
434        screen_list->lock.autolock_timeout == ((long long unsigned int)0) - 1)
435    {
436        screen_list->lock.autolock_timeout = atoi(argv) * 1000000;
437        /* if timeout is 0, set it to 0xFFFFFFFFFFFFFFFF */
438        if (!screen_list->lock.autolock_timeout)
439            screen_list->lock.autolock_timeout -= 1;
440    }
441    return 0;
442}
443
444int set_lock_on_detach(const char *argv, struct screen_list *screen_list)
445{
446    if (IS_OPTION_TRUE)
447        screen_list->lock.lock_on_detach = 1;
448    else
449        screen_list->lock.lock_on_detach = 0;
450    return 0;
451}
452
453int set_eyecandy(const char *argv, struct screen_list *screen_list)
454{
455    if (IS_OPTION_TRUE)
456        screen_list->eyecandy = 1;
457    else
458        screen_list->eyecandy = 0;
459    return 0;
460}
461
462int set_border(const char *argv, struct screen_list *screen_list)
463{
464    if (IS_OPTION_TRUE)
465        screen_list->border_size = 1;
466    else
467        screen_list->border_size = 0;
468    return 0;
469}
470
471int set_socket_dir(const char *argv, struct screen_list *screen_list)
472{
473    screen_list->comm.socket_dir = strdup(argv);
474    return 0;
475}
476
477int set_delay(const char *argv, struct screen_list *screen_list)
478{
479    screen_list->requested_delay = atoi(argv);
480    screen_list->delay = atoi(argv);
481    return 0;
482}
483
484char *get_window_manager(struct screen_list *screen_list)
485{
486    debug("Window manager is %d", screen_list->wm_type);
487    switch (screen_list->wm_type)
488    {
489    case WM_FULL:
490        return "full";
491    case WM_CARD:
492        return "card";
493    case WM_VSPLIT:
494        return "vsplit";
495    case WM_HSPLIT:
496        return "hsplit";
497    default:
498        return "invalid window manager";
499    }
500    return NULL;                /* Not reached */
501}
502
503char *get_cube_duration(struct screen_list *screen_list)
504{
505    char *r = malloc(100);
506    sprintf(r, "%f", (float)screen_list->cube.duration / 1000000.0f);
507    return r;
508}
509
510char *get_thumbnails(struct screen_list *screen_list)
511{
512    if (screen_list->modals.mini)
513        return "true";
514    return "false";
515}
516
517char *get_status_bar(struct screen_list *screen_list)
518{
519    if (screen_list->modals.status)
520        return "true";
521    return "false";
522}
523
524char *get_eyecandy(struct screen_list *screen_list)
525{
526    if (screen_list->eyecandy)
527        return "true";
528    return "false";
529}
530
531char *get_border(struct screen_list *screen_list)
532{
533    if (screen_list->border_size)
534        return "true";
535    return "false";
536}
537
538char *get_screensaver_timeout(struct screen_list *screen_list)
539{
540    char *r = malloc(100);
541    sprintf(r, "%f", (float)screen_list->screensaver.timeout / 1000000.0f);
542    return r;
543}
544
545char *get_autolock_timeout(struct screen_list *screen_list)
546{
547    char *r = malloc(100);
548    sprintf(r, "%f", (float)screen_list->lock.autolock_timeout / 1000000.0f);
549    return r;
550}
551
552char *get_lock_on_detach(struct screen_list *screen_list)
553{
554    if (screen_list->lock.lock_on_detach)
555        return "true";
556    else
557        return "false";
558}
559
560char *get_socket_dir(struct screen_list *screen_list)
561{
562    return screen_list->comm.socket_dir;
563}
564
565char *get_delay(struct screen_list *screen_list)
566{
567    char *r = malloc(100);
568    sprintf(r, "%d", screen_list->requested_delay);
569    return r;
570}
Note: See TracBrowser for help on using the repository browser.