comparison src/xrdb.c @ 159:e7abb99c2a38

Initial revision
author Jim Blandy <jimb@redhat.com>
date Sat, 05 Jan 1991 19:03:03 +0000
parents
children 8c615e453683
comparison
equal deleted inserted replaced
158:a4e766535a97 159:e7abb99c2a38
1 /* Deal with the X Resource Manager.
2 Copyright (C) 1990 Free Software Foundation.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 1, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; see the file COPYING. If not, write to
16 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 /* Written by jla, 4/90 */
19
20 #include <X11/Xlib.h>
21 #include <X11/Xatom.h>
22 #include <X11/Xos.h>
23 #include <X11/X.h>
24 #include <X11/Xutil.h>
25 #include <X11/Xresource.h>
26 #include <sys/param.h>
27 #include <pwd.h>
28 #include <sys/stat.h>
29
30 #ifdef emacs
31 #include "config.h"
32 #endif
33
34 extern char *getenv ();
35 extern int getuid ();
36 extern struct passwd *getpwuid ();
37 extern struct passwd *getpwnam ();
38
39 static char *
40 gethomedir (dirname)
41 char *dirname;
42 {
43 int uid;
44 struct passwd *pw;
45 char *ptr;
46
47 if ((ptr = getenv ("HOME")) == NULL)
48 {
49 if ((ptr = getenv ("USER")) != NULL)
50 pw = getpwnam (ptr);
51 else
52 {
53 uid = getuid ();
54 pw = getpwuid (uid);
55 }
56 if (pw)
57 ptr = pw->pw_dir;
58 else
59 {
60 ptr = NULL;
61 *dirname = '\0';
62 }
63 }
64
65 if (ptr != NULL)
66 strcpy (dirname, ptr);
67
68 dirname += strlen (dirname);
69 *dirname = '/';
70 dirname++;
71 *dirname = '\0';
72
73 return dirname;
74 }
75
76 static int
77 file_p (path)
78 char *path;
79 {
80 struct stat status;
81
82 return (access (path, R_OK) == 0 /* exists and is readable */
83 && stat (path, &status) == 0 /* get the status */
84 && (status.st_mode & S_IFDIR) == 0); /* not a directory */
85 }
86
87 #if 0
88 #define X_DEFAULT_SEARCH_PATH "/usr/lib/X11/"
89 #endif
90
91 /* Isn't this just disgusting? */
92
93 #define X_DEFAULT_SEARCH_PATH "/usr/lib/X11/%L/%T/%N%S:/usr/lib/X11/%l/%T/%N%S:/usr/lib/X11/%T/%N%S"
94
95 static int
96 decode_magic (string, file, return_path)
97 char *string, *file, *return_path;
98 {
99 char *p = string;
100 char *t = return_path;
101
102 while (*p)
103 {
104 if (*p == '%')
105 switch (*++p)
106 {
107 case '%':
108 *t++ = '%';
109 p++;
110 break;
111
112 case 'N':
113 case 'T':
114 case 'S':
115 case 'L':
116 case 'l':
117 case 't':
118 case 'c':
119 default:
120 p++;
121 if (*t == '/' && *p == '/')
122 p++;
123 break;
124 }
125 else
126 *t++ = *p++;
127 }
128 *t = '\0';
129 strcat (return_path, file);
130
131 if (file_p (return_path))
132 return 1;
133
134 return_path[0] = '\0';
135 return 0;
136 }
137
138 static int
139 magic_searchpath_decoder (incantation_string, file, return_path)
140 char *incantation_string, *return_path, *file;
141 {
142 register char *s = incantation_string;
143 register char *p;
144 register char string[MAXPATHLEN];
145
146 while (*s)
147 {
148 p = s;
149
150 while (*p && *p != ':')
151 p++;
152
153 if (*p == ':' && *(p + 1) == ':')
154 {
155 bcopy ("%N%S", string, 5);
156 if (decode_magic (string, file, return_path))
157 return 1;
158
159 s = p + 1;
160 continue;
161 }
162
163 if (p > s)
164 {
165 int len = p - s;
166
167 bcopy (s, string, len);
168 string[len + 1] = '\0';
169 if (decode_magic (string, file, return_path))
170 return 1;
171 }
172
173 if (p)
174 s = p + 1;
175 else
176 return 0;
177 }
178
179 return 0;
180 }
181
182 static XrmDatabase
183 get_system_app (class)
184 char *class;
185 {
186 XrmDatabase db;
187 char path[MAXPATHLEN];
188 char *p;
189
190 if ((p = getenv ("XFILESEARCHPATH")) == NULL)
191 p = X_DEFAULT_SEARCH_PATH;
192
193 if (! magic_searchpath_decoder (p, class, path))
194 return NULL;
195
196 db = XrmGetFileDatabase (path);
197 return db;
198 }
199
200 static XrmDatabase
201 get_fallback (display)
202 Display *display;
203 {
204 XrmDatabase db;
205
206 return NULL;
207 }
208
209 static XrmDatabase
210 get_user_app (class)
211 char *class;
212 {
213 XrmDatabase db;
214 char *magic_path;
215 char path[MAXPATHLEN];
216
217 if ((magic_path = getenv ("XUSERFILESEARCHPATH")) == NULL)
218 {
219 char homedir[MAXPATHLEN];
220 char *default_magic;
221 char *p;
222
223 gethomedir (homedir);
224
225 if ((p = getenv ("XAPPLRESDIR")) == NULL)
226 {
227 default_magic = "%s/%%L/%%N:%s/%%l/%%N:%s/%%N";
228 magic_path = (char *) alloca ((3 * strlen (homedir))
229 + strlen (default_magic));
230 sprintf (magic_path, default_magic, homedir, homedir, homedir);
231 }
232 else
233 {
234 default_magic = "%s/%%L/%%N:%s/%%l/%%N:%s/%%N:%s/%%N";
235 magic_path = (char *) alloca ((3 * strlen (p))
236 + strlen (default_magic)
237 + strlen (homedir));
238 sprintf (magic_path, default_magic, p, p, p, homedir);
239 }
240 }
241
242 if (! magic_searchpath_decoder (magic_path, class, path))
243 return NULL;
244
245 db = XrmGetFileDatabase (path);
246 return db;
247 }
248
249 static XrmDatabase
250 get_user_db (display)
251 Display *display;
252 {
253 XrmDatabase db;
254 char *xdefs;
255
256 xdefs = XResourceManagerString (display);
257 if (xdefs != NULL)
258 db = XrmGetStringDatabase (xdefs);
259 else
260 {
261 char xdefault[MAXPATHLEN];
262
263 gethomedir (xdefault);
264 strcat (xdefault, ".Xdefaults");
265 db = XrmGetFileDatabase (xdefault);
266 }
267
268 return db;
269 }
270
271 static XrmDatabase
272 get_environ_db ()
273 {
274 XrmDatabase db;
275 char *p;
276 char path[MAXPATHLEN];
277
278 if ((p = getenv ("XENVIRONMENT")) == NULL)
279 {
280 gethomedir (path);
281 strcat (path, ".Xdefaults-");
282 gethostname (path + strlen (path), MAXPATHLEN - strlen (path));
283 p = path;
284 }
285
286 db = XrmGetFileDatabase (p);
287 return db;
288 }
289
290 /* Types of values that we can find in a database */
291
292 #define XrmStringType "String" /* String representation */
293 XrmRepresentation x_rm_string; /* Quark representation */
294
295 /* Load X resources based on the display and a possible -xrm option. */
296
297 XrmDatabase
298 x_load_resources (display, xrm_string, myclass)
299 Display *display;
300 char *xrm_string, *myclass;
301 {
302 char *xdefs;
303 XrmDatabase rdb;
304 XrmDatabase db;
305
306 x_rm_string = XrmStringToQuark (XrmStringType);
307 XrmInitialize ();
308 rdb = XrmGetStringDatabase ("");
309
310 /* Get application system defaults */
311 db = get_system_app (myclass);
312 if (db != NULL)
313 XrmMergeDatabases (db, &rdb);
314
315 /* Get Fallback resources */
316 db = get_fallback (display);
317 if (db != NULL)
318 XrmMergeDatabases (db, &rdb);
319
320 /* Get application user defaults */
321 db = get_user_app (myclass);
322 if (db != NULL)
323 XrmMergeDatabases (db, &rdb);
324
325 /* get User defaults */
326 db = get_user_db (display);
327 if (db != NULL)
328 XrmMergeDatabases (db, &rdb);
329
330 /* Get Environment defaults. */
331 db = get_environ_db ();
332 if (db != NULL)
333 XrmMergeDatabases (db, &rdb);
334
335 /* Last, merge in any specification from the command line. */
336 if (xrm_string != NULL)
337 {
338 db = XrmGetStringDatabase (xrm_string);
339 if (db != NULL)
340 XrmMergeDatabases (db, &rdb);
341 }
342
343 return rdb;
344 }
345
346 /* Retrieve the value of the resource specified by NAME with class CLASS
347 and of type TYPE from database RDB. The value is returned in RET_VALUE. */
348
349 int
350 x_get_resource (rdb, name, class, expected_type, ret_value)
351 XrmDatabase rdb;
352 char *name, *class;
353 XrmRepresentation expected_type;
354 XrmValue *ret_value;
355 {
356 XrmValue value;
357 XrmName namelist[100];
358 XrmClass classlist[100];
359 XrmRepresentation type;
360
361 XrmStringToNameList(name, namelist);
362 XrmStringToClassList(class, classlist);
363
364 if (XrmQGetResource (rdb, namelist, classlist, &type, &value) == True
365 && (type == expected_type))
366 {
367 if (type == x_rm_string)
368 (char *) ret_value->addr = value.addr;
369 else
370 bcopy (value.addr, ret_value->addr, ret_value->size);
371
372 return value.size;
373 }
374
375 return 0;
376 }
377
378 /* Retrieve the string resource specified by NAME with CLASS from
379 database RDB. */
380
381 char *
382 x_get_string_resource (rdb, name, class)
383 XrmDatabase rdb;
384 char *name, *class;
385 {
386 XrmValue value;
387
388 if (x_get_resource (rdb, name, class, x_rm_string, &value))
389 return (char *) value.addr;
390
391 return (char *) 0;
392 }
393
394 #ifdef TESTRM
395 #include <stdio.h>
396 #include "arg-list.h"
397
398 static void
399 fatal (msg, prog, x1, x2, x3, x4, x5)
400 char *msg, *prog;
401 int x1, x2, x3, x4, x5;
402 {
403 extern int errno;
404
405 if (errno)
406 perror (prog);
407
408 (void) fprintf (stderr, msg, prog, x1, x2, x3, x4, x5);
409 exit (1);
410 }
411
412 main (argc, argv)
413 int argc;
414 char **argv;
415 {
416 Display *display;
417 char *displayname, *resource_string, *class;
418 XrmDatabase xdb;
419 List *arg_list, *lp;
420
421 arg_list = arg_listify (argc, argv);
422
423 lp = member ("-d", arg_list);
424 if (!NIL (lp))
425 displayname = car (cdr (lp));
426 else
427 displayname = "localhost:0.0";
428
429 lp = member ("-xrm", arg_list);
430 if (! NIL (lp))
431 resource_string = car (cdr (lp));
432 else
433 resource_string = (char *) 0;
434
435 lp = member ("-c", arg_list);
436 if (! NIL (lp))
437 class = car (cdr (lp));
438 else
439 class = "Emacs";
440
441 free_arglist (arg_list);
442
443
444
445 if (!(display = XOpenDisplay (displayname)))
446 fatal ("Can't open display '%s'\n", XDisplayName (displayname));
447
448 xdb = x_load_resources (display, resource_string, class);
449
450 #if 0
451 /* In a real program, you'd want to also do this: */
452 display->db = xdb;
453 #endif
454
455 while (1)
456 {
457 char line[90];
458
459 printf ("String: ");
460 gets (line);
461 if (strlen (line))
462 {
463 char *value = x_get_string_resource (xdb, line, class);
464
465 if (value != NULL)
466 printf ("\t%s: %s\n\n", line, value);
467 else
468 printf ("\tNo Value.\n\n");
469 }
470 else
471 break;
472 }
473 printf ("\tExit.\n\n");
474
475 XCloseDisplay (display);
476 }
477 #endif /* TESTRM */