18db30ca8Sthorpej/* xscreensaver, Copyright (c) 1992, 1997, 1998
28db30ca8Sthorpej *  Jamie Zawinski <jwz@jwz.org>
38db30ca8Sthorpej *
48db30ca8Sthorpej * Permission to use, copy, modify, distribute, and sell this software and its
58db30ca8Sthorpej * documentation for any purpose is hereby granted without fee, provided that
68db30ca8Sthorpej * the above copyright notice appear in all copies and that both that
78db30ca8Sthorpej * copyright notice and this permission notice appear in supporting
88db30ca8Sthorpej * documentation.  No representations are made about the suitability of this
98db30ca8Sthorpej * software for any purpose.  It is provided "as is" without express or
108db30ca8Sthorpej * implied warranty.
118db30ca8Sthorpej */
128db30ca8Sthorpej
13c056561aSmbalmer/* 1999-Nov-21 Modified by Jim Knoble <jmknoble@jmknoble.cx>.
148db30ca8Sthorpej * Modifications:
158db30ca8Sthorpej *
168db30ca8Sthorpej *   - Made get_boolean_resource() accept a third parameter, default_value,
178db30ca8Sthorpej *     which determines the result of get_boolean_resource if either (a)
188db30ca8Sthorpej *     no such resource exists, or (b) the resource value does not conform
198db30ca8Sthorpej *     to the syntax of a boolean resource.
208db30ca8Sthorpej *
218db30ca8Sthorpej *   - Same for get_integer_resource(), get_pixel_resource().
228db30ca8Sthorpej *
238db30ca8Sthorpej *   - 1999-Dec-24 Moved header includes from utils.h to here.
248db30ca8Sthorpej *     Trimmed unused functions.
258db30ca8Sthorpej */
268db30ca8Sthorpej
278db30ca8Sthorpej#include <stdlib.h>
288db30ca8Sthorpej#include <stdio.h>
298db30ca8Sthorpej#include <string.h>
308db30ca8Sthorpej#include <math.h>
318db30ca8Sthorpej#include <X11/Xlib.h>
328db30ca8Sthorpej#include <X11/Xos.h>
338db30ca8Sthorpej#include <X11/Xresource.h>
348db30ca8Sthorpej#include "resources.h"
358db30ca8Sthorpej
368db30ca8Sthorpej
378db30ca8Sthorpej/* Resource functions.  Assumes: */
388db30ca8Sthorpej
398db30ca8Sthorpejextern char *progname;
408db30ca8Sthorpejextern char *progclass;
418db30ca8Sthorpejextern XrmDatabase db;
428db30ca8Sthorpej
438db30ca8Sthorpej#ifndef isupper
448db30ca8Sthorpej# define isupper(c)  ((c) >= 'A' && (c) <= 'Z')
458db30ca8Sthorpej#endif
468db30ca8Sthorpej#ifndef _tolower
478db30ca8Sthorpej# define _tolower(c)  ((c) - 'A' + 'a')
488db30ca8Sthorpej#endif
498db30ca8Sthorpej
508db30ca8Sthorpejchar *
518db30ca8Sthorpejget_string_resource (char *res_name, char *res_class)
528db30ca8Sthorpej{
538db30ca8Sthorpej  XrmValue value;
548db30ca8Sthorpej  char	*type;
558db30ca8Sthorpej  char full_name [1024], full_class [1024];
56c056561aSmbalmer  int result;
57c056561aSmbalmer
58c056561aSmbalmer  result = snprintf(full_name, sizeof(full_name), "%s.%s",
59c056561aSmbalmer      progname, res_name);
60c056561aSmbalmer  if (result == -1 || result >= sizeof(full_name)) {
61c056561aSmbalmer	  fprintf(stderr, "%s: resource name too long: %s.%s\n", progname,
62c056561aSmbalmer	      progname, res_name);
63c056561aSmbalmer	  return 0;
64c056561aSmbalmer  }
65c056561aSmbalmer  result = snprintf(full_class, sizeof(full_class), "%s.%s",
66c056561aSmbalmer      progclass, res_class);
67c056561aSmbalmer  if (result == -1 || result >= sizeof(full_class)) {
68c056561aSmbalmer	 fprintf(stderr, "%s: resource name too long: %s.%s\n", progname,
69c056561aSmbalmer	      progclass, res_class);
70c056561aSmbalmer	  return 0;
71c056561aSmbalmer  }
728db30ca8Sthorpej  if (XrmGetResource (db, full_name, full_class, &type, &value))
738db30ca8Sthorpej    {
748db30ca8Sthorpej      char *str = (char *) malloc (value.size + 1);
758db30ca8Sthorpej      strncpy (str, (char *) value.addr, value.size);
768db30ca8Sthorpej      str [value.size] = 0;
778db30ca8Sthorpej      return str;
788db30ca8Sthorpej    }
798db30ca8Sthorpej  return 0;
808db30ca8Sthorpej}
818db30ca8Sthorpej
828db30ca8SthorpejBool
838db30ca8Sthorpejget_boolean_resource (char *res_name, char *res_class, Bool default_value)
848db30ca8Sthorpej{
858db30ca8Sthorpej  char *tmp, buf [100];
868db30ca8Sthorpej  char *s = get_string_resource (res_name, res_class);
878db30ca8Sthorpej  char *os = s;
888db30ca8Sthorpej  if (! s) return default_value;
898db30ca8Sthorpej  for (tmp = buf; *s; s++)
908db30ca8Sthorpej    *tmp++ = isupper (*s) ? _tolower (*s) : *s;
918db30ca8Sthorpej  *tmp = 0;
928db30ca8Sthorpej  free (os);
938db30ca8Sthorpej
948db30ca8Sthorpej  while (*buf &&
958db30ca8Sthorpej	 (buf[strlen(buf)-1] == ' ' ||
968db30ca8Sthorpej	  buf[strlen(buf)-1] == '\t'))
978db30ca8Sthorpej    buf[strlen(buf)-1] = 0;
988db30ca8Sthorpej
998db30ca8Sthorpej  if (!strcmp (buf, "on") || !strcmp (buf, "true") || !strcmp (buf, "yes"))
1008db30ca8Sthorpej    return 1;
1018db30ca8Sthorpej  if (!strcmp (buf,"off") || !strcmp (buf, "false") || !strcmp (buf,"no"))
1028db30ca8Sthorpej    return 0;
1038db30ca8Sthorpej  fprintf (stderr, "%s: %s must be boolean, not %s.\n",
1048db30ca8Sthorpej	   progname, res_name, buf);
1058db30ca8Sthorpej  return default_value;
1068db30ca8Sthorpej}
1078db30ca8Sthorpej
1088db30ca8Sthorpejint
1098db30ca8Sthorpejget_integer_resource (char *res_name, char *res_class, int default_value)
1108db30ca8Sthorpej{
1118db30ca8Sthorpej  int val;
1128db30ca8Sthorpej  char c, *s = get_string_resource (res_name, res_class);
1138db30ca8Sthorpej  char *ss = s;
1148db30ca8Sthorpej  if (!s) return default_value;
1158db30ca8Sthorpej
1168db30ca8Sthorpej  while (*ss && *ss <= ' ') ss++;			/* skip whitespace */
1178db30ca8Sthorpej
1188db30ca8Sthorpej  if (ss[0] == '0' && (ss[1] == 'x' || ss[1] == 'X'))	/* 0x: parse as hex */
1198db30ca8Sthorpej    {
1208db30ca8Sthorpej      if (1 == sscanf (ss+2, "%x %c", &val, &c))
1218db30ca8Sthorpej	{
1228db30ca8Sthorpej	  free (s);
1238db30ca8Sthorpej	  return val;
1248db30ca8Sthorpej	}
1258db30ca8Sthorpej    }
1268db30ca8Sthorpej  else							/* else parse as dec */
1278db30ca8Sthorpej    {
1288db30ca8Sthorpej      if (1 == sscanf (ss, "%d %c", &val, &c))
1298db30ca8Sthorpej	{
1308db30ca8Sthorpej	  free (s);
1318db30ca8Sthorpej	  return val;
1328db30ca8Sthorpej	}
1338db30ca8Sthorpej    }
1348db30ca8Sthorpej
1358db30ca8Sthorpej  fprintf (stderr, "%s: %s must be an integer, not %s.\n",
1368db30ca8Sthorpej	   progname, res_name, s);
1378db30ca8Sthorpej  free (s);
1388db30ca8Sthorpej  return default_value;
1398db30ca8Sthorpej}
1408db30ca8Sthorpej
1418db30ca8Sthorpejdouble
1428db30ca8Sthorpejget_float_resource (char *res_name, char *res_class)
1438db30ca8Sthorpej{
1448db30ca8Sthorpej  double val;
1458db30ca8Sthorpej  char c, *s = get_string_resource (res_name, res_class);
1468db30ca8Sthorpej  if (! s) return 0.0;
1478db30ca8Sthorpej  if (1 == sscanf (s, " %lf %c", &val, &c))
1488db30ca8Sthorpej    {
1498db30ca8Sthorpej      free (s);
1508db30ca8Sthorpej      return val;
1518db30ca8Sthorpej    }
1528db30ca8Sthorpej  fprintf (stderr, "%s: %s must be a float, not %s.\n",
1538db30ca8Sthorpej	   progname, res_name, s);
1548db30ca8Sthorpej  free (s);
1558db30ca8Sthorpej  return 0.0;
1568db30ca8Sthorpej}
1578db30ca8Sthorpej
1588db30ca8Sthorpej
1598db30ca8Sthorpejunsigned int
1608db30ca8Sthorpejget_pixel_resource (char *res_name, char *res_class,
1618db30ca8Sthorpej		    Display *dpy, Colormap cmap, unsigned int default_value)
1628db30ca8Sthorpej{
1638db30ca8Sthorpej  XColor color;
1648db30ca8Sthorpej  char *s = get_string_resource (res_name, res_class);
1658db30ca8Sthorpej  char *s2;
1668db30ca8Sthorpej  if (!s) goto DEFAULT;
1678db30ca8Sthorpej
1688db30ca8Sthorpej  for (s2 = s + strlen(s) - 1; s2 > s; s2--)
1698db30ca8Sthorpej    if (*s2 == ' ' || *s2 == '\t')
1708db30ca8Sthorpej      *s2 = 0;
1718db30ca8Sthorpej    else
1728db30ca8Sthorpej      break;
1738db30ca8Sthorpej
1748db30ca8Sthorpej  if (! XParseColor (dpy, cmap, s, &color))
1758db30ca8Sthorpej    {
1768db30ca8Sthorpej      fprintf (stderr, "%s: can't parse color %s\n", progname, s);
1778db30ca8Sthorpej      goto DEFAULT;
1788db30ca8Sthorpej    }
1798db30ca8Sthorpej  if (! XAllocColor (dpy, cmap, &color))
1808db30ca8Sthorpej    {
1818db30ca8Sthorpej      fprintf (stderr, "%s: couldn't allocate color %s\n", progname, s);
1828db30ca8Sthorpej      goto DEFAULT;
1838db30ca8Sthorpej    }
1848db30ca8Sthorpej  free (s);
1858db30ca8Sthorpej  return color.pixel;
1868db30ca8Sthorpej DEFAULT:
1878db30ca8Sthorpej  if (s) free (s);
1888db30ca8Sthorpej  return default_value;
1898db30ca8Sthorpej}
1908db30ca8Sthorpej
191