1 /*
2  * resources.c
3  * march 1994
4  *
5  * this file is copied essentially verbatim from the sources for Jamie
6  * Zawinski's xscreensaver package; his original copyright notice
7  * follows this comment.
8  */
9 
10 /* xscreensaver, Copyright (c) 1992 Jamie Zawinski <jwz@lucid.com>
11  *
12  * Permission to use, copy, modify, distribute, and sell this software
13  * and its documentation for any purpose is hereby granted without
14  * fee, provided that the above copyright notice appear in all copies
15  * and that both that copyright notice and this permission notice
16  * appear in supporting documentation. No representations are made
17  * about the suitability of this software for any purpose. It is
18  * provided "as is" without express or implied warranty.
19  */
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <X11/Xos.h>
24 #include <X11/Xlib.h>
25 #include <X11/Xresource.h>
26 #include "port.h"
27 
28 /* Resource functions.  Assumes: */
29 
30 extern char *progname;
31 extern char *progclass;
32 extern XrmDatabase db;
33 
34 #ifndef isupper
35 # define isupper(c)  ((c) >= 'A' && (c) <= 'Z')
36 #endif
37 #ifndef _tolower
38 # define _tolower(c)  ((c) - 'A' + 'a')
39 #endif
40 
41 char               *get_string_resource _P((const char *, const char *));
42 int                 get_boolean_resource _P((const char *, const char *));
43 int                 get_integer_resource _P((const char *, const char *));
44 double              get_float_resource _P((const char *, const char *));
45 unsigned int        get_pixel_resource _P((const char *, const char *,
46                       Display *, Colormap));
47 int                 parse_time _P((const char *, int, int));
48 static unsigned int get_time_resource _P((const char *, const char *, int));
49 unsigned int        get_seconds_resource _P((const char *, const char *));
50 unsigned int        get_minutes_resource _P((const char *, const char *));
51 
52 char *
get_string_resource(res_name,res_class)53 get_string_resource (res_name, res_class)
54      const char *res_name, *res_class;
55 {
56   XrmValue value;
57   char	*type;
58   char full_name [1024], full_class [1024];
59   strcpy (full_name, progname);
60   strcat (full_name, ".");
61   strcat (full_name, res_name);
62   strcpy (full_class, progclass);
63   strcat (full_class, ".");
64   strcat (full_class, res_class);
65   if (XrmGetResource (db, full_name, full_class, &type, &value))
66     {
67       char *str = (char *) malloc ((unsigned) value.size + 1);
68       strncpy (str, (char *) value.addr, value.size);
69       str [value.size] = 0;
70       return str;
71     }
72   return 0;
73 }
74 
75 int
get_boolean_resource(res_name,res_class)76 get_boolean_resource (res_name, res_class)
77      const char *res_name, *res_class;
78 {
79   char *tmp, buf [100];
80   char *s = get_string_resource (res_name, res_class);
81   char *os = s;
82   if (! s) return 0;
83   for (tmp = buf; *s; s++)
84     *tmp++ = isupper (*s) ? _tolower (*s) : *s;
85   *tmp = 0;
86   free (os);
87 
88   if (!strcmp (buf, "on") || !strcmp (buf, "true") || !strcmp (buf, "yes"))
89     return 1;
90   if (!strcmp (buf,"off") || !strcmp (buf, "false") || !strcmp (buf,"no"))
91     return 0;
92   fprintf (stderr, "%s: %s must be boolean, not %s.\n",
93 	   progname, res_class, buf);
94   return 0;
95 }
96 
97 int
get_integer_resource(res_name,res_class)98 get_integer_resource (res_name, res_class)
99      const char *res_name, *res_class;
100 {
101   int val;
102   char c, *s = get_string_resource (res_name, res_class);
103   if (!s) return 0;
104   if (1 == sscanf (s, " %d %c", &val, &c))
105     {
106       free (s);
107       return val;
108     }
109   fprintf (stderr, "%s: %s must be an integer, not %s.\n",
110 	   progname, res_name, s);
111   free (s);
112   return 0;
113 }
114 
115 double
get_float_resource(res_name,res_class)116 get_float_resource (res_name, res_class)
117      const char *res_name, *res_class;
118 {
119   double val;
120   char c, *s = get_string_resource (res_name, res_class);
121   if (! s) return 0.0;
122   if (1 == sscanf (s, " %lf %c", &val, &c))
123     {
124       free (s);
125       return val;
126     }
127   fprintf (stderr, "%s: %s must be a float, not %s.\n",
128 	   progname, res_name, s);
129   free (s);
130   return 0.0;
131 }
132 
133 
134 unsigned int
get_pixel_resource(res_name,res_class,dpy,cmap)135 get_pixel_resource (res_name, res_class, dpy, cmap)
136      const char *res_name, *res_class;
137      Display *dpy;
138      Colormap cmap;
139 {
140   XColor color;
141   char *s = get_string_resource (res_name, res_class);
142   if (!s) goto DEFAULT;
143 
144   if (! XParseColor (dpy, cmap, s, &color))
145     {
146       fprintf (stderr, "%s: can't parse color %s\n", progname, s);
147       goto DEFAULT;
148     }
149   if (! XAllocColor (dpy, cmap, &color))
150     {
151       fprintf (stderr, "%s: couldn't allocate color %s\n", progname, s);
152       goto DEFAULT;
153     }
154   free (s);
155   return color.pixel;
156  DEFAULT:
157   if (s) free (s);
158   return (strcmp (res_class, "Background")
159 	  ? WhitePixel (dpy, DefaultScreen (dpy))
160 	  : BlackPixel (dpy, DefaultScreen (dpy)));
161 }
162 
163 
164 int
parse_time(string,seconds_default_p,silent_p)165 parse_time (string, seconds_default_p, silent_p)
166      const char *string;
167      Bool seconds_default_p, silent_p;
168 {
169   unsigned int h, m, s;
170   char c;
171   if (3 == sscanf (string,   " %u : %2u : %2u %c", &h, &m, &s, &c))
172     ;
173   else if (2 == sscanf (string, " : %2u : %2u %c", &m, &s, &c) ||
174 	   2 == sscanf (string,    " %u : %2u %c", &m, &s, &c))
175     h = 0;
176   else if (1 == sscanf (string,       " : %2u %c", &s, &c))
177     h = m = 0;
178   else if (1 == sscanf (string,          " %u %c",
179 			(seconds_default_p ? &s : &m), &c))
180     {
181       h = 0;
182       if (seconds_default_p) m = 0;
183       else s = 0;
184     }
185   else
186     {
187       if (! silent_p)
188 	fprintf (stderr, "%s: invalid time interval specification \"%s\".\n",
189 		 progname, string);
190       return -1;
191     }
192   if (s >= 60 && (h != 0 || m != 0))
193     {
194       if (! silent_p)
195 	fprintf (stderr, "%s: seconds > 59 in \"%s\".\n", progname, string);
196       return -1;
197     }
198   if (m >= 60 && h > 0)
199     {
200       if (! silent_p)
201 	fprintf (stderr, "%s: minutes > 59 in \"%s\".\n", progname, string);
202       return -1;
203     }
204   return ((h * 60 * 60) + (m * 60) + s);
205 }
206 
207 static unsigned int
get_time_resource(res_name,res_class,sec_p)208 get_time_resource (res_name, res_class, sec_p)
209      const char *res_name, *res_class;
210      Bool sec_p;
211 {
212   int val;
213   char *s = get_string_resource (res_name, res_class);
214   if (!s) return 0;
215   val = parse_time (s, sec_p, False);
216   free (s);
217   return (val < 0 ? 0 : val);
218 }
219 
220 unsigned int
get_seconds_resource(res_name,res_class)221 get_seconds_resource (res_name, res_class)
222      const char *res_name, *res_class;
223 {
224   return get_time_resource (res_name, res_class, True);
225 }
226 
227 unsigned int
get_minutes_resource(res_name,res_class)228 get_minutes_resource (res_name, res_class)
229      const char *res_name, *res_class;
230 {
231   return get_time_resource (res_name, res_class, False);
232 }
233