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

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