#include "rxvt.h" /* NECESSARY */
#include "version.h"
+#include <sys/utsname.h>
+
#ifdef KEYSYM_RESOURCE
#include "keyboard.h"
#endif
/* #define DEBUG_RESOURCES */
-static const char *const xnames[2] = { ".Xdefaults", ".Xresources" };
-
/*{{{ monolithic option/resource structure: */
/*
* `string' options MUST have a usage argument
(optList[i].flag & Opt_Boolean)
#define optList_isReverse(i) \
(optList[i].flag & Opt_Reverse)
-#define optList_size() \
+#define optList_size \
(sizeof (optList) / sizeof (optList[0]))
static const struct
BOOL (Rs_secondaryScreen, "secondaryScreen", "ssc", Opt_secondaryScreen, "enable secondary screen"),
BOOL (Rs_secondaryScroll, "secondaryScroll", "ssr", Opt_secondaryScroll, "enable secondary screen scroll"),
#endif
+#if 0 && TODO
#if !defined(NO_RESOURCES) && defined(USE_XGETDEFAULT)
INFO ("xrm", "string", "X resource"),
#endif
+#endif
INFO ("e", "command arg ...", "command to execute")
};
case 0: /* brief listing */
rxvt_log (" [-help] [--help]\n");
- for (col = 1, i = 0; i < optList_size (); i++)
+ for (col = 1, i = 0; i < optList_size; i++)
if (optList[i].desc != NULL)
{
int len = 0;
case 1: /* full command-line listing */
rxvt_log (" [options] [-e command args]\n\nwhere options include:\n");
- for (i = 0; i < optList_size (); i++)
+ for (i = 0; i < optList_size; i++)
if (optList[i].desc != NULL)
{
#ifdef DEBUG_STRICT
rxvt_log (" [options] [-e command args]\n\n"
"where resources (long-options) include:\n");
- for (i = 0; i < optList_size (); i++)
+ for (i = 0; i < optList_size; i++)
if (optList[i].kw != NULL)
rxvt_log (" %s: %*s%s\n",
optList[i].kw,
for (i = 1; i < argc; i++)
{
- unsigned int entry, longopt = 0;
- const char *flag, *opt;
+ unsigned int entry, longopt = 0;
+ const char *flag, *opt;
opt = argv[i];
#ifdef DEBUG_RESOURCES
rxvt_usage (0);
/* feature: always try to match long-options */
- for (entry = 0; entry < optList_size (); entry++)
+ for (entry = 0; entry < optList_size; entry++)
if ((optList[entry].kw && !strcmp (opt, optList[entry].kw))
|| (!longopt
&& optList[entry].opt && !strcmp (opt, optList[entry].opt)))
break;
- if (entry < optList_size ())
+ if (entry < optList_size)
{
if (optList_isReverse (entry))
flag = flag == On ? Off : On;
optList[entry].opt, optList[entry].kw, flag);
#endif
if (flag == On)
- options |= (optList[entry].flag);
+ options |= optList[entry].flag;
else
- options &= ~ (optList[entry].flag);
+ options &= ~optList[entry].flag;
if (optList[entry].doff != -1)
rs[optList[entry].doff] = flag;
len = strlen (name);
while ((str = fgets (buffer, sizeof (buffer), stream)) != NULL)
{
- unsigned int entry, n;
+ unsigned int entry, n;
while (*str && isspace (*str))
str++; /* leading whitespace */
# ifdef KEYSYM_RESOURCE
if (!parse_keysym (str, NULL))
# endif /* KEYSYM_RESOURCE */
- for (entry = 0; entry < optList_size (); entry++)
+ for (entry = 0; entry < optList_size; entry++)
{
const char *kw = optList[entry].kw;
str += n + 1;
rxvt_Str_trim (str);
n = strlen (str);
+
if (n && rs[optList[entry].doff] == NULL)
{
/* not already set */
if (optList_isBool (entry))
{
- s = strcasecmp (str, "TRUE") == 0
- || strcasecmp (str, "YES") == 0
- || strcasecmp (str, "ON") == 0
- || strcasecmp (str, "1") == 0;
+ s = strcasecmp (str, "true") == 0
+ || strcasecmp (str, "yes") == 0
+ || strcasecmp (str, "on") == 0
+ || strcmp (str, "1") == 0;
if (optList_isReverse (entry))
s = !s;
*/
/* ARGSUSED */
void
-rxvt_term::extract_resources (Display *display __attribute__ ((unused)), const char *name)
+rxvt_term::extract_resources ()
{
+ dDisp;
+
#ifndef NO_RESOURCES
+ char *homedir = (char *)getenv ("HOME");
+ char fname[1024];
+
# if defined XAPPLOADDIR
# if defined(HAVE_XSETLOCALE) || defined(HAVE_SETLOCALE)
/* Compute the path of the possibly available localized Rxvt file */
- char *localepath = NULL;
-
- if (locale != NULL)
- { /* XXX: must limit length of string */
- localepath = (char *)rxvt_malloc (256);
- sprintf (localepath, XAPPLOADDIRLOCALE "/" RESCLASS,
- (int) (258 - sizeof (XAPPLOADDIRLOCALE) - sizeof (RESCLASS)),
- locale); /* 258 = 255 + 4 (-.*s) - 1 (/) */
- }
+ char localepath[1024];
- {
+ if (locale)
+ snprintf (localepath, sizeof (localepath), XAPPLOADDIRLOCALE "/" RESCLASS, locale);
+ else
+ localepath[0] = 0;
# endif
# endif
# ifdef USE_XGETDEFAULT
- /*
- * get resources using the X library function
- */
- int entry;
+ /*
+ * get resources using the X library function
+ */
+ int entry;
# ifdef XrmEnumOneLevel
- int i;
- char *displayResource, *xe;
- XrmName name_prefix[3];
- XrmClass class_prefix[3];
- XrmDatabase database, rdb1;
- char fname[1024];
+ int i;
+ char *displayResource, *xe;
+ XrmName name_prefix[3];
+ XrmClass class_prefix[3];
+ XrmDatabase database, rdb1;
- XrmInitialize ();
- database = NULL;
+ XrmInitialize ();
+ database = NULL;
- /* Get any Xserver defaults */
+ // for ordering, see for example http://www.faqs.org/faqs/Xt-FAQ/ Subject: 20
- displayResource = XResourceManagerString (display);
- if (displayResource != NULL)
- database = XrmGetStringDatabase (displayResource);
+ // 6. System wide per application default file.
+ /* Add in Rxvt file */
+# if defined(HAVE_XSETLOCALE) || defined(HAVE_SETLOCALE)
+ if (*localepath
+ && ((rdb1 = XrmGetFileDatabase (localepath))
+ || (rdb1 = XrmGetFileDatabase (XAPPLOADDIR "/" RESCLASS))))
+# endif
+ XrmMergeDatabases (rdb1, &database);
-# ifdef HAVE_EXTRA_XRESOURCE_FILES
- /* Add in ~/.Xdefaults or ~/.Xresources */
+ /* Add in $XAPPLRESDIR/Rxvt only; not bothering with XUSERFILESEARCHPATH */
+ if ((xe = (char *)getenv ("XAPPLRESDIR")))
{
- char *ptr;
+ snprintf (fname, sizeof (fname), "%s/%s", xe, RESCLASS);
- if ((ptr = (char *)getenv ("HOME")) == NULL)
- ptr = ".";
+ if ((rdb1 = XrmGetFileDatabase (fname)))
+ XrmMergeDatabases (rdb1, &database);
+ }
- for (i = 0; i < (sizeof (xnames) / sizeof (xnames[0])); i++)
- {
- sprintf (fname, "%-.*s/%s", sizeof (fname) - strlen (xnames[i]) - 2,
- ptr, xnames[i]);
- if ((rdb1 = XrmGetFileDatabase (fname)))
- {
- XrmMergeDatabases (rdb1, &database);
-# ifndef HAVE_BOTH_XRESOURCE_FILES
- break;
-# endif
- }
- }
+ // 5. User's per application default file.
+ // none
+
+ // 4. User's defaults file.
+ /* Get any Xserver defaults */
+ displayResource = XResourceManagerString (disp);
+ if (displayResource != NULL)
+ {
+ if ((rdb1 = XrmGetStringDatabase (displayResource)))
+ XrmMergeDatabases (rdb1, &database);
}
-# endif
+ else if (homedir)
+ {
+ snprintf (fname, sizeof (fname), "%s/.Xdefaults", homedir);
- /* Add in XENVIRONMENT file */
+ if ((rdb1 = XrmGetFileDatabase (fname)))
+ XrmMergeDatabases (rdb1, &database);
+ }
- if ((xe = (char *)getenv ("XENVIRONMENT")) != NULL
- && (rdb1 = XrmGetFileDatabase (xe)) != NULL)
- XrmMergeDatabases (rdb1, &database);
+ /* Get screen specific resources */
+ displayResource = XScreenResourceString (ScreenOfDisplay (disp, display->screen));
+ if (displayResource != NULL)
+ {
+ if ((rdb1 = XrmGetStringDatabase (displayResource)))
+ /* Merge with screen-independent resources */
+ XrmMergeDatabases (rdb1, &database);
- /* Add in Rxvt file */
-# if defined(HAVE_XSETLOCALE) || defined(HAVE_SETLOCALE)
- if (localepath == NULL || (rdb1 = XrmGetFileDatabase (localepath)) == NULL)
-# endif
- rdb1 = XrmGetFileDatabase (XAPPLOADDIR "/" RESCLASS);
+ XFree (displayResource);
+ }
- if (rdb1 != NULL)
- XrmMergeDatabases (rdb1, &database);
+ // 3. User's per host defaults file
+ /* Add in XENVIRONMENT file */
+ if ((xe = (char *)getenv ("XENVIRONMENT"))
+ && (rdb1 = XrmGetFileDatabase (xe)))
+ XrmMergeDatabases (rdb1, &database);
+ else if (homedir)
+ {
+ struct utsname un;
- /* Add in $XAPPLRESDIR/Rxvt only; not bothering with XUSERFILESEARCHPATH */
- if ((xe = (char *)getenv ("XAPPLRESDIR")) != NULL)
- {
- sprintf (fname, "%-.*s/" RESCLASS, sizeof (fname)
- - sizeof (RESCLASS) - 2, xe);
- if ((rdb1 = XrmGetFileDatabase (fname)) != NULL)
- XrmMergeDatabases (rdb1, &database);
- }
+ if (!uname (&un))
+ {
+ snprintf (fname, sizeof (fname), "%s/.Xdefaults-%s", homedir, un.nodename);
- XrmSetDatabase (display, database);
+ if ((rdb1 = XrmGetFileDatabase (fname)))
+ XrmMergeDatabases (rdb1, &database);
+ }
+ }
+
+ XrmSetDatabase (disp, database);
# endif
- /*
- * Query resources for options that affect us
- */
- for (entry = 0; entry < optList_size (); entry++)
- {
- int s;
- char *p, *p0;
- const char *kw = optList[entry].kw;
+ /*
+ * Query resources for options that affect us
+ */
+ for (entry = 0; entry < optList_size; entry++)
+ {
+ int s;
+ char *p, *p0;
+ const char *kw = optList[entry].kw;
- if (kw == NULL || rs[optList[entry].doff] != NULL)
- continue; /* previously set */
+ if (kw == NULL || rs[optList[entry].doff] != NULL)
+ continue; /* previously set */
- p = XGetDefault (display, name, kw);
- p0 = XGetDefault (display, "!INVALIDPROGRAMMENAMEDONTMATCH!", kw);
- if (p == NULL || (p0 && strcmp (p, p0) == 0))
- {
- p = XGetDefault (display, RESCLASS, kw);
+ p = XGetDefault (disp, rs[Rs_name], kw);
+ p0 = XGetDefault (disp, "!INVALIDPROGRAMMENAMEDONTMATCH!", kw);
+ if (p == NULL || (p0 && strcmp (p, p0) == 0))
+ {
+ p = XGetDefault (disp, RESCLASS, kw);
#ifdef RESFALLBACK
- if (p == NULL || (p0 && strcmp (p, p0) == 0))
- p = XGetDefault (display, RESFALLBACK, kw);
+ if (p == NULL || (p0 && strcmp (p, p0) == 0))
+ p = XGetDefault (disp, RESFALLBACK, kw);
#endif
- }
+ }
- if (p == NULL && p0)
- p = p0;
+ if (p == NULL && p0)
+ p = p0;
- if (p)
- {
- rs[optList[entry].doff] = p;
+ if (p)
+ {
+ rs[optList[entry].doff] = p;
- if (optList_isBool (entry))
- {
- s = strcasecmp (p, "TRUE") == 0
- || strcasecmp (p, "YES") == 0
- || strcasecmp (p, "ON") == 0
- || strcasecmp (p, "1") == 0;
- if (optList_isReverse (entry))
- s = !s;
- if (s)
- options |= (optList[entry].flag);
- else
- options &= ~ (optList[entry].flag);
- }
- }
- }
+ if (optList_isBool (entry))
+ {
+ s = strcasecmp (p, "TRUE") == 0
+ || strcasecmp (p, "YES") == 0
+ || strcasecmp (p, "ON") == 0
+ || strcasecmp (p, "1") == 0;
- /*
- * [R5 or later]: enumerate the resource database
- */
-# ifdef XrmEnumOneLevel
-# ifdef KEYSYM_RESOURCE
- name_prefix[0] = XrmStringToName (name);
- name_prefix[1] = XrmStringToName ("keysym");
- name_prefix[2] = NULLQUARK;
- class_prefix[0] = XrmStringToName (RESCLASS);
- class_prefix[1] = XrmStringToName ("Keysym");
- class_prefix[2] = NULLQUARK;
- /* XXX: Need to check sizeof (rxvt_t) == sizeof (XPointer) */
- XrmEnumerateDatabase (XrmGetDatabase (display), name_prefix, class_prefix,
- XrmEnumOneLevel, rxvt_define_key, NULL);
-# ifdef RESFALLBACK
- name_prefix[0] = XrmStringToName (RESFALLBACK);
- name_prefix[1] = XrmStringToName ("keysym");
- class_prefix[0] = XrmStringToName (RESFALLBACK);
- class_prefix[1] = XrmStringToName ("Keysym");
- /* XXX: Need to check sizeof (rxvt_t) == sizeof (XPointer) */
- XrmEnumerateDatabase (XrmGetDatabase (display), name_prefix, class_prefix,
- XrmEnumOneLevel, rxvt_define_key, NULL);
-# endif
+ if (optList_isReverse (entry))
+ s = !s;
+
+ if (s)
+ options |= optList[entry].flag;
+ else
+ options &= ~optList[entry].flag;
+ }
+ }
+ }
+
+ /*
+ * [R5 or later]: enumerate the resource database
+ */
+# ifdef KEYSYM_RESOURCE
+ name_prefix[0] = XrmStringToName (rs[Rs_name]);
+ name_prefix[1] = XrmStringToName ("keysym");
+ name_prefix[2] = NULLQUARK;
+ class_prefix[0] = XrmStringToName (RESCLASS);
+ class_prefix[1] = XrmStringToName ("Keysym");
+ class_prefix[2] = NULLQUARK;
+ /* XXX: Need to check sizeof (rxvt_t) == sizeof (XPointer) */
+ XrmEnumerateDatabase (XrmGetDatabase (disp), name_prefix, class_prefix,
+ XrmEnumOneLevel, rxvt_define_key, NULL);
+# ifdef RESFALLBACK
+ name_prefix[0] = XrmStringToName (RESFALLBACK);
+ name_prefix[1] = XrmStringToName ("keysym");
+ class_prefix[0] = XrmStringToName (RESFALLBACK);
+ class_prefix[1] = XrmStringToName ("Keysym");
+ /* XXX: Need to check sizeof (rxvt_t) == sizeof (XPointer) */
+ XrmEnumerateDatabase (XrmGetDatabase (disp), name_prefix, class_prefix,
+ XrmEnumOneLevel, rxvt_define_key, NULL);
# endif
# endif
# else /* USE_XGETDEFAULT */
- /* get resources the hard way, but save lots of memory */
- FILE *fd = NULL;
- char *home;
-
- if ((home = getenv ("HOME")) != NULL)
- {
- unsigned int i, len = strlen (home) + 2;
- char *f = NULL;
+ /* get resources the hard way, but save lots of memory */
+ FILE *fd = NULL;
- for (i = 0; i < (sizeof (xnames) / sizeof (xnames[0])); i++)
- {
- f = (char *)rxvt_realloc (f, len + strlen (xnames[i]));
-
- sprintf (f, "%s/%s", home, xnames[i]);
+ if (homedir)
+ {
+ static const char *const xnames[2] = { ".Xdefaults", ".Xresources" };
- if ((fd = fopen (f, "r")) != NULL)
- break;
- }
+ for (int i = 0; i < (sizeof (xnames) / sizeof (xnames [0])); i++)
+ {
+ snprintf (fname, sizeof (fname), "%s/%s", homedir, xnames [i]);
- free (f);
- }
- /*
- * The normal order to match resources is the following:
- * @ global resources (partial match, ~/.Xdefaults)
- * @ application file resources (XAPPLOADDIR/Rxvt)
- * @ class resources (~/.Xdefaults)
- * @ private resources (~/.Xdefaults)
- *
- * However, for the hand-rolled resources, the matching algorithm
- * checks if a resource string value has already been allocated
- * and won't overwrite it with (in this case) a less specific
- * resource value.
- *
- * This avoids multiple allocation. Also, when we've called this
- * routine command-line string options have already been applied so we
- * needn't to allocate for those resources.
- *
- * So, search in resources from most to least specific.
- *
- * Also, use a special sub-class so that we can use either or both of
- * "XTerm" and "Rxvt" as class names.
- */
-
- get_xdefaults (fd, name);
- get_xdefaults (fd, RESCLASS);
+ if ((fd = fopen (fname, "r")) != NULL)
+ break;
+ }
+ }
+ /*
+ * The normal order to match resources is the following:
+ * @ global resources (partial match, ~/.Xdefaults)
+ * @ application file resources (XAPPLOADDIR/Rxvt)
+ * @ class resources (~/.Xdefaults)
+ * @ private resources (~/.Xdefaults)
+ *
+ * However, for the hand-rolled resources, the matching algorithm
+ * checks if a resource string value has already been allocated
+ * and won't overwrite it with (in this case) a less specific
+ * resource value.
+ *
+ * This avoids multiple allocation. Also, when we've called this
+ * routine command-line string options have already been applied so we
+ * needn't to allocate for those resources.
+ *
+ * So, search in resources from most to least specific.
+ *
+ * Also, use a special sub-class so that we can use either or both of
+ * "XTerm" and "Rxvt" as class names.
+ */
+
+ get_xdefaults (fd, rs[Rs_name]);
+ get_xdefaults (fd, RESCLASS);
# ifdef RESFALLBACK
- get_xdefaults (fd, RESFALLBACK);
+ get_xdefaults (fd, RESFALLBACK);
# endif
# if defined(XAPPLOADDIR) && defined(USE_XAPPLOADDIR)
- {
- FILE *ad = NULL;
+ {
+ FILE *ad = NULL;
# if defined(HAVE_XSETLOCALE) || defined(HAVE_SETLOCALE)
- if (localepath == NULL || (ad = fopen (localepath, "r")) == NULL)
+ if (!*localepath || (ad = fopen (localepath, "r")) == NULL)
# endif
- ad = fopen (XAPPLOADDIR "/" RESCLASS, "r");
- if (ad != NULL)
- {
- get_xdefaults (ad, RESCLASS);
- get_xdefaults (ad, "");
- fclose (ad);
- }
- }
+ ad = fopen (XAPPLOADDIR "/" RESCLASS, "r");
+ if (ad != NULL)
+ {
+ get_xdefaults (ad, RESCLASS);
+ get_xdefaults (ad, "");
+ fclose (ad);
+ }
+ }
# endif /* XAPPLOADDIR */
- get_xdefaults (fd, ""); /* partial match */
- if (fd != NULL)
- fclose (fd);
+ get_xdefaults (fd, ""); /* partial match */
+ if (fd != NULL)
+ fclose (fd);
# endif /* USE_XGETDEFAULT */
-# if defined XAPPLOADDIR
-# if defined(HAVE_XSETLOCALE) || defined(HAVE_SETLOCALE)
-
- }
-
- /* Free the path of the possibly available localized Rxvt file */
- free (localepath);
-# endif
-# endif
-
#endif /* NO_RESOURCES */
}