try make bootstrap work in one pass for other people..
[mikachu/openbox.git] / src / Configuration.cc
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2 // Configuration.hh for Blackbox - an X11 Window manager
3 // Copyright (c) 2002 - 2002 Ben Jansens (ben@orodu.net)
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a
6 // copy of this software and associated documentation files (the "Software"),
7 // to deal in the Software without restriction, including without limitation
8 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 // and/or sell copies of the Software, and to permit persons to whom the
10 // Software is furnished to do so, subject to the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 // DEALINGS IN THE SOFTWARE.
22
23 #ifdef    HAVE_CONFIG_H
24 #include "../config.h"
25 #endif // HAVE_CONFIG_H
26
27 extern "C" {
28 #ifdef    HAVE_STDLIB_H
29 #  include <stdlib.h>
30 #endif // HAVE_STDLIB_H
31 }
32
33 #include "Configuration.hh"
34 #include "Util.hh"
35
36 #include <algorithm>
37
38 using std::string;
39
40 bool Configuration::_initialized = False;
41
42 Configuration::Configuration(const string &file, bool autosave) {
43   setFile(file);
44   _modified = False;
45   _database = NULL;
46   _autosave = autosave;
47   if (! _initialized) {
48     XrmInitialize();
49     _initialized = True;
50   }
51 }
52
53 Configuration::Configuration(bool autosave) {
54   _modified = False;
55   _database = NULL;
56   _autosave = autosave;
57   if (! _initialized) {
58     XrmInitialize();
59     _initialized = True;
60   }
61 }
62
63 Configuration::~Configuration() {
64   if (_database != NULL)
65     XrmDestroyDatabase(_database);
66 }
67
68 void Configuration::setFile(const string &file) {
69   _file = file;
70 }
71
72 void Configuration::setAutoSave(bool autosave) {
73   _autosave = autosave;
74 }
75
76 void Configuration::save() {
77   assert(_database != NULL);
78   XrmPutFileDatabase(_database, _file.c_str());
79   _modified = False;
80 }
81
82 bool Configuration::load() {
83   if (_database != NULL)
84     XrmDestroyDatabase(_database);
85   _modified = False;
86   if (NULL == (_database = XrmGetFileDatabase(_file.c_str())))
87     return False;
88   return True;
89 }
90
91 bool Configuration::merge(const string &file, bool overwrite) {
92   if (XrmCombineFileDatabase(file.c_str(), &_database, overwrite) == 0)
93     return False;
94   _modified = True;
95   if (_autosave)
96     save();
97   return True;
98 }
99
100 void Configuration::create() {
101   if (_database != NULL)
102     XrmDestroyDatabase(_database);
103   _modified = False;
104   assert(NULL != (_database = XrmGetStringDatabase("")));
105 }
106
107 void Configuration::setValue(const string &rname, bool value) {
108   assert(_database != NULL);
109
110   const char *val = (value ? "True" : "False");
111   string rc_string = rname + ": " + val;
112   XrmPutLineResource(&_database, rc_string.c_str());
113
114   _modified = True;
115   if (_autosave)
116     save();
117 }
118
119 void Configuration::setValue(const string &rname, unsigned long value) {
120   assert(_database != NULL);
121   
122   string rc_string = rname + ": " + itostring(value);
123   XrmPutLineResource(&_database, rc_string.c_str());
124
125   _modified = True;
126   if (_autosave)
127     save();
128 }
129
130 void Configuration::setValue(const string &rname, long value) {
131   assert(_database != NULL);
132   
133   string rc_string = rname + ": " + itostring(value);
134   XrmPutLineResource(&_database, rc_string.c_str());
135
136   _modified = True;
137   if (_autosave)
138     save();
139 }
140
141 void Configuration::setValue(const string &rname, const char *value) {
142   assert(_database != NULL);
143   assert(value != NULL);
144   
145   string rc_string = rname + ": " + value;
146   XrmPutLineResource(&_database, rc_string.c_str());
147
148   _modified = True;
149   if (_autosave)
150     save();
151 }
152
153 void Configuration::setValue(const string &rname, const string &value) {
154   assert(_database != NULL);
155   
156   string rc_string = rname + ": " + value;
157   XrmPutLineResource(&_database, rc_string.c_str());
158
159   _modified = True;
160   if (_autosave)
161     save();
162 }
163
164 bool Configuration::getValue(const string &rname, bool &value) const {
165   assert(_database != NULL);
166   
167   string rclass = createClassName(rname);
168   
169   char *rettype;
170   XrmValue retvalue;
171   if (0 == XrmGetResource(_database, rname.c_str(), rclass.c_str(), 
172                           &rettype, &retvalue) || retvalue.addr == NULL)
173     return False;
174   string val = retvalue.addr;
175   if (val == "True" || val == "True")
176     value = True;
177   else
178     value = False;
179   return True;
180 }
181
182 bool Configuration::getValue(const string &rname, long &value) const {
183   assert(_database != NULL);
184   
185   string rclass = createClassName(rname);
186   
187   char *rettype;
188   XrmValue retvalue;
189   if (0 == XrmGetResource(_database, rname.c_str(), rclass.c_str(), 
190                           &rettype, &retvalue) || retvalue.addr == NULL)
191     return False;
192   char *end;
193   value = strtol(retvalue.addr, &end, 10);
194   if (end == retvalue.addr)
195     return False;
196   return True;
197 }
198
199 bool Configuration::getValue(const string &rname, unsigned long &value) const {
200   assert(_database != NULL);
201   
202   string rclass = createClassName(rname);
203   
204   char *rettype;
205   XrmValue retvalue;
206   if (0 == XrmGetResource(_database, rname.c_str(), rclass.c_str(), 
207                           &rettype, &retvalue) || retvalue.addr == NULL)
208     return False;
209   char *end;
210   value = strtoul(retvalue.addr, &end, 10);
211   if (end == retvalue.addr)
212     return False;
213   return True;
214 }
215
216 bool Configuration::getValue(const string &rname,
217                              string &value) const {
218   assert(_database != NULL);
219   
220   string rclass = createClassName(rname);
221   
222   char *rettype;
223   XrmValue retvalue;
224   if (0 == XrmGetResource(_database, rname.c_str(), rclass.c_str(), 
225                           &rettype, &retvalue) || retvalue.addr == NULL)
226     return False;
227   value = retvalue.addr;
228   return True;
229 }
230   
231
232 string Configuration::createClassName(const string &rname) const {
233   string rclass(rname);
234
235   string::iterator it = rclass.begin(), end = rclass.end();
236   while (True) {
237     *it = toUpper(*it);
238     ++it;
239     if (it == end) break;
240     it = std::find(it, rclass.end(), '.');
241     if (it == end) break;
242     ++it;
243     if (it == end) break;
244   }
245   return rclass;
246 }
247   
248
249 char Configuration::toUpper(char c) const {
250   if (c >= 'a' && c <= 'z')
251     return c - 'a' + 'A';
252   return c;
253 }