1/* xscreensaver, Copyright (c) 1992, 1997, 1998
2 *  Jamie Zawinski <jwz@jwz.org>
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation.  No representations are made about the suitability of this
9 * software for any purpose.  It is provided "as is" without express or
10 * implied warranty.
11 */
12
13/* 1999-Nov-21 Modified by Jim Knoble <jmknoble@jmknoble.cx>.
14 * Modifications:
15 *
16 *   - Made get_boolean_resource() accept a third parameter, default_value,
17 *     which determines the result of get_boolean_resource if either (a)
18 *     no such resource exists, or (b) the resource value does not conform
19 *     to the syntax of a boolean resource.
20 *
21 *   - Same for get_integer_resource(), get_pixel_resource().
22 *
23 *   - 1999-Dec-24 Moved header includes from utils.h to here.
24 *     Trimmed unused functions.
25 */
26
27#include <stdlib.h>
28#include <stdio.h>
29#include <string.h>
30#include <math.h>
31#include <X11/Xlib.h>
32#include <X11/Xos.h>
33#include <X11/Xresource.h>
34#include "resources.h"
35
36
37/* Resource functions.  Assumes: */
38
39extern char *progname;
40extern char *progclass;
41extern XrmDatabase db;
42
43#ifndef isupper
44# define isupper(c)  ((c) >= 'A' && (c) <= 'Z')
45#endif
46#ifndef _tolower
47# define _tolower(c)  ((c) - 'A' + 'a')
48#endif
49
50char *
51get_string_resource (char *res_name, char *res_class)
52{
53  XrmValue value;
54  char	*type;
55  char full_name [1024], full_class [1024];
56  int result;
57
58  result = snprintf(full_name, sizeof(full_name), "%s.%s",
59      progname, res_name);
60  if (result == -1 || result >= sizeof(full_name)) {
61	  fprintf(stderr, "%s: resource name too long: %s.%s\n", progname,
62	      progname, res_name);
63	  return 0;
64  }
65  result = snprintf(full_class, sizeof(full_class), "%s.%s",
66      progclass, res_class);
67  if (result == -1 || result >= sizeof(full_class)) {
68	 fprintf(stderr, "%s: resource name too long: %s.%s\n", progname,
69	      progclass, res_class);
70	  return 0;
71  }
72  if (XrmGetResource (db, full_name, full_class, &type, &value))
73    {
74      char *str = (char *) malloc (value.size + 1);
75      strncpy (str, (char *) value.addr, value.size);
76      str [value.size] = 0;
77      return str;
78    }
79  return 0;
80}
81
82Bool
83get_boolean_resource (char *res_name, char *res_class, Bool default_value)
84{
85  char *tmp, buf [100];
86  char *s = get_string_resource (res_name, res_class);
87  char *os = s;
88  if (! s) return default_value;
89  for (tmp = buf; *s; s++)
90    *tmp++ = isupper (*s) ? _tolower (*s) : *s;
91  *tmp = 0;
92  free (os);
93
94  while (*buf &&
95	 (buf[strlen(buf)-1] == ' ' ||
96	  buf[strlen(buf)-1] == '\t'))
97    buf[strlen(buf)-1] = 0;
98
99  if (!strcmp (buf, "on") || !strcmp (buf, "true") || !strcmp (buf, "yes"))
100    return 1;
101  if (!strcmp (buf,"off") || !strcmp (buf, "false") || !strcmp (buf,"no"))
102    return 0;
103  fprintf (stderr, "%s: %s must be boolean, not %s.\n",
104	   progname, res_name, buf);
105  return default_value;
106}
107
108int
109get_integer_resource (char *res_name, char *res_class, int default_value)
110{
111  int val;
112  char c, *s = get_string_resource (res_name, res_class);
113  char *ss = s;
114  if (!s) return default_value;
115
116  while (*ss && *ss <= ' ') ss++;			/* skip whitespace */
117
118  if (ss[0] == '0' && (ss[1] == 'x' || ss[1] == 'X'))	/* 0x: parse as hex */
119    {
120      if (1 == sscanf (ss+2, "%x %c", &val, &c))
121	{
122	  free (s);
123	  return val;
124	}
125    }
126  else							/* else parse as dec */
127    {
128      if (1 == sscanf (ss, "%d %c", &val, &c))
129	{
130	  free (s);
131	  return val;
132	}
133    }
134
135  fprintf (stderr, "%s: %s must be an integer, not %s.\n",
136	   progname, res_name, s);
137  free (s);
138  return default_value;
139}
140
141double
142get_float_resource (char *res_name, char *res_class)
143{
144  double val;
145  char c, *s = get_string_resource (res_name, res_class);
146  if (! s) return 0.0;
147  if (1 == sscanf (s, " %lf %c", &val, &c))
148    {
149      free (s);
150      return val;
151    }
152  fprintf (stderr, "%s: %s must be a float, not %s.\n",
153	   progname, res_name, s);
154  free (s);
155  return 0.0;
156}
157
158
159unsigned int
160get_pixel_resource (char *res_name, char *res_class,
161		    Display *dpy, Colormap cmap, unsigned int default_value)
162{
163  XColor color;
164  char *s = get_string_resource (res_name, res_class);
165  char *s2;
166  if (!s) goto DEFAULT;
167
168  for (s2 = s + strlen(s) - 1; s2 > s; s2--)
169    if (*s2 == ' ' || *s2 == '\t')
170      *s2 = 0;
171    else
172      break;
173
174  if (! XParseColor (dpy, cmap, s, &color))
175    {
176      fprintf (stderr, "%s: can't parse color %s\n", progname, s);
177      goto DEFAULT;
178    }
179  if (! XAllocColor (dpy, cmap, &color))
180    {
181      fprintf (stderr, "%s: couldn't allocate color %s\n", progname, s);
182      goto DEFAULT;
183    }
184  free (s);
185  return color.pixel;
186 DEFAULT:
187  if (s) free (s);
188  return default_value;
189}
190
191