This source file includes following definitions.
- x_get_customization_string
- magic_db
- search_magic_path
- get_system_app
- get_fallback
- get_user_app
- get_user_db
- get_environ_db
- x_load_resources
- x_get_resource
- x_get_string_resource
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #include <config.h>
24
25 #include <unistd.h>
26 #include <errno.h>
27 #include <epaths.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30
31 #include "lisp.h"
32
33
34
35 #include "xterm.h"
36
37 #include <X11/Xlib.h>
38 #include <X11/Xatom.h>
39 #include <X11/X.h>
40 #include <X11/Xutil.h>
41 #include <X11/Xresource.h>
42 #ifdef HAVE_PWD_H
43 #include <pwd.h>
44 #endif
45
46
47
48
49
50
51 static char *x_customization_string;
52
53
54
55
56
57 static char *
58 x_get_customization_string (XrmDatabase db, const char *name,
59 const char *class)
60 {
61 char *full_name = alloca (strlen (name) + sizeof "customization" + 3);
62 char *full_class = alloca (strlen (class) + sizeof "Customization" + 3);
63 const char *result;
64
65 sprintf (full_name, "%s.%s", name, "customization");
66 sprintf (full_class, "%s.%s", class, "Customization");
67
68 result = x_get_string_resource (&db, full_name, full_class);
69 return result ? xstrdup (result) : NULL;
70 }
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101 static XrmDatabase
102 magic_db (const char *string, ptrdiff_t string_len, const char *class,
103 const char *escaped_suffix)
104 {
105 XrmDatabase db;
106 char *lang = getenv ("LANG");
107
108 ptrdiff_t path_size = 100;
109 char *path = xmalloc (path_size);
110 ptrdiff_t path_len = 0;
111
112 const char *p = string;
113
114 while (p < string + string_len)
115 {
116
117 const char *next = p;
118 ptrdiff_t next_len = 1;
119
120 if (*p == '%')
121 {
122 p++;
123
124 if (p >= string + string_len)
125 next_len = 0;
126 else
127 switch (*p)
128 {
129 case '%':
130 next = "%";
131 next_len = 1;
132 break;
133
134 case 'C':
135 if (x_customization_string)
136 {
137 next = x_customization_string;
138 next_len = strlen (next);
139 }
140 else
141 next_len = 0;
142 break;
143
144 case 'N':
145 next = class;
146 next_len = strlen (class);
147 break;
148
149 case 'T':
150 next = "app-defaults";
151 next_len = strlen (next);
152 break;
153
154 default:
155 case 'S':
156 next_len = 0;
157 break;
158
159 case 'L':
160 case 'l':
161 if (! lang)
162 {
163 xfree (path);
164 return NULL;
165 }
166
167 next = lang;
168 next_len = strlen (next);
169 break;
170
171 case 't':
172 case 'c':
173 xfree (path);
174 return NULL;
175 }
176 }
177
178
179 if (path_size - path_len <= next_len)
180 path = xpalloc (path, &path_size, path_len - path_size + next_len + 1,
181 -1, sizeof *path);
182
183 memcpy (path + path_len, next, next_len);
184 path_len += next_len;
185
186 p++;
187
188
189 if (p >= string + string_len && escaped_suffix)
190 {
191 string = escaped_suffix;
192 string_len = strlen (string);
193 p = string;
194 escaped_suffix = NULL;
195 }
196 }
197
198 path[path_len] = '\0';
199 db = XrmGetFileDatabase (path);
200 xfree (path);
201 return db;
202 }
203
204
205
206
207
208
209 static XrmDatabase
210 search_magic_path (const char *search_path, const char *class,
211 const char *escaped_suffix)
212 {
213 const char *s, *p;
214
215 for (s = search_path; *s; s = p)
216 {
217 for (p = s; *p && *p != ':'; p++)
218 ;
219
220 if (p > s)
221 {
222 XrmDatabase db = magic_db (s, p - s, class, escaped_suffix);
223 if (db)
224 return db;
225 }
226 else if (*p == ':')
227 {
228 static char const ns[] = "%N%S";
229 XrmDatabase db = magic_db (ns, strlen (ns), class, escaped_suffix);
230 if (db)
231 return db;
232 }
233
234 if (*p == ':')
235 p++;
236 }
237
238 return 0;
239 }
240
241
242
243 static XrmDatabase
244 get_system_app (const char *class)
245 {
246 const char *path;
247
248 path = getenv ("XFILESEARCHPATH");
249 if (! path) path = PATH_X_DEFAULTS;
250
251 return search_magic_path (path, class, 0);
252 }
253
254
255 static XrmDatabase
256 get_fallback (Display *display)
257 {
258 return NULL;
259 }
260
261
262 static XrmDatabase
263 get_user_app (const char *class)
264 {
265 XrmDatabase db = 0;
266 const char *path;
267
268
269
270 path = getenv ("XUSERFILESEARCHPATH");
271 if (path)
272 db = search_magic_path (path, class, 0);
273
274 if (! db)
275 {
276
277
278 path = getenv ("XAPPLRESDIR");
279 if (path)
280 {
281 db = search_magic_path (path, class, "/%L/%N");
282 if (!db)
283 db = search_magic_path (path, class, "/%N");
284 }
285 }
286
287 if (! db)
288 {
289
290
291 char const *home = get_homedir ();
292 db = search_magic_path (home, class, "/%L/%N");
293 if (! db)
294 db = search_magic_path (home, class, "/%N");
295 }
296
297 return db;
298 }
299
300 static char const xdefaults[] = ".Xdefaults";
301
302 static XrmDatabase
303 get_user_db (Display *display)
304 {
305 XrmDatabase db;
306 char *xdefs;
307
308 #ifdef PBaseSize
309 xdefs = XResourceManagerString (display);
310 #else
311 xdefs = display->xdefaults;
312 #endif
313
314 if (xdefs != NULL)
315 db = XrmGetStringDatabase (xdefs);
316 else
317 {
318
319 char const *home = get_homedir ();
320 char *filename = xmalloc (strlen (home) + 1 + sizeof xdefaults);
321 splice_dir_file (filename, home, xdefaults);
322 db = XrmGetFileDatabase (filename);
323 xfree (filename);
324 }
325
326 #ifdef HAVE_XSCREENRESOURCESTRING
327
328 xdefs = XScreenResourceString (DefaultScreenOfDisplay (display));
329 if (xdefs != NULL)
330 {
331 XrmMergeDatabases (XrmGetStringDatabase (xdefs), &db);
332 XFree (xdefs);
333 }
334 #endif
335
336 return db;
337 }
338
339 static XrmDatabase
340 get_environ_db (void)
341 {
342 XrmDatabase db;
343 char *p = getenv ("XENVIRONMENT");
344 char *filename = 0;
345
346 if (!p)
347 {
348 Lisp_Object system_name = Fsystem_name ();
349 if (STRINGP (system_name))
350 {
351
352 char const *home = get_homedir ();
353 p = filename = xmalloc (strlen (home) + 1 + sizeof xdefaults
354 + 1 + SBYTES (system_name));
355 char *e = splice_dir_file (p, home, xdefaults);
356 *e++ = '-';
357 lispstpcpy (e, system_name);
358 }
359 }
360
361 db = XrmGetFileDatabase (p);
362
363 xfree (filename);
364
365 return db;
366 }
367
368
369
370
371
372 #define XrmStringType "String"
373 static XrmRepresentation x_rm_string;
374
375
376
377 XrmDatabase
378 x_load_resources (Display *display, const char *xrm_string,
379 const char *myname, const char *myclass)
380 {
381 XrmDatabase user_database;
382 XrmDatabase rdb;
383 XrmDatabase db;
384 char line[256];
385
386 x_rm_string = XrmStringToQuark (XrmStringType);
387 #ifndef USE_X_TOOLKIT
388
389
390 XrmInitialize ();
391 #endif
392 rdb = XrmGetStringDatabase ("");
393
394 #ifdef USE_MOTIF
395
396
397 if (FIXNUMP (Vdouble_click_time) && XFIXNUM (Vdouble_click_time) > 0)
398 {
399 sprintf (line, "%s*fsb*DirList.doubleClickInterval: %"pI"d",
400 myclass, XFIXNAT (Vdouble_click_time));
401 XrmPutLineResource (&rdb, line);
402 sprintf (line, "%s*fsb*ItemsList.doubleClickInterval: %"pI"d",
403 myclass, XFIXNAT (Vdouble_click_time));
404 XrmPutLineResource (&rdb, line);
405 }
406 #else
407
408
409 sprintf (line, "Emacs.dialog*.background: grey75");
410 XrmPutLineResource (&rdb, line);
411 #if !(defined USE_CAIRO || defined HAVE_XFT) || !defined (USE_LUCID)
412 sprintf (line, "Emacs.dialog*.font: %s",
413 "-*-helvetica-medium-r-*--*-120-*-*-*-*-iso8859-1");
414 XrmPutLineResource (&rdb, line);
415 sprintf (line, "*XlwMenu*font: %s",
416 "-*-helvetica-medium-r-*--*-120-*-*-*-*-iso8859-1");
417 XrmPutLineResource (&rdb, line);
418 #endif
419 sprintf (line, "*XlwMenu*background: grey75");
420 XrmPutLineResource (&rdb, line);
421 sprintf (line, "Emacs*verticalScrollBar.background: grey75");
422 XrmPutLineResource (&rdb, line);
423 sprintf (line, "Emacs*horizontalScrollBar.background: grey75");
424 XrmPutLineResource (&rdb, line);
425 #endif
426
427 user_database = get_user_db (display);
428
429
430
431 xfree (x_customization_string);
432 x_customization_string
433 = x_get_customization_string (user_database, myname, myclass);
434
435
436 db = get_system_app (myclass);
437 if (db != NULL)
438 XrmMergeDatabases (db, &rdb);
439
440
441 db = get_fallback (display);
442 if (db != NULL)
443 XrmMergeDatabases (db, &rdb);
444
445
446 db = get_user_app (myclass);
447 if (db != NULL)
448 XrmMergeDatabases (db, &rdb);
449
450
451 if (user_database != NULL)
452 XrmMergeDatabases (user_database, &rdb);
453
454
455 db = get_environ_db ();
456 if (db != NULL)
457 XrmMergeDatabases (db, &rdb);
458
459
460 if (xrm_string != NULL)
461 {
462 db = XrmGetStringDatabase (xrm_string);
463 if (db != NULL)
464 XrmMergeDatabases (db, &rdb);
465 }
466
467 return rdb;
468 }
469
470
471
472
473
474 static int
475 x_get_resource (XrmDatabase rdb, const char *name, const char *class,
476 XrmRepresentation expected_type, XrmValue *ret_value)
477 {
478 XrmValue value;
479 XrmName namelist[100];
480 XrmClass classlist[100];
481 XrmRepresentation type;
482
483 XrmStringToNameList (name, namelist);
484 XrmStringToClassList (class, classlist);
485
486 if (XrmQGetResource (rdb, namelist, classlist, &type, &value) == True
487 && (type == expected_type))
488 {
489 *ret_value = value;
490 return value.size;
491 }
492
493 return 0;
494 }
495
496
497
498
499 const char *
500 x_get_string_resource (void *v_rdb, const char *name, const char *class)
501 {
502 XrmDatabase *rdb = v_rdb;
503 XrmValue value;
504
505 if (inhibit_x_resources)
506
507 return NULL;
508
509 if (x_get_resource (*rdb, name, class, x_rm_string, &value))
510 return (const char *) value.addr;
511
512 return NULL;
513 }