diff options
author | Jim Blandy <jimb@redhat.com> | 1991-01-05 19:03:03 +0000 |
---|---|---|
committer | Jim Blandy <jimb@redhat.com> | 1991-01-05 19:03:03 +0000 |
commit | ef2d40100a0fd262819a13ce549e2a3941dc2325 (patch) | |
tree | 701706279c4c3bddacff2aadb5a69d4400ceede8 /src/xrdb.c | |
parent | f307a3f0e99d8034c5a118f06f85e1c75b1c0300 (diff) | |
download | emacs-ef2d40100a0fd262819a13ce549e2a3941dc2325.tar.gz |
Initial revision
Diffstat (limited to 'src/xrdb.c')
-rw-r--r-- | src/xrdb.c | 477 |
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 */ |