summaryrefslogtreecommitdiff
path: root/src/xrdb.c
diff options
context:
space:
mode:
authorJim Blandy <jimb@redhat.com>1991-01-05 19:03:03 +0000
committerJim Blandy <jimb@redhat.com>1991-01-05 19:03:03 +0000
commitef2d40100a0fd262819a13ce549e2a3941dc2325 (patch)
tree701706279c4c3bddacff2aadb5a69d4400ceede8 /src/xrdb.c
parentf307a3f0e99d8034c5a118f06f85e1c75b1c0300 (diff)
downloademacs-ef2d40100a0fd262819a13ce549e2a3941dc2325.tar.gz
Initial revision
Diffstat (limited to 'src/xrdb.c')
-rw-r--r--src/xrdb.c477
1 files changed, 477 insertions, 0 deletions
diff --git a/src/xrdb.c b/src/xrdb.c
new file mode 100644
index 00000000000..930b4d54d43
--- /dev/null
+++ b/src/xrdb.c
@@ -0,0 +1,477 @@
+/* Deal with the X Resource Manager.
+ Copyright (C) 1990 Free Software Foundation.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 1, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING. If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* Written by jla, 4/90 */
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <X11/Xos.h>
+#include <X11/X.h>
+#include <X11/Xutil.h>
+#include <X11/Xresource.h>
+#include <sys/param.h>
+#include <pwd.h>
+#include <sys/stat.h>
+
+#ifdef emacs
+#include "config.h"
+#endif
+
+extern char *getenv ();
+extern int getuid ();
+extern struct passwd *getpwuid ();
+extern struct passwd *getpwnam ();
+
+static char *
+gethomedir (dirname)
+ char *dirname;
+{
+ int uid;
+ struct passwd *pw;
+ char *ptr;
+
+ if ((ptr = getenv ("HOME")) == NULL)
+ {
+ if ((ptr = getenv ("USER")) != NULL)
+ pw = getpwnam (ptr);
+ else
+ {
+ uid = getuid ();
+ pw = getpwuid (uid);
+ }
+ if (pw)
+ ptr = pw->pw_dir;
+ else
+ {
+ ptr = NULL;
+ *dirname = '\0';
+ }
+ }
+
+ if (ptr != NULL)
+ strcpy (dirname, ptr);
+
+ dirname += strlen (dirname);
+ *dirname = '/';
+ dirname++;
+ *dirname = '\0';
+
+ return dirname;
+}
+
+static int
+file_p (path)
+ char *path;
+{
+ struct stat status;
+
+ return (access (path, R_OK) == 0 /* exists and is readable */
+ && stat (path, &status) == 0 /* get the status */
+ && (status.st_mode & S_IFDIR) == 0); /* not a directory */
+}
+
+#if 0
+#define X_DEFAULT_SEARCH_PATH "/usr/lib/X11/"
+#endif
+
+/* Isn't this just disgusting? */
+
+#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"
+
+static int
+decode_magic (string, file, return_path)
+ char *string, *file, *return_path;
+{
+ char *p = string;
+ char *t = return_path;
+
+ while (*p)
+ {
+ if (*p == '%')
+ switch (*++p)
+ {
+ case '%':
+ *t++ = '%';
+ p++;
+ break;
+
+ case 'N':
+ case 'T':
+ case 'S':
+ case 'L':
+ case 'l':
+ case 't':
+ case 'c':
+ default:
+ p++;
+ if (*t == '/' && *p == '/')
+ p++;
+ break;
+ }
+ else
+ *t++ = *p++;
+ }
+ *t = '\0';
+ strcat (return_path, file);
+
+ if (file_p (return_path))
+ return 1;
+
+ return_path[0] = '\0';
+ return 0;
+}
+
+static int
+magic_searchpath_decoder (incantation_string, file, return_path)
+ char *incantation_string, *return_path, *file;
+{
+ register char *s = incantation_string;
+ register char *p;
+ register char string[MAXPATHLEN];
+
+ while (*s)
+ {
+ p = s;
+
+ while (*p && *p != ':')
+ p++;
+
+ if (*p == ':' && *(p + 1) == ':')
+ {
+ bcopy ("%N%S", string, 5);
+ if (decode_magic (string, file, return_path))
+ return 1;
+
+ s = p + 1;
+ continue;
+ }
+
+ if (p > s)
+ {
+ int len = p - s;
+
+ bcopy (s, string, len);
+ string[len + 1] = '\0';
+ if (decode_magic (string, file, return_path))
+ return 1;
+ }
+
+ if (p)
+ s = p + 1;
+ else
+ return 0;
+ }
+
+ return 0;
+}
+
+static XrmDatabase
+get_system_app (class)
+ char *class;
+{
+ XrmDatabase db;
+ char path[MAXPATHLEN];
+ char *p;
+
+ if ((p = getenv ("XFILESEARCHPATH")) == NULL)
+ p = X_DEFAULT_SEARCH_PATH;
+
+ if (! magic_searchpath_decoder (p, class, path))
+ return NULL;
+
+ db = XrmGetFileDatabase (path);
+ return db;
+}
+
+static XrmDatabase
+get_fallback (display)
+ Display *display;
+{
+ XrmDatabase db;
+
+ return NULL;
+}
+
+static XrmDatabase
+get_user_app (class)
+ char *class;
+{
+ XrmDatabase db;
+ char *magic_path;
+ char path[MAXPATHLEN];
+
+ if ((magic_path = getenv ("XUSERFILESEARCHPATH")) == NULL)
+ {
+ char homedir[MAXPATHLEN];
+ char *default_magic;
+ char *p;
+
+ gethomedir (homedir);
+
+ if ((p = getenv ("XAPPLRESDIR")) == NULL)
+ {
+ default_magic = "%s/%%L/%%N:%s/%%l/%%N:%s/%%N";
+ magic_path = (char *) alloca ((3 * strlen (homedir))
+ + strlen (default_magic));
+ sprintf (magic_path, default_magic, homedir, homedir, homedir);
+ }
+ else
+ {
+ default_magic = "%s/%%L/%%N:%s/%%l/%%N:%s/%%N:%s/%%N";
+ magic_path = (char *) alloca ((3 * strlen (p))
+ + strlen (default_magic)
+ + strlen (homedir));
+ sprintf (magic_path, default_magic, p, p, p, homedir);
+ }
+ }
+
+ if (! magic_searchpath_decoder (magic_path, class, path))
+ return NULL;
+
+ db = XrmGetFileDatabase (path);
+ return db;
+}
+
+static XrmDatabase
+get_user_db (display)
+ Display *display;
+{
+ XrmDatabase db;
+ char *xdefs;
+
+ xdefs = XResourceManagerString (display);
+ if (xdefs != NULL)
+ db = XrmGetStringDatabase (xdefs);
+ else
+ {
+ char xdefault[MAXPATHLEN];
+
+ gethomedir (xdefault);
+ strcat (xdefault, ".Xdefaults");
+ db = XrmGetFileDatabase (xdefault);
+ }
+
+ return db;
+}
+
+static XrmDatabase
+get_environ_db ()
+{
+ XrmDatabase db;
+ char *p;
+ char path[MAXPATHLEN];
+
+ if ((p = getenv ("XENVIRONMENT")) == NULL)
+ {
+ gethomedir (path);
+ strcat (path, ".Xdefaults-");
+ gethostname (path + strlen (path), MAXPATHLEN - strlen (path));
+ p = path;
+ }
+
+ db = XrmGetFileDatabase (p);
+ return db;
+}
+
+/* Types of values that we can find in a database */
+
+#define XrmStringType "String" /* String representation */
+XrmRepresentation x_rm_string; /* Quark representation */
+
+/* Load X resources based on the display and a possible -xrm option. */
+
+XrmDatabase
+x_load_resources (display, xrm_string, myclass)
+ Display *display;
+ char *xrm_string, *myclass;
+{
+ char *xdefs;
+ XrmDatabase rdb;
+ XrmDatabase db;
+
+ x_rm_string = XrmStringToQuark (XrmStringType);
+ XrmInitialize ();
+ rdb = XrmGetStringDatabase ("");
+
+ /* Get application system defaults */
+ db = get_system_app (myclass);
+ if (db != NULL)
+ XrmMergeDatabases (db, &rdb);
+
+ /* Get Fallback resources */
+ db = get_fallback (display);
+ if (db != NULL)
+ XrmMergeDatabases (db, &rdb);
+
+ /* Get application user defaults */
+ db = get_user_app (myclass);
+ if (db != NULL)
+ XrmMergeDatabases (db, &rdb);
+
+ /* get User defaults */
+ db = get_user_db (display);
+ if (db != NULL)
+ XrmMergeDatabases (db, &rdb);
+
+ /* Get Environment defaults. */
+ db = get_environ_db ();
+ if (db != NULL)
+ XrmMergeDatabases (db, &rdb);
+
+ /* Last, merge in any specification from the command line. */
+ if (xrm_string != NULL)
+ {
+ db = XrmGetStringDatabase (xrm_string);
+ if (db != NULL)
+ XrmMergeDatabases (db, &rdb);
+ }
+
+ return rdb;
+}
+
+/* Retrieve the value of the resource specified by NAME with class CLASS
+ and of type TYPE from database RDB. The value is returned in RET_VALUE. */
+
+int
+x_get_resource (rdb, name, class, expected_type, ret_value)
+ XrmDatabase rdb;
+ char *name, *class;
+ XrmRepresentation expected_type;
+ XrmValue *ret_value;
+{
+ XrmValue value;
+ XrmName namelist[100];
+ XrmClass classlist[100];
+ XrmRepresentation type;
+
+ XrmStringToNameList(name, namelist);
+ XrmStringToClassList(class, classlist);
+
+ if (XrmQGetResource (rdb, namelist, classlist, &type, &value) == True
+ && (type == expected_type))
+ {
+ if (type == x_rm_string)
+ (char *) ret_value->addr = value.addr;
+ else
+ bcopy (value.addr, ret_value->addr, ret_value->size);
+
+ return value.size;
+ }
+
+ return 0;
+}
+
+/* Retrieve the string resource specified by NAME with CLASS from
+ database RDB. */
+
+char *
+x_get_string_resource (rdb, name, class)
+ XrmDatabase rdb;
+ char *name, *class;
+{
+ XrmValue value;
+
+ if (x_get_resource (rdb, name, class, x_rm_string, &value))
+ return (char *) value.addr;
+
+ return (char *) 0;
+}
+
+#ifdef TESTRM
+#include <stdio.h>
+#include "arg-list.h"
+
+static void
+fatal (msg, prog, x1, x2, x3, x4, x5)
+ char *msg, *prog;
+ int x1, x2, x3, x4, x5;
+{
+ extern int errno;
+
+ if (errno)
+ perror (prog);
+
+ (void) fprintf (stderr, msg, prog, x1, x2, x3, x4, x5);
+ exit (1);
+}
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ Display *display;
+ char *displayname, *resource_string, *class;
+ XrmDatabase xdb;
+ List *arg_list, *lp;
+
+ arg_list = arg_listify (argc, argv);
+
+ lp = member ("-d", arg_list);
+ if (!NIL (lp))
+ displayname = car (cdr (lp));
+ else
+ displayname = "localhost:0.0";
+
+ lp = member ("-xrm", arg_list);
+ if (! NIL (lp))
+ resource_string = car (cdr (lp));
+ else
+ resource_string = (char *) 0;
+
+ lp = member ("-c", arg_list);
+ if (! NIL (lp))
+ class = car (cdr (lp));
+ else
+ class = "Emacs";
+
+ free_arglist (arg_list);
+
+
+
+ if (!(display = XOpenDisplay (displayname)))
+ fatal ("Can't open display '%s'\n", XDisplayName (displayname));
+
+ xdb = x_load_resources (display, resource_string, class);
+
+#if 0
+ /* In a real program, you'd want to also do this: */
+ display->db = xdb;
+#endif
+
+ while (1)
+ {
+ char line[90];
+
+ printf ("String: ");
+ gets (line);
+ if (strlen (line))
+ {
+ char *value = x_get_string_resource (xdb, line, class);
+
+ if (value != NULL)
+ printf ("\t%s: %s\n\n", line, value);
+ else
+ printf ("\tNo Value.\n\n");
+ }
+ else
+ break;
+ }
+ printf ("\tExit.\n\n");
+
+ XCloseDisplay (display);
+}
+#endif /* TESTRM */