1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
22
23 #ifdef emacs
24 #include <config.h>
25 #endif
26
27 #ifdef HAVE_UNISTD_H
28 #include <unistd.h>
29 #endif
30
31 #include <errno.h>
32 #include <epaths.h>
33
34 #include <stdio.h>
35 #include <setjmp.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 #include <sys/stat.h>
46
47 #if !defined(S_ISDIR) && defined(S_IFDIR)
48 #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
49 #endif
50
51 #include "lisp.h"
52
53 extern char *getenv ();
54
55 56
57 #if 0
58 extern short getuid (); 59 60
61 #endif
62
63 #ifdef DECLARE_GETPWUID_WITH_UID_T
64 extern struct passwd *getpwuid (uid_t);
65 extern struct passwd *getpwnam (const char *);
66 #else
67 extern struct passwd *getpwuid ();
68 extern struct passwd *getpwnam ();
69 #endif
70
71 extern char *get_system_name ();
72
73 74
75 #ifdef emacs
76
77 #undef malloc
78 #undef realloc
79 #undef free
80 #define malloc xmalloc
81 #define realloc xrealloc
82 #define free xfree
83 #endif
84
85 char *x_get_string_resource ();
86 static int file_p ();
87
88
89
90
91
92 93
94 char *x_customization_string;
95
96
97 98 99
100 char *
101 x_get_customization_string (db, name, class)
102 XrmDatabase db;
103 char *name, *class;
104 {
105 char *full_name
106 = (char *) alloca (strlen (name) + sizeof ("customization") + 3);
107 char *full_class
108 = (char *) alloca (strlen (class) + sizeof ("Customization") + 3);
109 char *result;
110
111 sprintf (full_name, "%s.%s", name, "customization");
112 sprintf (full_class, "%s.%s", class, "Customization");
113
114 result = x_get_string_resource (db, full_name, full_class);
115
116 if (result)
117 {
118 char *copy = (char *) malloc (strlen (result) + 1);
119 strcpy (copy, result);
120 return copy;
121 }
122 else
123 return 0;
124 }
125
126
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
156
157 static char *
158 magic_file_p (string, string_len, class, escaped_suffix, suffix)
159 char *string;
160 int string_len;
161 char *class, *escaped_suffix, *suffix;
162 {
163 char *lang = getenv ("LANG");
164
165 int path_size = 100;
166 char *path = (char *) malloc (path_size);
167 int path_len = 0;
168
169 char *p = string;
170
171 while (p < string + string_len)
172 {
173
174 char *next = NULL;
175 int next_len;
176
177 if (*p == '%')
178 {
179 p++;
180
181 if (p >= string + string_len)
182 next_len = 0;
183 else
184 switch (*p)
185 {
186 case '%':
187 next = "%";
188 next_len = 1;
189 break;
190
191 case 'C':
192 next = (x_customization_string
193 ? x_customization_string
194 : "");
195 next_len = strlen (next);
196 break;
197
198 case 'N':
199 next = class;
200 next_len = strlen (class);
201 break;
202
203 case 'T':
204 next = "app-defaults";
205 next_len = strlen (next);
206 break;
207
208 default:
209 case 'S':
210 next_len = 0;
211 break;
212
213 case 'L':
214 case 'l':
215 if (! lang)
216 {
217 free (path);
218 return NULL;
219 }
220
221 next = lang;
222 next_len = strlen (next);
223 break;
224
225 case 't':
226 case 'c':
227 free (path);
228 return NULL;
229 }
230 }
231 else
232 next = p, next_len = 1;
233
234
235 if (path_len + next_len + 1 > path_size)
236 {
237 path_size = (path_len + next_len + 1) * 2;
238 path = (char *) realloc (path, path_size);
239 }
240
241 bcopy (next, path + path_len, next_len);
242 path_len += next_len;
243
244 p++;
245
246
247 if (p >= string + string_len && escaped_suffix)
248 {
249 string = escaped_suffix;
250 string_len = strlen (string);
251 p = string;
252 escaped_suffix = NULL;
253 }
254 }
255
256
257 if (suffix)
258 {
259 int suffix_len = strlen (suffix);
260
261 if (path_len + suffix_len + 1 > path_size)
262 {
263 path_size = (path_len + suffix_len + 1);
264 path = (char *) realloc (path, path_size);
265 }
266
267 bcopy (suffix, path + path_len, suffix_len);
268 path_len += suffix_len;
269 }
270
271 path[path_len] = '\0';
272
273 if (! file_p (path))
274 {
275 free (path);
276 return NULL;
277 }
278
279 return path;
280 }
281
282
283 static char *
284 gethomedir ()
285 {
286 struct passwd *pw;
287 char *ptr;
288 char *copy;
289
290 if ((ptr = getenv ("HOME")) == NULL)
291 {
292 if ((ptr = getenv ("LOGNAME")) != NULL
293 || (ptr = getenv ("USER")) != NULL)
294 pw = getpwnam (ptr);
295 else
296 pw = getpwuid (getuid ());
297
298 if (pw)
299 ptr = pw->pw_dir;
300 }
301
302 if (ptr == NULL)
303 return xstrdup ("/");
304
305 copy = (char *) malloc (strlen (ptr) + 2);
306 strcpy (copy, ptr);
307 strcat (copy, "/");
308
309 return copy;
310 }
311
312
313 static int
314 file_p (filename)
315 char *filename;
316 {
317 struct stat status;
318
319 return (access (filename, 4) == 0
320 && stat (filename, &status) == 0
321 && (S_ISDIR (status.st_mode)) == 0);
322 }
323
324
325 326 327
328
329 static char *
330 search_magic_path (search_path, class, escaped_suffix, suffix)
331 char *search_path, *class, *escaped_suffix, *suffix;
332 {
333 register char *s, *p;
334
335 for (s = search_path; *s; s = p)
336 {
337 for (p = s; *p && *p != ':'; p++)
338 ;
339
340 if (p > s)
341 {
342 char *path = magic_file_p (s, p - s, class, escaped_suffix, suffix);
343 if (path)
344 return path;
345 }
346 else if (*p == ':')
347 {
348 char *path;
349
350 s = "%N%S";
351 path = magic_file_p (s, strlen (s), class, escaped_suffix, suffix);
352 if (path)
353 return path;
354 }
355
356 if (*p == ':')
357 p++;
358 }
359
360 return 0;
361 }
362
363
364
365 static XrmDatabase
366 get_system_app (class)
367 char *class;
368 {
369 XrmDatabase db = NULL;
370 char *path;
371
372 path = getenv ("XFILESEARCHPATH");
373 if (! path) path = PATH_X_DEFAULTS;
374
375 path = search_magic_path (path, class, 0, 0);
376 if (path)
377 {
378 db = XrmGetFileDatabase (path);
379 free (path);
380 }
381
382 return db;
383 }
384
385
386 static XrmDatabase
387 get_fallback (display)
388 Display *display;
389 {
390 return NULL;
391 }
392
393
394 static XrmDatabase
395 get_user_app (class)
396 char *class;
397 {
398 char *path;
399 char *file = 0;
400 char *free_it = 0;
401
402 403
404 if (((path = getenv ("XUSERFILESEARCHPATH"))
405 && (file = search_magic_path (path, class, 0, 0)))
406
407 408
409 || ((path = getenv ("XAPPLRESDIR"))
410 && ((file = search_magic_path (path, class, "/%L/%N", 0))
411 || (file = search_magic_path (path, class, "/%N", 0))))
412
413 414
415 || (free_it = gethomedir (),
416 ((file = search_magic_path (free_it, class, "%L/%N", 0))
417 || (file = search_magic_path (free_it, class, "%N", 0)))))
418 {
419 XrmDatabase db = XrmGetFileDatabase (file);
420 free (file);
421 free (free_it);
422 return db;
423 }
424
425 free (free_it);
426 return NULL;
427 }
428
429
430 static XrmDatabase
431 get_user_db (display)
432 Display *display;
433 {
434 XrmDatabase db;
435 char *xdefs;
436
437 #ifdef PBaseSize
438 xdefs = XResourceManagerString (display);
439 #else
440 xdefs = display->xdefaults;
441 #endif
442
443 if (xdefs != NULL)
444 db = XrmGetStringDatabase (xdefs);
445 else
446 {
447 char *home;
448 char *xdefault;
449
450 home = gethomedir ();
451 xdefault = (char *) malloc (strlen (home) + sizeof (".Xdefaults"));
452 strcpy (xdefault, home);
453 strcat (xdefault, ".Xdefaults");
454 db = XrmGetFileDatabase (xdefault);
455 free (home);
456 free (xdefault);
457 }
458
459 #ifdef HAVE_XSCREENRESOURCESTRING
460
461 xdefs = XScreenResourceString (DefaultScreenOfDisplay (display));
462 if (xdefs != NULL)
463 {
464 XrmMergeDatabases (XrmGetStringDatabase (xdefs), &db);
465 XFree (xdefs);
466 }
467 #endif
468
469 return db;
470 }
471
472 static XrmDatabase
473 get_environ_db ()
474 {
475 XrmDatabase db;
476 char *p;
477 char *path = 0, *home = 0, *host;
478
479 if ((p = getenv ("XENVIRONMENT")) == NULL)
480 {
481 home = gethomedir ();
482 host = get_system_name ();
483 path = (char *) malloc (strlen (home)
484 + sizeof (".Xdefaults-")
485 + strlen (host));
486 sprintf (path, "%s%s%s", home, ".Xdefaults-", host);
487 p = path;
488 }
489
490 db = XrmGetFileDatabase (p);
491
492 free (path);
493 free (home);
494
495 return db;
496 }
497
498
499
500
501
502 #define XrmStringType "String"
503 XrmRepresentation x_rm_string;
504
505
506
507 XrmDatabase
508 x_load_resources (display, xrm_string, myname, myclass)
509 Display *display;
510 char *xrm_string, *myname, *myclass;
511 {
512 XrmDatabase user_database;
513 XrmDatabase rdb;
514 XrmDatabase db;
515 char line[256];
516
517 char *helv = "-*-helvetica-medium-r-*--*-120-*-*-*-*-iso8859-1";
518
519 #ifdef USE_MOTIF
520 char *courier = "-*-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1";
521 extern Lisp_Object Vdouble_click_time;
522 #endif
523
524 x_rm_string = XrmStringToQuark (XrmStringType);
525 #ifndef USE_X_TOOLKIT
526 527
528 XrmInitialize ();
529 #endif
530 rdb = XrmGetStringDatabase ("");
531
532 533
534 #ifdef USE_MOTIF
535
536 sprintf (line, "%s.pane.background: grey75", myclass);
537 XrmPutLineResource (&rdb, line);
538 sprintf (line, "%s*fontList: %s", myclass, helv);
539 XrmPutLineResource (&rdb, line);
540 sprintf (line, "%s*menu*background: grey75", myclass);
541 XrmPutLineResource (&rdb, line);
542 sprintf (line, "%s*menubar*background: grey75", myclass);
543 XrmPutLineResource (&rdb, line);
544 sprintf (line, "%s*verticalScrollBar.background: grey75", myclass);
545 XrmPutLineResource (&rdb, line);
546 sprintf (line, "%s*verticalScrollBar.troughColor: grey75", myclass);
547 XrmPutLineResource (&rdb, line);
548 sprintf (line, "%s.dialog*.background: grey75", myclass);
549 XrmPutLineResource (&rdb, line);
550 sprintf (line, "%s*fsb.Text.background: white", myclass);
551 XrmPutLineResource (&rdb, line);
552 sprintf (line, "%s*fsb.FilterText.background: white", myclass);
553 XrmPutLineResource (&rdb, line);
554 sprintf (line, "%s*fsb*DirList.background: white", myclass);
555 XrmPutLineResource (&rdb, line);
556 sprintf (line, "%s*fsb*ItemsList.background: white", myclass);
557 XrmPutLineResource (&rdb, line);
558 sprintf (line, "%s*fsb*background: grey75", myclass);
559 XrmPutLineResource (&rdb, line);
560 sprintf (line, "%s*fsb.Text.fontList: %s", myclass, courier);
561 XrmPutLineResource (&rdb, line);
562 sprintf (line, "%s*fsb.FilterText.fontList: %s", myclass, courier);
563 XrmPutLineResource (&rdb, line);
564 sprintf (line, "%s*fsb*ItemsList.fontList: %s", myclass, courier);
565 XrmPutLineResource (&rdb, line);
566 sprintf (line, "%s*fsb*DirList.fontList: %s", myclass, courier);
567 XrmPutLineResource (&rdb, line);
568
569 570
571 if (INTEGERP (Vdouble_click_time) && XINT (Vdouble_click_time) > 0)
572 {
573 sprintf (line, "%s*fsb*DirList.doubleClickInterval: %d",
574 myclass, XFASTINT (Vdouble_click_time));
575 XrmPutLineResource (&rdb, line);
576 sprintf (line, "%s*fsb*ItemsList.doubleClickInterval: %d",
577 myclass, XFASTINT (Vdouble_click_time));
578 XrmPutLineResource (&rdb, line);
579 }
580
581 #else
582
583 sprintf (line, "Emacs.dialog*.font: %s", helv);
584 XrmPutLineResource (&rdb, line);
585 sprintf (line, "Emacs.dialog*.background: grey75");
586 XrmPutLineResource (&rdb, line);
587 sprintf (line, "*XlwMenu*font: %s", helv);
588 XrmPutLineResource (&rdb, line);
589 sprintf (line, "*XlwMenu*background: grey75");
590 XrmPutLineResource (&rdb, line);
591 sprintf (line, "Emacs*verticalScrollBar.background: grey75");
592 XrmPutLineResource (&rdb, line);
593
594 #endif
595
596 user_database = get_user_db (display);
597
598 599
600 free (x_customization_string);
601 x_customization_string
602 = x_get_customization_string (user_database, myname, myclass);
603
604
605 db = get_system_app (myclass);
606 if (db != NULL)
607 XrmMergeDatabases (db, &rdb);
608
609
610 db = get_fallback (display);
611 if (db != NULL)
612 XrmMergeDatabases (db, &rdb);
613
614
615 db = get_user_app (myclass);
616 if (db != NULL)
617 XrmMergeDatabases (db, &rdb);
618
619
620 if (user_database != NULL)
621 XrmMergeDatabases (user_database, &rdb);
622
623
624 db = get_environ_db ();
625 if (db != NULL)
626 XrmMergeDatabases (db, &rdb);
627
628
629 if (xrm_string != NULL)
630 {
631 db = XrmGetStringDatabase (xrm_string);
632 if (db != NULL)
633 XrmMergeDatabases (db, &rdb);
634 }
635
636 return rdb;
637 }
638
639
640 641
642
643 int
644 x_get_resource (rdb, name, class, expected_type, ret_value)
645 XrmDatabase rdb;
646 char *name, *class;
647 XrmRepresentation expected_type;
648 XrmValue *ret_value;
649 {
650 XrmValue value;
651 XrmName namelist[100];
652 XrmClass classlist[100];
653 XrmRepresentation type;
654
655 XrmStringToNameList(name, namelist);
656 XrmStringToClassList(class, classlist);
657
658 if (XrmQGetResource (rdb, namelist, classlist, &type, &value) == True
659 && (type == expected_type))
660 {
661 if (type == x_rm_string)
662 ret_value->addr = (char *) value.addr;
663 else
664 bcopy (value.addr, ret_value->addr, ret_value->size);
665
666 return value.size;
667 }
668
669 return 0;
670 }
671
672 673
674
675 char *
676 x_get_string_resource (rdb, name, class)
677 XrmDatabase rdb;
678 char *name, *class;
679 {
680 XrmValue value;
681
682 if (inhibit_x_resources)
683
684 return NULL;
685
686 if (x_get_resource (rdb, name, class, x_rm_string, &value))
687 return (char *) value.addr;
688
689 return (char *) 0;
690 }
691
692
693
694 #ifdef TESTRM
695
696 typedef char **List;
697 #define arg_listify(len, list) (list)
698 #define car(list) (*(list))
699 #define cdr(list) (list + 1)
700 #define NIL(list) (! *(list))
701 #define free_arglist(list)
702
703 static List
704 member (elt, list)
705 char *elt;
706 List list;
707 {
708 List p;
709
710 for (p = list; ! NIL (p); p = cdr (p))
711 if (! strcmp (elt, car (p)))
712 return p;
713
714 return p;
715 }
716
717 static void
718 fatal (msg, prog, x1, x2, x3, x4, x5)
719 char *msg, *prog;
720 int x1, x2, x3, x4, x5;
721 {
722 if (errno)
723 perror (prog);
724
725 (void) fprintf (stderr, msg, prog, x1, x2, x3, x4, x5);
726 exit (1);
727 }
728
729 main (argc, argv)
730 int argc;
731 char **argv;
732 {
733 Display *display;
734 char *displayname, *resource_string, *class, *name;
735 XrmDatabase xdb;
736 List arg_list, lp;
737
738 arg_list = arg_listify (argc, argv);
739
740 lp = member ("-d", arg_list);
741 if (!NIL (lp))
742 displayname = car (cdr (lp));
743 else
744 displayname = "localhost:0.0";
745
746 lp = member ("-xrm", arg_list);
747 if (! NIL (lp))
748 resource_string = car (cdr (lp));
749 else
750 resource_string = (char *) 0;
751
752 lp = member ("-c", arg_list);
753 if (! NIL (lp))
754 class = car (cdr (lp));
755 else
756 class = "Emacs";
757
758 lp = member ("-n", arg_list);
759 if (! NIL (lp))
760 name = car (cdr (lp));
761 else
762 name = "emacs";
763
764 free_arglist (arg_list);
765
766 if (!(display = XOpenDisplay (displayname)))
767 fatal ("Can't open display '%s'\n", XDisplayName (displayname));
768
769 xdb = x_load_resources (display, resource_string, name, class);
770
771
772 display->db = xdb;
773
774 while (1)
775 {
776 char query_name[90];
777 char query_class[90];
778
779 printf ("Name: ");
780 gets (query_name);
781
782 if (strlen (query_name))
783 {
784 char *value;
785
786 printf ("Class: ");
787 gets (query_class);
788
789 value = x_get_string_resource (xdb, query_name, query_class);
790
791 if (value != NULL)
792 printf ("\t%s(%s): %s\n\n", query_name, query_class, value);
793 else
794 printf ("\tNo Value.\n\n");
795 }
796 else
797 break;
798 }
799 printf ("\tExit.\n\n");
800
801 XCloseDisplay (display);
802 }
803 #endif
804
805 806