wmaker: remove useless null pointer check (Coverity #109612)
[wmaker-crm.git] / WPrefs.app / WPrefs.c
blobaf28a27d7a93b9cc32c0f7be159670c95f8379d7
1 /* WPrefs.c- main window and other basic stuff
3 * WPrefs - Window Maker Preferences Program
5 * Copyright (c) 1998-2003 Alfredo K. Kojima
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "config.h"
24 #include "WPrefs.h"
25 #include <assert.h>
27 #ifdef HAVE_STDNORETURN
28 #include <stdnoreturn.h>
29 #endif
32 #define MAX_SECTIONS 16
34 typedef struct _WPrefs {
35 WMWindow *win;
37 WMScrollView *scrollV;
38 WMFrame *buttonF;
39 WMButton *sectionB[MAX_SECTIONS];
41 int sectionCount;
43 WMButton *saveBtn;
44 WMButton *closeBtn;
45 WMButton *undoBtn;
46 WMButton *undosBtn;
48 WMButton *balloonBtn;
50 WMFrame *banner;
51 WMLabel *nameL;
52 WMLabel *versionL;
53 WMLabel *statusL;
55 Panel *currentPanel;
56 } _WPrefs;
58 static _WPrefs WPrefs;
60 /* system wide defaults dictionary. Read-only */
61 static WMPropList *GlobalDB = NULL;
62 /* user defaults dictionary */
63 static WMPropList *WindowMakerDB = NULL;
64 static char *WindowMakerDBPath = NULL;
66 static Bool TIFFOK = False;
68 #define INITIALIZED_PANEL (1<<0)
70 static void loadConfigurations(WMScreen * scr, WMWindow * mainw);
72 static void savePanelData(Panel * panel);
74 static void prepareForClose(void);
76 static noreturn void quit(WMWidget *w, void *data)
78 /* Parameter not used, but tell the compiler that it is ok */
79 (void) w;
80 (void) data;
82 prepareForClose();
84 WMReleaseApplication();
85 exit(0);
88 static void save(WMWidget * w, void *data)
90 int i;
91 WMPropList *p1, *p2;
92 WMPropList *keyList;
93 WMPropList *key;
94 XEvent ev;
96 /* Parameter not used, but tell the compiler that it is ok */
97 (void) data;
99 /* puts("gathering data"); */
100 for (i = 0; i < WPrefs.sectionCount; i++) {
101 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
102 if ((rec->callbacks.flags & INITIALIZED_PANEL))
103 savePanelData((Panel *) rec);
105 /* puts("compressing data"); */
106 /* compare the user dictionary with the global and remove redundant data */
107 keyList = WMGetPLDictionaryKeys(GlobalDB);
108 /* puts(WMGetPropListDescription(WindowMakerDB, False)); */
109 for (i = 0; i < WMGetPropListItemCount(keyList); i++) {
110 key = WMGetFromPLArray(keyList, i);
112 /* We don't have this value anyway, so no problem.
113 * Probably a new option */
114 p1 = WMGetFromPLDictionary(WindowMakerDB, key);
115 if (!p1)
116 continue;
117 /* The global doesn't have it, so no problem either. */
118 p2 = WMGetFromPLDictionary(GlobalDB, key);
119 if (!p2)
120 continue;
121 /* If both values are the same, don't save. */
122 if (WMIsPropListEqualTo(p1, p2))
123 WMRemoveFromPLDictionary(WindowMakerDB, key);
125 /* puts(WMGetPropListDescription(WindowMakerDB, False)); */
126 WMReleasePropList(keyList);
127 /* puts("storing data"); */
129 WMWritePropListToFile(WindowMakerDB, WindowMakerDBPath);
131 memset(&ev, 0, sizeof(XEvent));
133 ev.xclient.type = ClientMessage;
134 ev.xclient.message_type = XInternAtom(WMScreenDisplay(WMWidgetScreen(w)), "_WINDOWMAKER_COMMAND", False);
135 ev.xclient.window = DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w)));
136 ev.xclient.format = 8;
137 strncpy(ev.xclient.data.b, "Reconfigure", sizeof(ev.xclient.data.b));
139 XSendEvent(WMScreenDisplay(WMWidgetScreen(w)),
140 DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w))), False, SubstructureRedirectMask, &ev);
141 XFlush(WMScreenDisplay(WMWidgetScreen(w)));
144 static void undo(WMWidget * w, void *data)
146 PanelRec *rec = (PanelRec *) WPrefs.currentPanel;
148 /* Parameter not used, but tell the compiler that it is ok */
149 (void) w;
150 (void) data;
152 if (!rec)
153 return;
155 if (rec->callbacks.undoChanges && (rec->callbacks.flags & INITIALIZED_PANEL)) {
156 (*rec->callbacks.undoChanges) (WPrefs.currentPanel);
160 static void undoAll(WMWidget * w, void *data)
162 int i;
164 /* Parameter not used, but tell the compiler that it is ok */
165 (void) w;
166 (void) data;
168 for (i = 0; i < WPrefs.sectionCount; i++) {
169 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
171 if (rec->callbacks.undoChanges && (rec->callbacks.flags & INITIALIZED_PANEL))
172 (*rec->callbacks.undoChanges) ((Panel *) rec);
176 static void prepareForClose(void)
178 int i;
180 for (i = 0; i < WPrefs.sectionCount; i++) {
181 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
183 if (rec->callbacks.prepareForClose && (rec->callbacks.flags & INITIALIZED_PANEL))
184 (*rec->callbacks.prepareForClose) ((Panel *) rec);
188 static void toggleBalloons(WMWidget *w, void *data)
190 WMUserDefaults *udb = WMGetStandardUserDefaults();
191 Bool flag;
193 /* Parameter not used, but tell the compiler that it is ok */
194 (void) w;
195 (void) data;
197 flag = WMGetButtonSelected(WPrefs.balloonBtn);
199 WMSetBalloonEnabled(WMWidgetScreen(WPrefs.win), flag);
201 WMSetUDBoolForKey(udb, flag, "BalloonHelp");
204 static void createMainWindow(WMScreen * scr)
206 WMScroller *scroller;
207 WMFont *font;
208 char buffer[128];
210 WPrefs.win = WMCreateWindow(scr, "wprefs");
211 WMResizeWidget(WPrefs.win, 520, 390);
212 WMSetWindowTitle(WPrefs.win, _("Window Maker Preferences"));
213 WMSetWindowCloseAction(WPrefs.win, quit, NULL);
214 WMSetWindowMaxSize(WPrefs.win, 520, 390);
215 WMSetWindowMinSize(WPrefs.win, 520, 390);
216 WMSetWindowMiniwindowTitle(WPrefs.win, _("Preferences"));
218 WPrefs.scrollV = WMCreateScrollView(WPrefs.win);
219 WMResizeWidget(WPrefs.scrollV, 500, 87);
220 WMMoveWidget(WPrefs.scrollV, 10, 10);
221 WMSetScrollViewRelief(WPrefs.scrollV, WRSunken);
222 WMSetScrollViewHasHorizontalScroller(WPrefs.scrollV, True);
223 WMSetScrollViewHasVerticalScroller(WPrefs.scrollV, False);
224 scroller = WMGetScrollViewHorizontalScroller(WPrefs.scrollV);
225 WMSetScrollerArrowsPosition(scroller, WSANone);
227 WPrefs.buttonF = WMCreateFrame(WPrefs.win);
228 WMSetFrameRelief(WPrefs.buttonF, WRFlat);
230 WMSetScrollViewContentView(WPrefs.scrollV, WMWidgetView(WPrefs.buttonF));
232 WPrefs.undosBtn = WMCreateCommandButton(WPrefs.win);
233 WMResizeWidget(WPrefs.undosBtn, 90, 28);
234 WMMoveWidget(WPrefs.undosBtn, 135, 350);
235 WMSetButtonText(WPrefs.undosBtn, _("Revert Page"));
236 WMSetButtonAction(WPrefs.undosBtn, undo, NULL);
238 WPrefs.undoBtn = WMCreateCommandButton(WPrefs.win);
239 WMResizeWidget(WPrefs.undoBtn, 90, 28);
240 WMMoveWidget(WPrefs.undoBtn, 235, 350);
241 WMSetButtonText(WPrefs.undoBtn, _("Revert All"));
242 WMSetButtonAction(WPrefs.undoBtn, undoAll, NULL);
244 WPrefs.saveBtn = WMCreateCommandButton(WPrefs.win);
245 WMResizeWidget(WPrefs.saveBtn, 80, 28);
246 WMMoveWidget(WPrefs.saveBtn, 335, 350);
247 WMSetButtonText(WPrefs.saveBtn, _("Save"));
248 WMSetButtonAction(WPrefs.saveBtn, save, NULL);
250 WPrefs.closeBtn = WMCreateCommandButton(WPrefs.win);
251 WMResizeWidget(WPrefs.closeBtn, 80, 28);
252 WMMoveWidget(WPrefs.closeBtn, 425, 350);
253 WMSetButtonText(WPrefs.closeBtn, _("Close"));
254 WMSetButtonAction(WPrefs.closeBtn, quit, NULL);
256 WPrefs.balloonBtn = WMCreateSwitchButton(WPrefs.win);
257 WMResizeWidget(WPrefs.balloonBtn, 200, 28);
258 WMMoveWidget(WPrefs.balloonBtn, 15, 350);
259 WMSetButtonText(WPrefs.balloonBtn, _("Balloon Help"));
260 WMSetButtonAction(WPrefs.balloonBtn, toggleBalloons, NULL);
262 WMUserDefaults *udb = WMGetStandardUserDefaults();
263 Bool flag = WMGetUDBoolForKey(udb, "BalloonHelp");
265 WMSetButtonSelected(WPrefs.balloonBtn, flag);
266 WMSetBalloonEnabled(scr, flag);
269 /* banner */
270 WPrefs.banner = WMCreateFrame(WPrefs.win);
271 WMResizeWidget(WPrefs.banner, FRAME_WIDTH, FRAME_HEIGHT);
272 WMMoveWidget(WPrefs.banner, FRAME_LEFT, FRAME_TOP);
273 WMSetFrameRelief(WPrefs.banner, WRFlat);
275 font = WMCreateFont(scr, "Lucida Sans,URW Gothic L,Times New Roman,serif"
276 ":bold:pixelsize=26:antialias=true");
277 WPrefs.nameL = WMCreateLabel(WPrefs.banner);
278 WMSetLabelTextAlignment(WPrefs.nameL, WACenter);
279 WMResizeWidget(WPrefs.nameL, FRAME_WIDTH - 20, 60);
280 WMMoveWidget(WPrefs.nameL, 10, 50);
281 WMSetLabelFont(WPrefs.nameL, font);
282 WMSetLabelText(WPrefs.nameL, _("Window Maker Preferences"));
283 WMReleaseFont(font);
285 WPrefs.versionL = WMCreateLabel(WPrefs.banner);
286 WMResizeWidget(WPrefs.versionL, FRAME_WIDTH - 20, 20);
287 WMMoveWidget(WPrefs.versionL, 10, 120);
288 WMSetLabelTextAlignment(WPrefs.versionL, WACenter);
289 sprintf(buffer, _("Version %s"), VERSION);
290 WMSetLabelText(WPrefs.versionL, buffer);
292 WPrefs.statusL = WMCreateLabel(WPrefs.banner);
293 WMResizeWidget(WPrefs.statusL, FRAME_WIDTH - 20, 60);
294 WMMoveWidget(WPrefs.statusL, 10, 150);
295 WMSetLabelTextAlignment(WPrefs.statusL, WACenter);
296 WMSetLabelText(WPrefs.statusL, _("Starting..."));
298 WMMapSubwidgets(WPrefs.win);
300 WMUnmapWidget(WPrefs.undosBtn);
301 WMUnmapWidget(WPrefs.undoBtn);
302 WMUnmapWidget(WPrefs.saveBtn);
305 static void showPanel(Panel * panel)
307 PanelRec *rec = (PanelRec *) panel;
309 if (!(rec->callbacks.flags & INITIALIZED_PANEL)) {
310 (*rec->callbacks.createWidgets) (panel);
311 rec->callbacks.flags |= INITIALIZED_PANEL;
314 WMSetWindowTitle(WPrefs.win, rec->sectionName);
316 if (rec->callbacks.showPanel)
317 (*rec->callbacks.showPanel) (panel);
319 WMMapWidget(rec->box);
322 static void hidePanel(Panel * panel)
324 PanelRec *rec = (PanelRec *) panel;
326 WMUnmapWidget(rec->box);
328 if (rec->callbacks.hidePanel)
329 (*rec->callbacks.hidePanel) (panel);
332 static void savePanelData(Panel * panel)
334 PanelRec *rec = (PanelRec *) panel;
336 if (rec->callbacks.updateDomain) {
337 (*rec->callbacks.updateDomain) (panel);
341 static void changeSection(WMWidget * self, void *data)
343 /* Parameter not used, but tell the compiler that it is ok */
344 (void) self;
346 if (WPrefs.currentPanel == data)
347 return;
349 if (WPrefs.currentPanel == NULL) {
350 WMDestroyWidget(WPrefs.nameL);
351 WMDestroyWidget(WPrefs.versionL);
352 WMDestroyWidget(WPrefs.statusL);
354 WMSetFrameRelief(WPrefs.banner, WRGroove);
356 /* WMMapWidget(WPrefs.undosBtn);
357 WMMapWidget(WPrefs.undoBtn);
359 WMMapWidget(WPrefs.saveBtn);
362 showPanel(data);
364 if (WPrefs.currentPanel)
365 hidePanel(WPrefs.currentPanel);
366 WPrefs.currentPanel = data;
369 char *LocateImage(const char *name)
371 char *path;
372 char *tmp = wmalloc(strlen(name) + 8);
374 if (TIFFOK) {
375 sprintf(tmp, "%s.tiff", name);
376 path = WMPathForResourceOfType(tmp, "tiff");
377 } else {
378 sprintf(tmp, "%s.xpm", name);
379 path = WMPathForResourceOfType(tmp, "xpm");
381 wfree(tmp);
382 if (!path) {
383 wwarning(_("could not locate image file %s"), name);
386 return path;
389 void CreateImages(WMScreen *scr, RContext *rc, RImage *xis, const char *file,
390 WMPixmap **icon_normal, WMPixmap **icon_greyed)
392 RImage *icon;
393 char *path;
394 RColor gray = { 0xae, 0xaa, 0xae, 0 };
396 path = LocateImage(file);
397 if (!path)
399 *icon_normal = NULL;
400 if (icon_greyed)
401 *icon_greyed = NULL;
402 return;
405 *icon_normal = WMCreatePixmapFromFile(scr, path);
406 if (!*icon_normal)
408 wwarning(_("could not load icon %s"), path);
409 if (icon_greyed)
410 *icon_greyed = NULL;
411 wfree(path);
412 return;
415 if (!icon_greyed) // Greyed-out version not requested, we are done
417 wfree(path);
418 return;
421 icon = RLoadImage(rc, path, 0);
422 if (!icon)
424 wwarning(_("could not load icon %s"), path);
425 *icon_greyed = NULL;
426 wfree(path);
427 return;
429 RCombineImageWithColor(icon, &gray);
430 if (xis)
432 RCombineImagesWithOpaqueness(icon, xis, 180);
434 *icon_greyed = WMCreatePixmapFromRImage(scr, icon, 127);
435 if (!*icon_greyed)
437 wwarning(_("could not process icon %s: %s"), path, RMessageForError(RErrorCode));
439 RReleaseImage(icon);
440 wfree(path);
444 void SetButtonAlphaImage(WMScreen *scr, WMButton *bPtr, const char *file)
446 WMPixmap *icon;
447 RColor color;
448 char *iconPath;
450 iconPath = LocateImage(file);
452 color.red = 0xae;
453 color.green = 0xaa;
454 color.blue = 0xae;
455 color.alpha = 0;
456 if (iconPath) {
457 icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
458 if (!icon)
459 wwarning(_("could not load icon file %s"), iconPath);
460 } else {
461 icon = NULL;
464 WMSetButtonImage(bPtr, icon);
466 color.red = 0xff;
467 color.green = 0xff;
468 color.blue = 0xff;
469 color.alpha = 0;
470 if (iconPath) {
471 icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
472 if (!icon)
473 wwarning(_("could not load icon file %s"), iconPath);
474 } else {
475 icon = NULL;
478 WMSetButtonAltImage(bPtr, icon);
480 if (icon)
481 WMReleasePixmap(icon);
483 if (iconPath)
484 wfree(iconPath);
487 void AddSection(Panel * panel, const char *iconFile)
489 WMButton *bPtr;
491 assert(WPrefs.sectionCount < MAX_SECTIONS);
493 bPtr = WMCreateCustomButton(WPrefs.buttonF, WBBStateLightMask | WBBStateChangeMask);
494 WMResizeWidget(bPtr, 64, 64);
495 WMMoveWidget(bPtr, WPrefs.sectionCount * 64, 0);
496 WMSetButtonImagePosition(bPtr, WIPImageOnly);
497 WMSetButtonAction(bPtr, changeSection, panel);
498 WMHangData(bPtr, panel);
500 WMSetBalloonTextForView(((PanelRec *) panel)->description, WMWidgetView(bPtr));
501 SetButtonAlphaImage(WMWidgetScreen(bPtr), bPtr, iconFile);
502 WMMapWidget(bPtr);
504 WPrefs.sectionB[WPrefs.sectionCount] = bPtr;
506 if (WPrefs.sectionCount > 0)
507 WMGroupButtons(WPrefs.sectionB[0], bPtr);
509 WPrefs.sectionCount++;
511 WMResizeWidget(WPrefs.buttonF, WPrefs.sectionCount * 64, 64);
514 void Initialize(WMScreen * scr)
516 char **list;
517 int i;
518 char *path;
520 list = RSupportedFileFormats();
521 for (i = 0; list[i] != NULL; i++) {
522 if (strcmp(list[i], "TIFF") == 0) {
523 TIFFOK = True;
524 break;
528 if (TIFFOK)
529 path = WMPathForResourceOfType("WPrefs.tiff", NULL);
530 else
531 path = WMPathForResourceOfType("WPrefs.xpm", NULL);
532 if (path) {
533 RImage *tmp;
535 tmp = RLoadImage(WMScreenRContext(scr), path, 0);
536 if (!tmp) {
537 wwarning(_("could not load image file %s:%s"), path, RMessageForError(RErrorCode));
538 } else {
539 WMSetApplicationIconImage(scr, tmp);
540 RReleaseImage(tmp);
542 wfree(path);
545 memset(&WPrefs, 0, sizeof(_WPrefs));
546 createMainWindow(scr);
548 WMRealizeWidget(WPrefs.win);
550 WMSetWindowMiniwindowImage(WPrefs.win, WMGetApplicationIconImage(scr));
552 WMMapWidget(WPrefs.win);
553 XFlush(WMScreenDisplay(scr));
554 WMSetLabelText(WPrefs.statusL, _("Loading Window Maker configuration files..."));
555 XFlush(WMScreenDisplay(scr));
556 loadConfigurations(scr, WPrefs.win);
558 WMSetLabelText(WPrefs.statusL, _("Initializing configuration panels..."));
560 InitFocus(WPrefs.banner);
561 InitWindowHandling(WPrefs.banner);
563 InitMenuPreferences(WPrefs.banner);
564 InitIcons(WPrefs.banner);
565 InitPreferences(WPrefs.banner);
567 InitPaths(WPrefs.banner);
568 InitDocks(WPrefs.banner);
569 InitWorkspace(WPrefs.banner);
570 InitConfigurations(WPrefs.banner);
572 InitMenu(WPrefs.banner);
574 #ifdef not_yet_fully_implemented
575 InitKeyboardSettings(WPrefs.banner);
576 #endif
577 InitKeyboardShortcuts(WPrefs.banner);
578 InitMouseSettings(WPrefs.banner);
580 InitAppearance(WPrefs.banner);
582 InitFontSimple(WPrefs.banner);
584 #ifdef not_yet_fully_implemented
585 InitThemes(WPrefs.banner);
586 #endif
587 InitExpert(WPrefs.banner);
589 WMRealizeWidget(WPrefs.scrollV);
591 WMSetLabelText(WPrefs.statusL, "");
594 WMWindow *GetWindow(void)
596 return WPrefs.win;
599 static void loadConfigurations(WMScreen * scr, WMWindow * mainw)
601 WMPropList *db, *gdb;
602 char *path;
603 FILE *file;
604 char buffer[1024];
605 char mbuf[1024];
606 int v1, v2, v3;
608 path = wdefaultspathfordomain("WindowMaker");
609 WindowMakerDBPath = path;
611 db = WMReadPropListFromFile(path);
612 if (db) {
613 if (!WMIsPLDictionary(db)) {
614 WMReleasePropList(db);
615 db = NULL;
616 sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), path);
617 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
619 } else {
620 sprintf(mbuf, _("Could not load Window Maker domain (%s) from defaults database."), path);
621 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
624 path = getenv("WMAKER_BIN_NAME");
625 if (!path)
626 path = "wmaker";
628 char *command;
630 command = wstrconcat(path, " --version");
631 file = popen(command, "r");
632 wfree(command);
634 if (!file || !fgets(buffer, 1023, file)) {
635 werror(_("could not extract version information from Window Maker"));
636 wfatal(_("Make sure wmaker is in your search path."));
638 WMRunAlertPanel(scr, mainw, _("Error"),
640 ("Could not extract version from Window Maker. Make sure it is correctly installed and is in your PATH environment variable."),
641 _("OK"), NULL, NULL);
642 exit(1);
644 if (file)
645 pclose(file);
647 if (sscanf(buffer, "Window Maker %i.%i.%i", &v1, &v2, &v3) != 3
648 && sscanf(buffer, "WindowMaker %i.%i.%i", &v1, &v2, &v3) != 3) {
649 WMRunAlertPanel(scr, mainw, _("Error"),
650 _("Could not extract version from Window Maker. "
651 "Make sure it is correctly installed and the path "
652 "where it installed is in the PATH environment "
653 "variable."), _("OK"), NULL, NULL);
654 exit(1);
656 if (v1 == 0 && (v2 < 18 || v3 < 0)) {
657 sprintf(mbuf, _("WPrefs only supports Window Maker 0.18.0 or newer.\n"
658 "The version installed is %i.%i.%i\n"), v1, v2, v3);
659 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
660 exit(1);
663 if (v1 > 1 || (v1 == 1 && (v2 > 0))) {
664 sprintf(mbuf,
666 ("Window Maker %i.%i.%i, which is installed in your system, is not fully supported by this version of WPrefs."),
667 v1, v2, v3);
668 WMRunAlertPanel(scr, mainw, _("Warning"), mbuf, _("OK"), NULL, NULL);
672 char *command;
674 command = wstrconcat(path, " --global_defaults_path");
675 file = popen(command, "r");
676 wfree(command);
678 if (!file || !fgets(buffer, 1023, file)) {
679 werror(_("could not run \"%s --global_defaults_path\"."), path);
680 exit(1);
681 } else {
682 char *ptr;
683 ptr = strchr(buffer, '\n');
684 if (ptr)
685 *ptr = 0;
686 strcat(buffer, "/WindowMaker");
689 if (file)
690 pclose(file);
692 gdb = WMReadPropListFromFile(buffer);
694 if (gdb) {
695 if (!WMIsPLDictionary(gdb)) {
696 WMReleasePropList(gdb);
697 gdb = NULL;
698 sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), buffer);
699 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
701 } else {
702 sprintf(mbuf, _("Could not load global Window Maker domain (%s)."), buffer);
703 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
706 if (!db) {
707 db = WMCreatePLDictionary(NULL, NULL);
709 if (!gdb) {
710 gdb = WMCreatePLDictionary(NULL, NULL);
713 GlobalDB = gdb;
715 WindowMakerDB = db;
718 WMPropList *GetObjectForKey(const char *defaultName)
720 WMPropList *object = NULL;
721 WMPropList *key = WMCreatePLString(defaultName);
723 object = WMGetFromPLDictionary(WindowMakerDB, key);
724 if (!object)
725 object = WMGetFromPLDictionary(GlobalDB, key);
727 WMReleasePropList(key);
729 return object;
732 void SetObjectForKey(WMPropList * object, const char *defaultName)
734 WMPropList *key = WMCreatePLString(defaultName);
736 WMPutInPLDictionary(WindowMakerDB, key, object);
737 WMReleasePropList(key);
740 void RemoveObjectForKey(const char *defaultName)
742 WMPropList *key = WMCreatePLString(defaultName);
744 WMRemoveFromPLDictionary(WindowMakerDB, key);
746 WMReleasePropList(key);
749 char *GetStringForKey(const char *defaultName)
751 WMPropList *val;
753 val = GetObjectForKey(defaultName);
755 if (!val)
756 return NULL;
758 if (!WMIsPLString(val))
759 return NULL;
761 return WMGetFromPLString(val);
764 WMPropList *GetArrayForKey(const char *defaultName)
766 WMPropList *val;
768 val = GetObjectForKey(defaultName);
770 if (!val)
771 return NULL;
773 if (!WMIsPLArray(val))
774 return NULL;
776 return val;
779 WMPropList *GetDictionaryForKey(const char *defaultName)
781 WMPropList *val;
783 val = GetObjectForKey(defaultName);
785 if (!val)
786 return NULL;
788 if (!WMIsPLDictionary(val))
789 return NULL;
791 return val;
794 int GetIntegerForKey(const char *defaultName)
796 WMPropList *val;
797 char *str;
798 int value;
800 val = GetObjectForKey(defaultName);
802 if (!val)
803 return 0;
805 if (!WMIsPLString(val))
806 return 0;
808 str = WMGetFromPLString(val);
809 if (!str)
810 return 0;
812 if (sscanf(str, "%i", &value) != 1)
813 return 0;
815 return value;
818 Bool GetBoolForKey(const char *defaultName)
820 int value;
821 char *str;
823 str = GetStringForKey(defaultName);
825 if (!str)
826 return False;
828 if (sscanf(str, "%i", &value) == 1 && value != 0)
829 return True;
831 if (strcasecmp(str, "YES") == 0)
832 return True;
834 if (strcasecmp(str, "Y") == 0)
835 return True;
837 return False;
840 void SetIntegerForKey(int value, const char *defaultName)
842 WMPropList *object;
843 char buffer[128];
845 sprintf(buffer, "%i", value);
846 object = WMCreatePLString(buffer);
848 SetObjectForKey(object, defaultName);
849 WMReleasePropList(object);
852 void SetStringForKey(const char *value, const char *defaultName)
854 WMPropList *object;
856 object = WMCreatePLString(value);
858 SetObjectForKey(object, defaultName);
859 WMReleasePropList(object);
862 void SetBoolForKey(Bool value, const char *defaultName)
864 static WMPropList *yes = NULL, *no = NULL;
866 if (!yes) {
867 yes = WMCreatePLString("YES");
868 no = WMCreatePLString("NO");
871 SetObjectForKey(value ? yes : no, defaultName);
874 void SetSpeedForKey(int speed, const char *defaultName)
876 char *str;
878 switch (speed) {
879 case 0:
880 str = "ultraslow";
881 break;
882 case 1:
883 str = "slow";
884 break;
885 case 2:
886 str = "medium";
887 break;
888 case 3:
889 str = "fast";
890 break;
891 case 4:
892 str = "ultrafast";
893 break;
894 default:
895 str = NULL;
898 if (str)
899 SetStringForKey(str, defaultName);
902 int GetSpeedForKey(const char *defaultName)
904 char *str;
905 int i;
907 str = GetStringForKey(defaultName);
908 if (!str)
909 return 2;
911 if (strcasecmp(str, "ultraslow") == 0)
912 i = 0;
913 else if (strcasecmp(str, "slow") == 0)
914 i = 1;
915 else if (strcasecmp(str, "medium") == 0)
916 i = 2;
917 else if (strcasecmp(str, "fast") == 0)
918 i = 3;
919 else if (strcasecmp(str, "ultrafast") == 0)
920 i = 4;
921 else {
922 wwarning(_("bad speed value for option %s; using default Medium"), defaultName);
923 i = 2;
925 return i;