~ubuntu-branches/ubuntu/precise/nvidia-settings/precise-proposed

« back to all changes in this revision

Viewing changes to src/config-file.c

  • Committer: Bazaar Package Importer
  • Author(s): Randall Donald
  • Date: 2004-07-03 19:09:17 UTC
  • Revision ID: james.westby@ubuntu.com-20040703190917-rqkze2s58ux5pamy
Tags: upstream-1.0
ImportĀ upstreamĀ versionĀ 1.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * nvidia-settings: A tool for configuring the NVIDIA X driver on Unix
 
3
 * and Linux systems.
 
4
 *
 
5
 * Copyright (C) 2004 NVIDIA Corporation.
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or
 
8
 * modify it under the terms of Version 2 of the GNU General Public
 
9
 * License as published by the Free Software Foundation.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful, but
 
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See Version 2
 
14
 * of the GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the:
 
18
 *
 
19
 *           Free Software Foundation, Inc.
 
20
 *           59 Temple Place - Suite 330
 
21
 *           Boston, MA 02111-1307, USA
 
22
 *
 
23
 */
 
24
 
 
25
/*
 
26
 * config-file.c - this source file contains functions for processing
 
27
 * the NVIDIA X Server control panel configuration file.
 
28
 *
 
29
 * The configuration file is simply a newline-separated list of
 
30
 * attribute strings, where the syntax of an attribute string is
 
31
 * described in the comments of parse.h
 
32
 *
 
33
 * The pound sign ('#') signifies the beginning of a comment; comments
 
34
 * continue until a newline.
 
35
 */
 
36
 
 
37
 
 
38
#include <unistd.h>
 
39
#include <string.h>
 
40
#include <stdio.h>
 
41
#include <sys/mman.h>
 
42
#include <sys/types.h>
 
43
#include <sys/stat.h>
 
44
#include <fcntl.h>
 
45
#include <errno.h>
 
46
#include <ctype.h>
 
47
#include <stdlib.h>
 
48
#include <time.h>
 
49
 
 
50
#include "NvCtrlAttributes.h"
 
51
 
 
52
#include "config-file.h"
 
53
#include "query-assign.h"
 
54
#include "parse.h"
 
55
#include "msg.h"
 
56
 
 
57
#define MAX_CONFIG_FILE_LINE_LEN 256
 
58
 
 
59
 
 
60
typedef struct {
 
61
    ParsedAttribute a;
 
62
    int line;
 
63
    CtrlHandles *h;
 
64
} ParsedAttributeWrapper;
 
65
 
 
66
 
 
67
static ParsedAttributeWrapper *parse_config_file(char *buf,
 
68
                                                 const char *file,
 
69
                                                 ConfigProperties *);
 
70
 
 
71
static int process_config_file_attributes(const char *file,
 
72
                                          ParsedAttributeWrapper *w,
 
73
                                          const char *display_name);
 
74
 
 
75
static void save_gui_parsed_attributes(ParsedAttributeWrapper *w,
 
76
                                       ParsedAttribute *p);
 
77
 
 
78
static float get_color_value(int attr,
 
79
                             float c[3], float b[3], float g[3]);
 
80
 
 
81
static int parse_config_properties(const char *line, ConfigProperties *conf);
 
82
 
 
83
static void init_config_properties(ConfigProperties *conf);
 
84
 
 
85
static void write_config_properties(FILE *stream, ConfigProperties *conf);
 
86
 
 
87
 
 
88
/*
 
89
 * nv_read_config_file() - read the specified config file, building a
 
90
 * list of attributes to send.  Once all attributes are read, send
 
91
 * them to the X server.
 
92
 *
 
93
 * mmap(2) the file into memory for easier manipulation.
 
94
 *
 
95
 * If an error occurs while parsing the configuration file, an error
 
96
 * message is printed to stderr, NV_FALSE is returned, and nothing is
 
97
 * sent to the X server.
 
98
 *
 
99
 * XXX should we do any sort of versioning to handle compatibility
 
100
 * problems in the future?
 
101
 */
 
102
 
 
103
int nv_read_config_file(const char *file, const char *display_name,
 
104
                        ParsedAttribute *p, ConfigProperties *conf)
 
105
{
 
106
    int fd, ret;
 
107
    struct stat stat_buf;
 
108
    char *buf;
 
109
    ParsedAttributeWrapper *w = NULL;
 
110
    
 
111
    /* initialize the ConfigProperties */
 
112
 
 
113
    init_config_properties(conf);
 
114
 
 
115
    /* open the file */
 
116
 
 
117
    fd = open(file, O_RDONLY);
 
118
    if (fd == -1) {
 
119
        /*
 
120
         * It's OK if the file doesn't exist... but should we print a
 
121
         * warning?
 
122
         */
 
123
        return NV_FALSE;
 
124
    }
 
125
    
 
126
    /* get the size of the file */
 
127
 
 
128
    ret = fstat(fd, &stat_buf);
 
129
    if (ret == -1) {
 
130
        nv_error_msg("Unable to determine size of file '%s' (%s).",
 
131
                     file, strerror(errno));
 
132
        return NV_FALSE;
 
133
    }
 
134
 
 
135
    if (stat_buf.st_size == 0) {
 
136
        nv_warning_msg("File '%s' has zero size; not reading.", file);
 
137
        close(fd);
 
138
        return NV_TRUE;
 
139
    }
 
140
 
 
141
    /* map the file into memory */
 
142
 
 
143
    buf = mmap(0, stat_buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
 
144
    if (buf == (void *) -1) {
 
145
        nv_error_msg("Unable to mmap file '%s' for reading (%s).",
 
146
                     file, strerror(errno));
 
147
        return NV_FALSE;
 
148
    }
 
149
    
 
150
    /* parse the actual text in the file */
 
151
 
 
152
    w = parse_config_file(buf, file, conf);
 
153
 
 
154
    if (munmap (buf, stat_buf.st_size) == -1) {
 
155
        nv_error_msg("Unable to unmap file '%s' after reading (%s).",
 
156
                     file, strerror(errno));
 
157
        return NV_FALSE;
 
158
    }
 
159
 
 
160
    /* close the file */
 
161
 
 
162
    close(fd);
 
163
    
 
164
    if (!w) return NV_FALSE;
 
165
 
 
166
    /* process the parsed attributes */
 
167
 
 
168
    ret = process_config_file_attributes(file, w, display_name);
 
169
 
 
170
    /*
 
171
     * add any relevant parsed attributes back to the list to be
 
172
     * passed to the gui
 
173
     */
 
174
 
 
175
    save_gui_parsed_attributes(w, p);
 
176
    
 
177
    if (w) free(w);
 
178
 
 
179
    return ret;
 
180
    
 
181
} /* nv_read_config_file() */
 
182
 
 
183
 
 
184
 
 
185
/*
 
186
 * nv_write_config_file() - write a configuration file to the
 
187
 * specified filename.
 
188
 *
 
189
 * XXX how should this be handled?  Currently, we just query all
 
190
 * writable attributes, writing their current value to file.
 
191
 *
 
192
 * XXX should query first, and only once we know we can't fail, then
 
193
 * write the file (to avoid deleting the existing file).
 
194
 */
 
195
 
 
196
int nv_write_config_file(const char *filename, CtrlHandles *h,
 
197
                         ParsedAttribute *p, ConfigProperties *conf)
 
198
{
 
199
    int screen, ret, entry, bit, val;
 
200
    FILE *stream;
 
201
    time_t now;
 
202
    AttributeTableEntry *a;
 
203
    ReturnStatus status;
 
204
    NVCTRLAttributeValidValuesRec valid;
 
205
    uint32 mask;
 
206
    char *tmp_d_str, *tmp, *prefix, scratch[4];
 
207
 
 
208
    stream = fopen(filename, "w");
 
209
    if (!stream) {
 
210
        nv_error_msg("Unable to open file '%s' for writing.", filename);
 
211
        return NV_FALSE;
 
212
    }
 
213
    
 
214
    /* write header */
 
215
    
 
216
    now = time(NULL);
 
217
    
 
218
    fprintf(stream, "#\n");
 
219
    fprintf(stream, "# %s\n", filename);
 
220
    fprintf(stream, "#\n");
 
221
    fprintf(stream, "# Configuration file for nvidia-settings - the NVIDIA "
 
222
            "X Server Settings utility\n");
 
223
 
 
224
    /* NOTE: ctime(3) generates a new line */
 
225
    
 
226
    fprintf(stream, "# Generated on %s", ctime(&now));
 
227
    fprintf(stream, "#\n");
 
228
    
 
229
    /* write the values in ConfigProperties */
 
230
 
 
231
    write_config_properties(stream, conf);
 
232
 
 
233
    /* for each screen, query each attribute in the table */
 
234
 
 
235
    fprintf(stream, "\n");
 
236
    fprintf(stream, "# Attributes:\n");
 
237
    fprintf(stream, "\n");
 
238
    
 
239
    for (screen = 0; screen < h->num_screens; screen++) {
 
240
 
 
241
        /* skip it if we don't have a handle for this screen */
 
242
 
 
243
        if (!h->h[screen]) continue;
 
244
 
 
245
        /*
 
246
         * construct the prefix that will be printed in the config
 
247
         * file infront of each attribute on this screen; this will
 
248
         * either be "[screen]" or "[displayname]".
 
249
         */
 
250
 
 
251
        if (conf->booleans &
 
252
            CONFIG_PROPERTIES_INCLUDE_DISPLAY_NAME_IN_CONFIG_FILE) {
 
253
            prefix = h->screen_names[screen];
 
254
        } else {
 
255
            snprintf(scratch, 4, "%d", screen);
 
256
            prefix = scratch;
 
257
        }
 
258
 
 
259
        /* loop over all the entries in the table */
 
260
 
 
261
        for (entry = 0; attributeTable[entry].name; entry++) {
 
262
 
 
263
            a = &attributeTable[entry];
 
264
            
 
265
            /* 
 
266
             * skip all attributes that are not supposed to be written
 
267
             * to the config file
 
268
             */
 
269
 
 
270
            if (a->flags & NV_PARSER_TYPE_NO_CONFIG_WRITE) continue;
 
271
 
 
272
            /*
 
273
             * special case the color attributes because we want to
 
274
             * print floats
 
275
             */
 
276
            
 
277
            if (a->flags & NV_PARSER_TYPE_COLOR_ATTRIBUTE) {
 
278
                float c[3], b[3], g[3];
 
279
                status = NvCtrlGetColorAttributes(h->h[screen], c, b, g);
 
280
                if (status != NvCtrlSuccess) continue;
 
281
                fprintf(stream, "%s%c%s=%f\n",
 
282
                        prefix, DISPLAY_NAME_SEPARATOR, a->name,
 
283
                        get_color_value(a->attr, c, b, g));
 
284
                continue;
 
285
            }
 
286
            
 
287
            for (bit = 0; bit < 24; bit++) {
 
288
                
 
289
                mask = 1 << bit;
 
290
                
 
291
                if ((h->d[screen] & mask) == 0x0) continue;
 
292
 
 
293
                status =
 
294
                    NvCtrlGetValidDisplayAttributeValues(h->h[screen], mask,
 
295
                                                         a->attr, &valid);
 
296
 
 
297
                if (status != NvCtrlSuccess) goto exit_bit_loop;
 
298
                
 
299
                if ((valid.permissions & ATTRIBUTE_TYPE_WRITE) == 0x0)
 
300
                    goto exit_bit_loop;
 
301
                
 
302
                status = NvCtrlGetDisplayAttribute(h->h[screen], mask,
 
303
                                                   a->attr, &val);
 
304
                
 
305
                if (status != NvCtrlSuccess) goto exit_bit_loop;
 
306
                
 
307
                if (valid.permissions & ATTRIBUTE_TYPE_DISPLAY) {
 
308
 
 
309
                    tmp_d_str =
 
310
                        display_device_mask_to_display_device_name(mask);
 
311
 
 
312
                    fprintf(stream, "%s%c%s[%s]=%d\n", prefix,
 
313
                            DISPLAY_NAME_SEPARATOR, a->name, tmp_d_str, val);
 
314
                    
 
315
                    free(tmp_d_str);
 
316
                    
 
317
                    continue;
 
318
                    
 
319
                } else {
 
320
 
 
321
                    fprintf(stream, "%s%c%s=%d\n", prefix,
 
322
                            DISPLAY_NAME_SEPARATOR, a->name, val);
 
323
 
 
324
                    /* fall through to exit_bit_loop */
 
325
                }
 
326
                
 
327
            exit_bit_loop:
 
328
 
 
329
                bit = 25; /* XXX force us out of the display device loop */
 
330
                
 
331
            } /* bit */
 
332
            
 
333
        } /* entry */
 
334
        
 
335
    } /* screen */
 
336
    
 
337
    /*
 
338
     * loop the ParsedAttribute list, writing the attributes to file.
 
339
     * note that we ignore conf->include_display_name_in_config_file
 
340
     * when writing these parsed attributes; this is because parsed
 
341
     * attributes (like the framelock properties) require a display
 
342
     * name be specified (since there are multiple X servers
 
343
     * involved).
 
344
     */
 
345
 
 
346
    while (p) {
 
347
        
 
348
        if (!p->next) {
 
349
            p = p->next;
 
350
            continue;
 
351
        }
 
352
 
 
353
        tmp = nv_get_attribute_name(p->attr);
 
354
        if (!tmp) continue;
 
355
 
 
356
        if (p->display_device_mask) {
 
357
 
 
358
            tmp_d_str = display_device_mask_to_display_device_name
 
359
                (p->display_device_mask);
 
360
                
 
361
            fprintf(stream, "%s%c%s[%s]=%d\n", p->display,
 
362
                    DISPLAY_NAME_SEPARATOR, tmp, tmp_d_str, p->val);
 
363
            
 
364
            free(tmp_d_str);
 
365
            
 
366
        } else {
 
367
                
 
368
            fprintf(stream, "%s%c%s=%d\n", p->display,
 
369
                    DISPLAY_NAME_SEPARATOR, tmp, p->val);
 
370
        }
 
371
        
 
372
        p = p->next;
 
373
    }
 
374
 
 
375
    /* close the configuration file */
 
376
 
 
377
    ret = fclose(stream);
 
378
    if (ret != 0) {
 
379
        nv_error_msg("Failure while closing file '%s'.", filename);
 
380
        return NV_FALSE;
 
381
    }
 
382
    
 
383
    return NV_TRUE;
 
384
    
 
385
} /* nv_write_config_file() */
 
386
 
 
387
 
 
388
 
 
389
/*
 
390
 * parse_config_file() - scan through the buffer; skipping comment
 
391
 * lines.  Non-comment lines with non-whitespace characters are passed
 
392
 * on to nv_parse_attribute_string for parsing.
 
393
 *
 
394
 * If an error occurs, an error message is printed and NULL is
 
395
 * returned.  If successful, a malloced array of
 
396
 * ParsedAttributeWrapper structs is returned.  The last
 
397
 * ParsedAttributeWrapper in the array has line == -1.  It is the
 
398
 * caller's responsibility to free the array.
 
399
 */
 
400
 
 
401
static ParsedAttributeWrapper *parse_config_file(char *buf, const char *file,
 
402
                                                 ConfigProperties *conf)
 
403
{
 
404
    int line, has_data, len, n, ret;
 
405
    char *cur, *c, *comment, tmp[MAX_CONFIG_FILE_LINE_LEN];
 
406
    ParsedAttributeWrapper *w;
 
407
    
 
408
    cur = buf;
 
409
    line = 1;
 
410
    n = 0;
 
411
    w = NULL;
 
412
 
 
413
    while (cur) {
 
414
        c = cur;
 
415
        comment = NULL;
 
416
        has_data = NV_FALSE;;
 
417
        
 
418
        while((*c != '\n') && (*c != '\0') && (*c != EOF)) {
 
419
            if (comment) { c++; continue; }
 
420
            if (*c == '#') { comment = c; continue; }
 
421
            if (!isspace(*c)) has_data = NV_TRUE;
 
422
            c++;
 
423
        }
 
424
 
 
425
        if (has_data) {
 
426
            if (!comment) comment = c;
 
427
            len = comment - cur;
 
428
            if (len >= MAX_CONFIG_FILE_LINE_LEN) {
 
429
                nv_error_msg("Error parsing configuration file '%s' on "
 
430
                             "line %d: line length exceeds maximum "
 
431
                             "length of %d.",
 
432
                             file, line, MAX_CONFIG_FILE_LINE_LEN);
 
433
                goto failed;
 
434
            }
 
435
 
 
436
            strncpy (tmp, cur, len);
 
437
            tmp[len] = '\0';
 
438
 
 
439
            /* first, see if this line is a config property */
 
440
 
 
441
            if (!parse_config_properties(tmp, conf)) {
 
442
                
 
443
                w = realloc(w, sizeof(ParsedAttributeWrapper) * (n+1));
 
444
            
 
445
                ret = nv_parse_attribute_string(tmp,
 
446
                                                NV_PARSER_ASSIGNMENT,
 
447
                                                &w[n].a);
 
448
                if (ret != NV_PARSER_STATUS_SUCCESS) {
 
449
                    nv_error_msg("Error parsing configuration file '%s' on "
 
450
                                 "line %d: '%s' (%s).",
 
451
                                 file, line, tmp, nv_parse_strerror(ret));
 
452
                    goto failed;
 
453
                }
 
454
            
 
455
                w[n].line = line;
 
456
                n++;
 
457
            }
 
458
        }
 
459
 
 
460
        if ((*c == '\0') || (*c == EOF)) cur = NULL;
 
461
        else cur = c + 1;
 
462
        
 
463
        line++;
 
464
    }
 
465
 
 
466
    /* mark the end of the array */
 
467
 
 
468
    w = realloc(w, sizeof(ParsedAttributeWrapper) * (n+1));
 
469
    w[n].line = -1;
 
470
    
 
471
    return w;
 
472
 
 
473
 failed:
 
474
    if (w) free(w);
 
475
    return NULL;
 
476
 
 
477
} /* parse_config_file() */
 
478
 
 
479
 
 
480
 
 
481
 
 
482
/*
 
483
 * process_config_file_attributes() - process the list of
 
484
 * attributes to be assigned that we acquired in parsing the config
 
485
 * file.
 
486
 */
 
487
 
 
488
static int process_config_file_attributes(const char *file,
 
489
                                          ParsedAttributeWrapper *w,
 
490
                                          const char *display_name)
 
491
{
 
492
    int i, j, ret, found, n = 0;
 
493
    CtrlHandles **h = NULL;
 
494
    
 
495
    /*
 
496
     * make sure that all ParsedAttributes have displays (this will do
 
497
     * nothing if we already have a display name
 
498
     */
 
499
 
 
500
    for (i = 0; w[i].line != -1; i++) {
 
501
        nv_assign_default_display(&w[i].a, display_name);
 
502
    }
 
503
    
 
504
    /* build the list of CtrlHandles */
 
505
    
 
506
    for (i = 0; w[i].line != -1; i++) {
 
507
        found = NV_FALSE;
 
508
        for (j = 0; j < n; j++) {
 
509
            if (nv_strcasecmp(h[j]->display, w[i].a.display)) {
 
510
                w[i].h = h[j];
 
511
                found = NV_TRUE;
 
512
                break;
 
513
            }
 
514
        }
 
515
 
 
516
        /*
 
517
         * no handle found for this display, need to create a new
 
518
         * handle.
 
519
         *
 
520
         * XXX we should really just build a list of what ctrl_handles
 
521
         * we need, and what attributes on which ctrl_handles, so that
 
522
         * we don't have to pass NV_CTRL_ATTRIBUTES_ALL_SUBSYSTEMS to
 
523
         * NvCtrlAttributeInit (done in nv_alloc_ctrl_handles())
 
524
         * unless we really need it.
 
525
         */
 
526
 
 
527
        if (!found) {
 
528
            h = realloc(h, sizeof(CtrlHandles *) * (n + 1));
 
529
            h[n] = nv_alloc_ctrl_handles(w[i].a.display);
 
530
            w[i].h = h[n];
 
531
            n++;
 
532
        }
 
533
    }
 
534
    
 
535
    /* now process each attribute, passing in the correct CtrlHandles */
 
536
 
 
537
    for (i = 0; w[i].line != -1; i++) {
 
538
 
 
539
        ret = nv_process_parsed_attribute(&w[i].a, w[i].h, NV_TRUE, NV_FALSE,
 
540
                                          "on line %d of configuration file "
 
541
                                          "'%s'", w[i].line, file);
 
542
        /*
 
543
         * XXX should we fail if processing the attribute failed?  For
 
544
         * now, we'll just keep going through the rest of the config
 
545
         * file.
 
546
         */
 
547
    }
 
548
    
 
549
    /* free all the CtrlHandles we allocated */
 
550
 
 
551
    for (i = 0; i < n; i++) {
 
552
        nv_free_ctrl_handles(h[i]);
 
553
    }
 
554
    
 
555
    if (h) free(h);
 
556
 
 
557
 
 
558
    return NV_TRUE;
 
559
    
 
560
} /* process_config_file_attributes() */
 
561
 
 
562
 
 
563
 
 
564
/*
 
565
 * save_gui_parsed_attributes() - scan through the parsed attribute
 
566
 * wrappers, and save any relevant attributes to the attribute list to
 
567
 * be passed to the gui.
 
568
 */
 
569
 
 
570
static void save_gui_parsed_attributes(ParsedAttributeWrapper *w,
 
571
                                       ParsedAttribute *p)
 
572
{
 
573
    int i;
 
574
 
 
575
    for (i = 0; w[i].line != -1; i++) {
 
576
        if (w[i].a.flags & NV_PARSER_TYPE_GUI_ATTRIUBUTE) {
 
577
            nv_parsed_attribute_add(p, &w[i].a);            
 
578
        }
 
579
    }
 
580
} /* save_gui_parsed_attributes() */
 
581
 
 
582
 
 
583
 
 
584
static float get_color_value(int attr, float c[3], float b[3], float g[3])
 
585
{
 
586
    switch (attr & (ALL_VALUES | ALL_CHANNELS)) {
 
587
    case (CONTRAST_VALUE | RED_CHANNEL):     return c[RED_CHANNEL_INDEX];
 
588
    case (CONTRAST_VALUE | GREEN_CHANNEL):   return c[GREEN_CHANNEL_INDEX];
 
589
    case (CONTRAST_VALUE | BLUE_CHANNEL):    return c[BLUE_CHANNEL_INDEX];
 
590
    case (BRIGHTNESS_VALUE | RED_CHANNEL):   return b[RED_CHANNEL_INDEX];
 
591
    case (BRIGHTNESS_VALUE | GREEN_CHANNEL): return b[GREEN_CHANNEL_INDEX];
 
592
    case (BRIGHTNESS_VALUE | BLUE_CHANNEL):  return b[BLUE_CHANNEL_INDEX];
 
593
    case (GAMMA_VALUE | RED_CHANNEL):        return g[RED_CHANNEL_INDEX];
 
594
    case (GAMMA_VALUE | GREEN_CHANNEL):      return g[GREEN_CHANNEL_INDEX];
 
595
    case (GAMMA_VALUE | BLUE_CHANNEL):       return g[BLUE_CHANNEL_INDEX];
 
596
    default:                                 return 0.0;
 
597
    }
 
598
} /* get_color_value() */
 
599
 
 
600
 
 
601
 
 
602
 
 
603
/*
 
604
 * Table of ConfigProperties (properties of the nvidia-settings
 
605
 * utilities itself, rather than properties of the X screen(s) that
 
606
 * nvidia-settings is configuring).  The table just binds string names
 
607
 * to the bitmask constants.
 
608
 */
 
609
 
 
610
typedef struct {
 
611
    char *name;
 
612
    unsigned int flag;
 
613
} ConfigPropertiesTableEntry;
 
614
 
 
615
ConfigPropertiesTableEntry configPropertyTable[] = {
 
616
    { "ToolTips", CONFIG_PROPERTIES_TOOLTIPS },
 
617
    { "DisplayStatusBar", CONFIG_PROPERTIES_DISPLAY_STATUS_BAR },
 
618
    { "SliderTextEntries", CONFIG_PROPERTIES_SLIDER_TEXT_ENTRIES },
 
619
    { "IncludeDisplayNameInConfigFile",
 
620
      CONFIG_PROPERTIES_INCLUDE_DISPLAY_NAME_IN_CONFIG_FILE },
 
621
    { NULL, 0 }
 
622
};
 
623
    
 
624
 
 
625
    
 
626
/*
 
627
 * parse_config_property() - special case the config properties; if
 
628
 * the given line sets a config property, update conf as appropriate
 
629
 * and return NV_TRUE.  If the given line does not describe a config
 
630
 * property, return NV_FALSE.
 
631
 */
 
632
 
 
633
static int parse_config_properties(const char *line, ConfigProperties *conf)
 
634
{
 
635
    char *no_spaces, *s;
 
636
    ConfigPropertiesTableEntry *t;
 
637
    int ret = NV_FALSE;
 
638
    unsigned int flag;
 
639
    
 
640
    no_spaces = remove_spaces(line);
 
641
 
 
642
    if (!no_spaces) goto done;
 
643
 
 
644
    s = strchr(no_spaces, '=');
 
645
 
 
646
    if (!s) goto done;
 
647
 
 
648
    *s = '\0';
 
649
    
 
650
    for (t = configPropertyTable, flag = 0; t->name; t++) {
 
651
        if (nv_strcasecmp(no_spaces, t->name)) {
 
652
            flag = t->flag;
 
653
            break;
 
654
        }
 
655
    }
 
656
 
 
657
    if (!flag) goto done;
 
658
 
 
659
    s++;
 
660
 
 
661
    if (nv_strcasecmp(s, "yes")) {
 
662
        conf->booleans |= flag;
 
663
    } else if (nv_strcasecmp(s, "no")) {
 
664
        conf->booleans &= ~flag;
 
665
    } else {
 
666
        goto done;
 
667
    }
 
668
    
 
669
    ret = NV_TRUE;
 
670
 
 
671
 done:
 
672
 
 
673
    if (no_spaces) free(no_spaces);
 
674
    return ret;
 
675
    
 
676
} /* parse_config_property() */
 
677
 
 
678
 
 
679
 
 
680
/*
 
681
 * write_config_properties() - write the ConfigProperties to file;
 
682
 * this just amounts to looping through the table, and printing if
 
683
 * each property is enabled or disabled.
 
684
 */
 
685
 
 
686
static void write_config_properties(FILE *stream, ConfigProperties *conf)
 
687
{
 
688
    ConfigPropertiesTableEntry *t;
 
689
 
 
690
    fprintf(stream, "\n");
 
691
    fprintf(stream, "# ConfigProperties:\n");
 
692
    fprintf(stream, "\n");
 
693
 
 
694
    for (t = configPropertyTable; t->name; t++) {
 
695
        fprintf(stream, "%s = %s\n", t->name,
 
696
                (t->flag & conf->booleans) ? "Yes" : "No");
 
697
    }
 
698
} /* write_config_properties()*/
 
699
 
 
700
 
 
701
 
 
702
/*
 
703
 * init_config_properties() - initialize the ConfigProperties
 
704
 * structure.
 
705
 */
 
706
 
 
707
static void init_config_properties(ConfigProperties *conf)
 
708
{
 
709
    memset(conf, 0, sizeof(ConfigProperties));
 
710
 
 
711
    conf->booleans = 
 
712
        (CONFIG_PROPERTIES_TOOLTIPS |
 
713
         CONFIG_PROPERTIES_DISPLAY_STATUS_BAR |
 
714
         CONFIG_PROPERTIES_SLIDER_TEXT_ENTRIES);
 
715
 
 
716
} /* init_config_properties() */