0.51.1 pre snapshot. Be careful, it may be buggy. It fixes some bugs though.
[wmaker-crm.git] / WINGs / userdefaults.c
blobc97dbd6259480de3613117bf1b32e6afa4fe50cf
2 #include <stdlib.h>
3 #include <strings.h>
4 #include <stdio.h>
5 #include <assert.h>
8 #include "../src/config.h"
10 #include "WUtil.h"
12 #include <proplist.h>
15 typedef struct W_UserDefaults {
16 proplist_t defaults;
18 proplist_t appDomain;
20 proplist_t searchListArray;
21 proplist_t *searchList; /* cache for searchListArray */
23 char dirty;
25 } UserDefaults;
28 static UserDefaults *sharedUserDefaults = NULL;
30 extern char *WMGetApplicationName();
32 #define DEFAULTS_DIR "/Defaults"
35 char*
36 wusergnusteppath()
38 char *path;
39 char *gspath;
40 int pathlen;
42 gspath = getenv("GNUSTEP_USER_ROOT");
43 if (gspath) {
44 gspath = wexpandpath(gspath);
45 pathlen = strlen(gspath) + 4;
46 path = wmalloc(pathlen);
47 strcpy(path, gspath);
48 free(gspath);
49 } else {
50 pathlen = strlen(wgethomedir()) + 10;
51 path = wmalloc(pathlen);
52 strcpy(path, wgethomedir());
53 strcat(path, "/GNUstep");
56 return path;
60 char*
61 wdefaultspathfordomain(char *domain)
63 char *path;
64 char *gspath;
66 gspath = wusergnusteppath();
67 path = wmalloc(strlen(gspath)+strlen(DEFAULTS_DIR)+strlen(domain)+4);
68 strcpy(path, gspath);
69 free(gspath);
70 strcat(path, DEFAULTS_DIR);
71 strcat(path, "/");
72 strcat(path, domain);
74 return path;
78 static void
79 #ifndef HAVE_ATEXIT
80 saveDefaultsChanges(int foo, void *bar)
81 #else
82 saveDefaultsChanges(void)
83 #endif
85 if (sharedUserDefaults && sharedUserDefaults->dirty) {
86 PLSave(sharedUserDefaults->appDomain, YES);
91 WMUserDefaults*
92 WMGetStandardUserDefaults(void)
94 if (!sharedUserDefaults) {
95 WMUserDefaults *defaults;
97 proplist_t domain;
98 proplist_t key;
99 char *path;
100 int i;
102 defaults = wmalloc(sizeof(WMUserDefaults));
103 memset(defaults, 0, sizeof(WMUserDefaults));
105 defaults->defaults = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
107 defaults->searchList = wmalloc(sizeof(proplist_t)*3);
109 /* application domain */
110 key = PLMakeString(WMGetApplicationName());
111 defaults->searchList[0] = key;
113 /* temporary kluge */
114 if (strcmp(WMGetApplicationName(), "WindowMaker")==0) {
115 domain = NULL;
116 path = NULL;
117 } else {
118 path = wdefaultspathfordomain(PLGetString(key));
120 domain = PLGetProplistWithPath(path);
122 if (!domain) {
123 proplist_t p;
125 domain = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
126 if (path) {
127 p = PLMakeString(path);
128 PLSetFilename(domain, p);
129 PLRelease(p);
132 if (path)
133 free(path);
135 defaults->appDomain = domain;
137 if (domain)
138 PLInsertDictionaryEntry(defaults->defaults, key, domain);
140 PLRelease(key);
142 /* global domain */
143 key = PLMakeString("WMGLOBAL");
144 defaults->searchList[1] = key;
146 path = wdefaultspathfordomain(PLGetString(key));
148 domain = PLGetProplistWithPath(path);
150 free(path);
152 if (!domain)
153 domain = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
155 if (domain)
156 PLInsertDictionaryEntry(defaults->defaults, key, domain);
158 PLRelease(key);
160 /* terminate list */
161 defaults->searchList[2] = NULL;
163 defaults->searchListArray=PLMakeArrayFromElements(NULL,NULL);
166 i = 0;
167 while (defaults->searchList[i]) {
168 PLAppendArrayElement(defaults->searchListArray,
169 defaults->searchList[i]);
170 i++;
173 sharedUserDefaults = defaults;
175 /* set to save changes in defaults when program is exited */
178 #ifndef HAVE_ATEXIT
179 on_exit(saveDefaultsChanges, (void*)NULL);
180 #else
181 atexit(saveDefaultsChanges);
182 #endif
185 return sharedUserDefaults;
190 proplist_t
191 WMGetUDObjectForKey(WMUserDefaults *database, char *defaultName)
193 proplist_t domainName, domain;
194 proplist_t object = NULL;
195 proplist_t key = PLMakeString(defaultName);
196 int i = 0;
198 while (database->searchList[i] && !object) {
199 domainName = database->searchList[i];
200 domain = PLGetDictionaryEntry(database->defaults, domainName);
201 if (domain) {
202 object = PLGetDictionaryEntry(domain, key);
204 i++;
206 PLRelease(key);
208 return object;
212 void
213 WMSetUDObjectForKey(WMUserDefaults *database, proplist_t object,
214 char *defaultName)
216 proplist_t key = PLMakeString(defaultName);
218 database->dirty = 1;
220 PLInsertDictionaryEntry(database->appDomain, key, object);
221 PLRelease(key);
225 void
226 WMRemoveUDObjectForKey(WMUserDefaults *database, char *defaultName)
228 proplist_t key = PLMakeString(defaultName);
230 database->dirty = 1;
232 PLRemoveDictionaryEntry(database->appDomain, key);
234 PLRelease(key);
238 char*
239 WMGetUDStringForKey(WMUserDefaults *database, char *defaultName)
241 proplist_t val;
243 val = WMGetUDObjectForKey(database, defaultName);
245 if (!val)
246 return NULL;
248 if (!PLIsString(val))
249 return NULL;
251 return wstrdup(PLGetString(val));
256 WMGetUDIntegerForKey(WMUserDefaults *database, char *defaultName)
258 proplist_t val;
259 char *str;
260 int value;
262 val = WMGetUDObjectForKey(database, defaultName);
264 if (!val)
265 return 0;
267 if (!PLIsString(val))
268 return 0;
270 str = PLGetString(val);
271 if (!str)
272 return 0;
274 if (sscanf(str, "%i", &value)!=1)
275 return 0;
277 return value;
282 float
283 WMGetUDFloatForKey(WMUserDefaults *database, char *defaultName)
285 proplist_t val;
286 char *str;
287 float value;
289 val = WMGetUDObjectForKey(database, defaultName);
291 if (!val || !PLIsString(val))
292 return 0.0;
294 if (!(str = PLGetString(val)))
295 return 0.0;
297 if (sscanf(str, "%f", &value)!=1)
298 return 0.0;
300 return value;
305 Bool
306 WMGetUDBoolForKey(WMUserDefaults *database, char *defaultName)
308 proplist_t val;
309 int value;
310 char *str;
312 val = WMGetUDObjectForKey(database, defaultName);
314 if (!val)
315 return False;
317 if (!PLIsString(val))
318 return False;
320 str = PLGetString(val);
321 if (!str)
322 return False;
324 if (sscanf(str, "%i", &value)==1 && value!=0)
325 return True;
327 if (strcasecmp(str, "YES")==0)
328 return True;
330 if (strcasecmp(str, "Y")==0)
331 return True;
333 return False;
337 void
338 WMSetUDIntegerForKey(WMUserDefaults *database, int value, char *defaultName)
340 proplist_t object;
341 char buffer[128];
343 sprintf(buffer, "%i", value);
344 object = PLMakeString(buffer);
346 WMSetUDObjectForKey(database, object, defaultName);
347 PLRelease(object);
353 void
354 WMSetUDStringForKey(WMUserDefaults *database, char *value, char *defaultName)
356 proplist_t object;
358 object = PLMakeString(value);
360 WMSetUDObjectForKey(database, object, defaultName);
361 PLRelease(object);
366 void
367 WMSetUDFloatForKey(WMUserDefaults *database, float value, char *defaultName)
369 proplist_t object;
370 char buffer[128];
372 sprintf(buffer, "%f", value);
373 object = PLMakeString(buffer);
375 WMSetUDObjectForKey(database, object, defaultName);
376 PLRelease(object);
381 void
382 WMSetUDBoolForKey(WMUserDefaults *database, Bool value, char *defaultName)
384 static proplist_t yes = NULL, no = NULL;
386 if (!yes) {
387 yes = PLMakeString("YES");
388 no = PLMakeString("NO");
391 WMSetUDObjectForKey(database, value ? yes : no, defaultName);
395 proplist_t
396 WMGetUDSearchList(WMUserDefaults *database)
398 return database->searchListArray;
402 void
403 WMSetUDSearchList(WMUserDefaults *database, proplist_t list)
405 int i, c;
407 if (database->searchList) {
408 i = 0;
409 while (database->searchList[i]) {
410 PLRelease(database->searchList[i]);
411 i++;
413 free(database->searchList);
415 if (database->searchListArray) {
416 PLRelease(database->searchListArray);
419 c = PLGetNumberOfElements(list);
420 database->searchList = wmalloc(sizeof(proplist_t)*(c+1));
422 for (i=0; i<c; i++) {
423 database->searchList[i] = PLGetArrayElement(list, i);
426 database->searchListArray = PLDeepCopy(list);