WE DONT USE BASE DISPLAY FOR ANYTHING ANY MORE!!@^!*@*!! YAY
[dana/openbox.git] / src / configuration.cc
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2
3 #ifdef    HAVE_CONFIG_H
4 #include "../config.h"
5 #endif // HAVE_CONFIG_H
6
7 extern "C" {
8 #ifdef    HAVE_STDLIB_H
9 #  include <stdlib.h>
10 #endif // HAVE_STDLIB_H
11 }
12
13 #include "configuration.hh"
14 #include "util.hh"
15
16 #include <algorithm>
17
18 using std::string;
19
20 namespace ob {
21
22 bool Configuration::_initialized = False;
23
24 Configuration::Configuration(const string &file, bool autosave) {
25   setFile(file);
26   _modified = False;
27   _database = NULL;
28   _autosave = autosave;
29   if (! _initialized) {
30     XrmInitialize();
31     _initialized = True;
32   }
33 }
34
35 Configuration::Configuration(bool autosave) {
36   _modified = False;
37   _database = NULL;
38   _autosave = autosave;
39   if (! _initialized) {
40     XrmInitialize();
41     _initialized = True;
42   }
43 }
44
45 Configuration::~Configuration() {
46   if (_database != NULL)
47     XrmDestroyDatabase(_database);
48 }
49
50 void Configuration::setFile(const string &file) {
51   _file = file;
52 }
53
54 void Configuration::setAutoSave(bool autosave) {
55   _autosave = autosave;
56 }
57
58 void Configuration::save() {
59   assert(_database != NULL);
60   XrmPutFileDatabase(_database, _file.c_str());
61   _modified = False;
62 }
63
64 bool Configuration::load() {
65   if (_database != NULL)
66     XrmDestroyDatabase(_database);
67   _modified = False;
68   if (NULL == (_database = XrmGetFileDatabase(_file.c_str())))
69     return False;
70   return True;
71 }
72
73 bool Configuration::merge(const string &file, bool overwrite) {
74   if (XrmCombineFileDatabase(file.c_str(), &_database, overwrite) == 0)
75     return False;
76   _modified = True;
77   if (_autosave)
78     save();
79   return True;
80 }
81
82 void Configuration::create() {
83   if (_database != NULL)
84     XrmDestroyDatabase(_database);
85   _modified = False;
86   assert(NULL != (_database = XrmGetStringDatabase("")));
87 }
88
89 void Configuration::setValue(const string &rname, bool value) {
90   assert(_database != NULL);
91
92   const char *val = (value ? "True" : "False");
93   string rc_string = rname + ": " + val;
94   XrmPutLineResource(&_database, rc_string.c_str());
95
96   _modified = True;
97   if (_autosave)
98     save();
99 }
100
101 void Configuration::setValue(const string &rname, unsigned long value) {
102   assert(_database != NULL);
103   
104   string rc_string = rname + ": " + itostring(value);
105   XrmPutLineResource(&_database, rc_string.c_str());
106
107   _modified = True;
108   if (_autosave)
109     save();
110 }
111
112 void Configuration::setValue(const string &rname, long value) {
113   assert(_database != NULL);
114   
115   string rc_string = rname + ": " + itostring(value);
116   XrmPutLineResource(&_database, rc_string.c_str());
117
118   _modified = True;
119   if (_autosave)
120     save();
121 }
122
123 void Configuration::setValue(const string &rname, const char *value) {
124   assert(_database != NULL);
125   assert(value != NULL);
126   
127   string rc_string = rname + ": " + value;
128   XrmPutLineResource(&_database, rc_string.c_str());
129
130   _modified = True;
131   if (_autosave)
132     save();
133 }
134
135 void Configuration::setValue(const string &rname, const string &value) {
136   assert(_database != NULL);
137   
138   string rc_string = rname + ": " + value;
139   XrmPutLineResource(&_database, rc_string.c_str());
140
141   _modified = True;
142   if (_autosave)
143     save();
144 }
145
146 bool Configuration::getValue(const string &rname, bool &value) const {
147   assert(_database != NULL);
148   
149   string rclass = createClassName(rname);
150   
151   char *rettype;
152   XrmValue retvalue;
153   if (0 == XrmGetResource(_database, rname.c_str(), rclass.c_str(), 
154                           &rettype, &retvalue) || retvalue.addr == NULL)
155     return False;
156   string val = retvalue.addr;
157   if (val == "True" || val == "True")
158     value = True;
159   else
160     value = False;
161   return True;
162 }
163
164 bool Configuration::getValue(const string &rname, long &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   char *end;
175   value = strtol(retvalue.addr, &end, 10);
176   if (end == retvalue.addr)
177     return False;
178   return True;
179 }
180
181 bool Configuration::getValue(const string &rname, unsigned long &value) const {
182   assert(_database != NULL);
183   
184   string rclass = createClassName(rname);
185   
186   char *rettype;
187   XrmValue retvalue;
188   if (0 == XrmGetResource(_database, rname.c_str(), rclass.c_str(), 
189                           &rettype, &retvalue) || retvalue.addr == NULL)
190     return False;
191   char *end;
192   value = strtoul(retvalue.addr, &end, 10);
193   if (end == retvalue.addr)
194     return False;
195   return True;
196 }
197
198 bool Configuration::getValue(const string &rname,
199                              string &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   value = retvalue.addr;
210   return True;
211 }
212   
213
214 string Configuration::createClassName(const string &rname) const {
215   string rclass(rname);
216
217   string::iterator it = rclass.begin(), end = rclass.end();
218   while (True) {
219     *it = toUpper(*it);
220     ++it;
221     if (it == end) break;
222     it = std::find(it, rclass.end(), '.');
223     if (it == end) break;
224     ++it;
225     if (it == end) break;
226   }
227   return rclass;
228 }
229   
230
231 char Configuration::toUpper(char c) const {
232   if (c >= 'a' && c <= 'z')
233     return c - 'a' + 'A';
234   return c;
235 }
236
237 }