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

« back to all changes in this revision

Viewing changes to src/command-line.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
#include <stdlib.h>
 
26
#include <pwd.h>
 
27
#include <sys/types.h>
 
28
#include <string.h>
 
29
#include <unistd.h>
 
30
#include <stdio.h>
 
31
#include <ctype.h>
 
32
 
 
33
#include "command-line.h"
 
34
#include "query-assign.h"
 
35
#include "msg.h"
 
36
#include "nvgetopt.h"
 
37
 
 
38
 
 
39
#define TAB    "  "
 
40
#define BIGTAB "      "
 
41
 
 
42
/* local prototypes */
 
43
 
 
44
static void print_assign_help(void);
 
45
static void print_query_help(void);
 
46
static void print_help(void);
 
47
static char *tilde_expansion(char *str);
 
48
static char *nvstrcat(const char *str, ...);
 
49
 
 
50
/*
 
51
 * print_version() - print version information
 
52
 */
 
53
 
 
54
extern const char *pNV_ID;
 
55
 
 
56
static void print_version(void)
 
57
{
 
58
    nv_msg(NULL, "");
 
59
    nv_msg(NULL, pNV_ID);
 
60
    nv_msg(TAB, "The NVIDIA X Server Settings tool.");
 
61
    nv_msg(NULL, "");
 
62
    nv_msg(TAB, "This program is used to configure the "
 
63
            "NVIDIA Linux graphics driver.");
 
64
    nv_msg(NULL, "");
 
65
    nv_msg(TAB, "Copyright (C) 2004 NVIDIA Corporation.");
 
66
    nv_msg(NULL, "");
 
67
    
 
68
} /* print_version() */
 
69
 
 
70
 
 
71
/*
 
72
 * Options table; the fields are:
 
73
 *
 
74
 * name - this is the long option name
 
75
 *
 
76
 * shortname - this is the one character short option name
 
77
 *
 
78
 * flags - bitmask; possible values are NVGETOPT_HAS_ARGUMENT and
 
79
 * NVGETOPT_IS_BOOLEAN
 
80
 *
 
81
 * description - text for use by print_help() to describe the option
 
82
 */
 
83
 
 
84
#define CONFIG_FILE_OPTION 1
 
85
 
 
86
static const NVGetoptOption __options[] = {
 
87
    { "version", 'v', 0, NULL,
 
88
      "Print the nvidia-settings version and exit." },
 
89
    
 
90
    { "help", 'h', 0, NULL,
 
91
      "Print usage information and exit." },
 
92
    
 
93
    { "config", CONFIG_FILE_OPTION, NVGETOPT_HAS_ARGUMENT, NULL,
 
94
      "Use the configuration file [CONFIG] rather than the "
 
95
      "default " DEFAULT_RC_FILE },
 
96
 
 
97
    { "ctrl-display", 'c', NVGETOPT_HAS_ARGUMENT, NULL,
 
98
      "Control the specified X display.  If this option is not given, then "
 
99
      "nvidia-settings will control the display specifed by '--display'.  If "
 
100
      "that is not given, then the $DISPLAY environment variable is used." },
 
101
    
 
102
    { "load-config-only", 'l', 0, NULL,
 
103
      "Load the configuration file, send the values specified therein to "
 
104
      "the X server, and exit.  This mode of operation is useful to place "
 
105
      "in your .xinitrc file, for example." },
 
106
 
 
107
    { "assign", 'a', NVGETOPT_HAS_ARGUMENT, print_assign_help, NULL },
 
108
 
 
109
    { "query", 'q', NVGETOPT_HAS_ARGUMENT, print_query_help, NULL },
 
110
    
 
111
    { NULL,               0, 0, 0                   },
 
112
};
 
113
 
 
114
 
 
115
 
 
116
/*
 
117
 * print_assign_help() - print help information for the assign option.
 
118
 */
 
119
 
 
120
static void print_assign_help(void)
 
121
{
 
122
    nv_msg(BIGTAB, "The ASSIGN argument to the '--assign' commandline option "
 
123
           "is of the form:");
 
124
    
 
125
    nv_msg(NULL, "");
 
126
    
 
127
    nv_msg(BIGTAB TAB, "{DISPLAY}/{attribute name}[{display devices}]"
 
128
           "={value}");
 
129
    
 
130
    nv_msg(NULL, "");
 
131
 
 
132
    nv_msg(BIGTAB, "This assigns the attribute {attribute name} to the value "
 
133
           "{value} on the X Display {DISPLAY}.  {DISPLAY} follows the usual "
 
134
           "{host}:{display}.{screen} syntax of the DISPLAY environment "
 
135
           "variable and is optional; when it is not specified, then it is "
 
136
           "implied following the same rule as the --ctrl-display option.  "
 
137
           "If the X screen is not specified, then the assignment is made to "
 
138
           "all X screens.  Note that the '/' is only required when {DISPLAY} "
 
139
           "is present.  The [{display devices}] portion is also optional; "
 
140
           "if it is not specified, then the attribute is assigned to all "
 
141
           "display devices.  Some examples:");
 
142
    
 
143
    nv_msg(NULL, "");
 
144
    
 
145
    nv_msg(BIGTAB TAB, "-a FSAA=5");
 
146
    nv_msg(BIGTAB TAB, "-a localhost:0.0/DigitalVibrance[CRT-0]=0");
 
147
    nv_msg(BIGTAB TAB, "--assign=\"SyncToVBlank=1\"");
 
148
    
 
149
} /* print_assign_help() */
 
150
 
 
151
 
 
152
 
 
153
/*
 
154
 * print_query_help() - print help information for the query option.
 
155
 */
 
156
 
 
157
static void print_query_help(void)
 
158
{
 
159
    nv_msg(BIGTAB, "The QUERY argument to the '--query' commandline option "
 
160
           "is of the form:");
 
161
 
 
162
    nv_msg(NULL, "");
 
163
 
 
164
    nv_msg(BIGTAB TAB, "{DISPLAY}/{attribute name}[{display devices}]");
 
165
    
 
166
    nv_msg(NULL, "");
 
167
 
 
168
    nv_msg(BIGTAB, "This queries the current value of the attribute "
 
169
           "{attribute name} on the X Display {DISPLAY}.  The format is "
 
170
           "the same as that for the '--assign' option, without "
 
171
           "'={value}'.  Specify '-q all' to query all attributes.");
 
172
 
 
173
} /* print_query_help() */
 
174
 
 
175
 
 
176
 
 
177
/*
 
178
 * print_help() - loop through the __options[] table, and print the
 
179
 * description of each option.
 
180
 */
 
181
 
 
182
void print_help(void)
 
183
{
 
184
    int i, j, len;
 
185
    char *msg, *tmp, scratch[64];
 
186
    const NVGetoptOption *o;
 
187
    
 
188
    print_version();
 
189
 
 
190
    nv_msg(NULL, "");
 
191
    nv_msg(NULL, "nvidia-settings [options]");
 
192
    nv_msg(NULL, "");
 
193
    
 
194
    for (i = 0; __options[i].name; i++) {
 
195
        o = &__options[i];
 
196
        if (isalpha(o->val)) {
 
197
            sprintf(scratch, "%c", o->val);
 
198
            msg = nvstrcat("-", scratch, ", --", o->name, NULL);
 
199
        } else {
 
200
            msg = nvstrcat("--", o->name, NULL);
 
201
        }
 
202
        if (o->flags & NVGETOPT_HAS_ARGUMENT) {
 
203
            len = strlen(o->name);
 
204
            for (j = 0; j < len; j++) scratch[j] = toupper(o->name[j]);
 
205
            scratch[len] = '\0';
 
206
            tmp = nvstrcat(msg, "=[", scratch, "]", NULL);
 
207
            free(msg);
 
208
            msg = tmp;
 
209
        }
 
210
        nv_msg(TAB, msg);
 
211
        if (o->description) nv_msg(BIGTAB, o->description);
 
212
        if (o->print_description) (*(o->print_description))();
 
213
        nv_msg(NULL, "");
 
214
        free(msg);
 
215
    }
 
216
} /* print_help() */
 
217
 
 
218
 
 
219
 
 
220
 
 
221
 
 
222
/*
 
223
 * parse_command_line() - malloc an Options structure, initialize it
 
224
 * with defaults, and fill in any pertinent data from the commandline
 
225
 * arguments.  This must be called after the gui is initialized (so
 
226
 * that the gui can remove its commandline arguments from argv).
 
227
 *
 
228
 * XXX it's unfortunate that we need to init the gui before calling
 
229
 * this, because many of the commandline options will cause us to not
 
230
 * even use the gui.
 
231
 */
 
232
 
 
233
Options *parse_command_line(int argc, char *argv[], char *dpy)
 
234
{
 
235
    Options *op;
 
236
    int n, c;
 
237
    char *strval;
 
238
 
 
239
    op = (Options *) malloc(sizeof (Options));
 
240
    memset(op, 0, sizeof (Options));
 
241
    
 
242
    op->config = DEFAULT_RC_FILE;
 
243
    
 
244
    /*
 
245
     * initialize the controlled display to the gui display name
 
246
     * passed in.
 
247
     */
 
248
    
 
249
    op->ctrl_display = dpy;
 
250
    
 
251
    while (1) {
 
252
        c = nvgetopt(argc, argv, __options, &strval, NULL);
 
253
 
 
254
        if (c == -1)
 
255
            break;
 
256
        
 
257
        switch (c) {
 
258
        case 'v': print_version(); exit(0); break;
 
259
        case 'h': print_help(); exit(0); break;
 
260
        case 'l': op->load = 1; break;
 
261
        case 'c': op->ctrl_display = strval; break;
 
262
        case 'a':
 
263
            n = op->num_assignments;
 
264
            op->assignments = realloc(op->assignments, sizeof(char *) * (n+1));
 
265
            op->assignments[n] = strval;
 
266
            op->num_assignments++;
 
267
            break;
 
268
        case 'q':
 
269
            n = op->num_queries;
 
270
            op->queries = realloc(op->queries, sizeof(char *) * (n+1));
 
271
            op->queries[n] = strval;
 
272
            op->num_queries++;
 
273
            break;
 
274
        case CONFIG_FILE_OPTION: op->config = strval; break;
 
275
        default:
 
276
            nv_error_msg("Invalid commandline, please run `%s --help` "
 
277
                         "for usage information.\n", argv[0]);
 
278
            exit(0);
 
279
        }
 
280
    }
 
281
 
 
282
    /* do tilde expansion on the config file path */
 
283
 
 
284
    op->config = tilde_expansion(op->config);
 
285
    
 
286
    return op;
 
287
 
 
288
} /* parse_command_line() */
 
289
 
 
290
 
 
291
 
 
292
/*
 
293
 * tilde_expansion() - do tilde expansion on the given path name;
 
294
 * based loosely on code snippets found in the comp.unix.programmer
 
295
 * FAQ.  The tilde expansion rule is: if a tilde ('~') is alone or
 
296
 * followed by a '/', then substitute the current user's home
 
297
 * directory; if followed by the name of a user, then substitute that
 
298
 * user's home directory.
 
299
 */
 
300
 
 
301
static char *tilde_expansion(char *str)
 
302
{
 
303
    char *prefix = NULL;
 
304
    char *replace, *user, *ret;
 
305
    struct passwd *pw;
 
306
    int len;
 
307
 
 
308
    if ((!str) || (str[0] != '~')) return str;
 
309
    
 
310
    if ((str[1] == '/') || (str[1] == '\0')) {
 
311
 
 
312
        /* expand to the current user's home directory */
 
313
 
 
314
        prefix = getenv("HOME");
 
315
        if (!prefix) {
 
316
            
 
317
            /* $HOME isn't set; get the home directory from /etc/passwd */
 
318
            
 
319
            pw = getpwuid(getuid());
 
320
            if (pw) prefix = pw->pw_dir;
 
321
        }
 
322
        
 
323
        replace = str + 1;
 
324
        
 
325
    } else {
 
326
    
 
327
        /* expand to the specified user's home directory */
 
328
 
 
329
        replace = strchr(str, '/');
 
330
        if (!replace) replace = str + strlen(str);
 
331
 
 
332
        len = replace - str;
 
333
        user = malloc(len + 1);
 
334
        strncpy(user, str+1, len-1);
 
335
        user[len] = '\0';
 
336
        pw = getpwnam(user);
 
337
        if (pw) prefix = pw->pw_dir;
 
338
        free (user);
 
339
    }
 
340
 
 
341
    if (!prefix) return str;
 
342
    
 
343
    ret = malloc(strlen(prefix) + strlen(replace) + 1);
 
344
    strcpy(ret, prefix);
 
345
    strcat(ret, replace);
 
346
    
 
347
    return ret;
 
348
 
 
349
} /* tilde_expansion() */
 
350
 
 
351
 
 
352
/* XXX useful utility function... where should this go? */
 
353
 
 
354
/*
 
355
 * nvstrcat() - allocate a new string, copying all given strings
 
356
 * into it.  taken from glib
 
357
 */
 
358
 
 
359
static char *nvstrcat(const char *str, ...)
 
360
{
 
361
    unsigned int l;
 
362
    va_list args;
 
363
    char *s;
 
364
    char *concat;
 
365
  
 
366
    l = 1 + strlen(str);
 
367
    va_start(args, str);
 
368
    s = va_arg(args, char *);
 
369
 
 
370
    while (s) {
 
371
        l += strlen(s);
 
372
        s = va_arg(args, char *);
 
373
    }
 
374
    va_end(args);
 
375
  
 
376
    concat = malloc(l);
 
377
    concat[0] = 0;
 
378
  
 
379
    strcat(concat, str);
 
380
    va_start(args, str);
 
381
    s = va_arg(args, char *);
 
382
    while (s) {
 
383
        strcat(concat, s);
 
384
        s = va_arg(args, char *);
 
385
    }
 
386
    va_end(args);
 
387
  
 
388
    return concat;
 
389
 
 
390
} /* nvstrcat() */