http://svn.poeml.de/viewvc/ppc/src-unpacked/xscreensaver/xscreensaver-4.12.tar.bz2...
[xscreensaver] / utils / resources.c
1 /* xscreensaver, Copyright (c) 1992, 1997, 1998, 2001, 2003
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 #include "utils.h"
14 #include "resources.h"
15 #include <X11/Xresource.h>
16
17
18 /* Resource functions.  Assumes: */
19
20 extern char *progname;
21 extern char *progclass;
22 extern XrmDatabase db;
23
24 static unsigned int get_time_resource (char *res_name, char *res_class,
25                                        Bool sec_p);
26
27 #ifndef isupper
28 # define isupper(c)  ((c) >= 'A' && (c) <= 'Z')
29 #endif
30 #ifndef _tolower
31 # define _tolower(c)  ((c) - 'A' + 'a')
32 #endif
33
34 char *
35 get_string_resource (char *res_name, char *res_class)
36 {
37   XrmValue value;
38   char  *type;
39   char full_name [1024], full_class [1024];
40   strcpy (full_name, progname);
41   strcat (full_name, ".");
42   strcat (full_name, res_name);
43   strcpy (full_class, progclass);
44   strcat (full_class, ".");
45   strcat (full_class, res_class);
46   if (XrmGetResource (db, full_name, full_class, &type, &value))
47     {
48       char *str = (char *) malloc (value.size + 1);
49       strncpy (str, (char *) value.addr, value.size);
50       str [value.size] = 0;
51       return str;
52     }
53   return 0;
54 }
55
56 Bool 
57 get_boolean_resource (char *res_name, char *res_class)
58 {
59   char *tmp, buf [100];
60   char *s = get_string_resource (res_name, res_class);
61   char *os = s;
62   if (! s) return 0;
63   for (tmp = buf; *s; s++)
64     *tmp++ = isupper (*s) ? _tolower (*s) : *s;
65   *tmp = 0;
66   free (os);
67
68   while (*buf &&
69          (buf[strlen(buf)-1] == ' ' ||
70           buf[strlen(buf)-1] == '\t'))
71     buf[strlen(buf)-1] = 0;
72
73   if (!strcmp (buf, "on") || !strcmp (buf, "true") || !strcmp (buf, "yes"))
74     return 1;
75   if (!strcmp (buf,"off") || !strcmp (buf, "false") || !strcmp (buf,"no"))
76     return 0;
77   fprintf (stderr, "%s: %s must be boolean, not %s.\n",
78            progname, res_name, buf);
79   return 0;
80 }
81
82 int 
83 get_integer_resource (char *res_name, char *res_class)
84 {
85   int val;
86   char c, *s = get_string_resource (res_name, res_class);
87   char *ss = s;
88   if (!s) return 0;
89
90   while (*ss && *ss <= ' ') ss++;                       /* skip whitespace */
91
92   if (ss[0] == '0' && (ss[1] == 'x' || ss[1] == 'X'))   /* 0x: parse as hex */
93     {
94       if (1 == sscanf (ss+2, "%x %c", (unsigned int *) &val, &c))
95         {
96           free (s);
97           return val;
98         }
99     }
100   else                                                  /* else parse as dec */
101     {
102       if (1 == sscanf (ss, "%d %c", &val, &c))
103         {
104           free (s);
105           return val;
106         }
107     }
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
116 get_float_resource (char *res_name, char *res_class)
117 {
118   double val;
119   char c, *s = get_string_resource (res_name, res_class);
120   if (! s) return 0.0;
121   if (1 == sscanf (s, " %lf %c", &val, &c))
122     {
123       free (s);
124       return val;
125     }
126   fprintf (stderr, "%s: %s must be a float, not %s.\n",
127            progname, res_name, s);
128   free (s);
129   return 0.0;
130 }
131
132
133 unsigned int
134 get_pixel_resource (char *res_name, char *res_class,
135                     Display *dpy, Colormap cmap)
136 {
137   XColor color;
138   char *s = get_string_resource (res_name, res_class);
139   char *s2;
140   Bool ok = True;
141   if (!s) goto DEFAULT;
142
143   for (s2 = s + strlen(s) - 1; s2 > s; s2--)
144     if (*s2 == ' ' || *s2 == '\t')
145       *s2 = 0;
146     else
147       break;
148
149   if (! XParseColor (dpy, cmap, s, &color))
150     {
151       fprintf (stderr, "%s: can't parse color %s", progname, s);
152       ok = False;
153       goto DEFAULT;
154     }
155   if (! XAllocColor (dpy, cmap, &color))
156     {
157       fprintf (stderr, "%s: couldn't allocate color %s", progname, s);
158       ok = False;
159       goto DEFAULT;
160     }
161   free (s);
162   return color.pixel;
163  DEFAULT:
164   if (s) free (s);
165
166   {
167     Bool black_p = (strlen(res_class) >= 10 &&
168                     !strcasecmp ("Background",
169                                  res_class + strlen(res_class) - 10));
170     if (!ok)
171       fprintf (stderr, ": using %s.\n", (black_p ? "black" : "white"));
172     color.flags = DoRed|DoGreen|DoBlue;
173     color.red = color.green = color.blue = (black_p ? 0 : 0xFFFF);
174     if (XAllocColor (dpy, cmap, &color))
175       return color.pixel;
176     else
177       {
178         fprintf (stderr, "%s: couldn't allocate %s either!\n", progname,
179                  (black_p ? "black" : "white"));
180         /* We can't use BlackPixel/WhitePixel here, because we don't know
181            what screen we're allocating on (only an issue when running inside
182            the xscreensaver daemon: for hacks, DefaultScreen is fine.)
183          */
184         return 0;
185       }
186   }
187 }
188
189
190 int
191 parse_time (const char *string, Bool seconds_default_p, Bool silent_p)
192 {
193   unsigned int h, m, s;
194   char c;
195   if (3 == sscanf (string,   " %u : %2u : %2u %c", &h, &m, &s, &c))
196     ;
197   else if (2 == sscanf (string, " : %2u : %2u %c", &m, &s, &c) ||
198            2 == sscanf (string,    " %u : %2u %c", &m, &s, &c))
199     h = 0;
200   else if (1 == sscanf (string,       " : %2u %c", &s, &c))
201     h = m = 0;
202   else if (1 == sscanf (string,          " %u %c",
203                         (seconds_default_p ? &s : &m), &c))
204     {
205       h = 0;
206       if (seconds_default_p) m = 0;
207       else s = 0;
208     }
209   else
210     {
211       if (! silent_p)
212         fprintf (stderr, "%s: invalid time interval specification \"%s\".\n",
213                  progname, string);
214       return -1;
215     }
216   if (s >= 60 && (h != 0 || m != 0))
217     {
218       if (! silent_p)
219         fprintf (stderr, "%s: seconds > 59 in \"%s\".\n", progname, string);
220       return -1;
221     }
222   if (m >= 60 && h > 0)
223     {
224       if (! silent_p)
225         fprintf (stderr, "%s: minutes > 59 in \"%s\".\n", progname, string);
226       return -1;
227     }
228   return ((h * 60 * 60) + (m * 60) + s);
229 }
230
231 static unsigned int 
232 get_time_resource (char *res_name, char *res_class, Bool sec_p)
233 {
234   int val;
235   char *s = get_string_resource (res_name, res_class);
236   if (!s) return 0;
237   val = parse_time (s, sec_p, False);
238   free (s);
239   return (val < 0 ? 0 : val);
240 }
241
242 unsigned int 
243 get_seconds_resource (char *res_name, char *res_class)
244 {
245   return get_time_resource (res_name, res_class, True);
246 }
247
248 unsigned int 
249 get_minutes_resource (char *res_name, char *res_class)
250 {
251   return get_time_resource (res_name, res_class, False);
252 }