GetWindow function, argument not used
[wmaker-crm.git] / WPrefs.app / WPrefs.c
blobde59cdfa93e1703e7556430f9cd3f1f038e8ee79
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 ICON_TITLE_FONT "sans serif:pixelsize=9"
33 #define ICON_TITLE_VFONT "sans serif:pixelsize=9:weight=100"
35 #define MAX_SECTIONS 16
37 typedef struct _WPrefs {
38 WMWindow *win;
40 WMScrollView *scrollV;
41 WMFrame *buttonF;
42 WMButton *sectionB[MAX_SECTIONS];
44 int sectionCount;
46 WMButton *saveBtn;
47 WMButton *closeBtn;
48 WMButton *undoBtn;
49 WMButton *undosBtn;
51 WMButton *balloonBtn;
53 WMFrame *banner;
54 WMLabel *nameL;
55 WMLabel *versionL;
56 WMLabel *statusL;
58 Panel *currentPanel;
59 } _WPrefs;
61 static _WPrefs WPrefs;
63 /* system wide defaults dictionary. Read-only */
64 static WMPropList *GlobalDB = NULL;
65 /* user defaults dictionary */
66 static WMPropList *WindowMakerDB = NULL;
67 static char *WindowMakerDBPath = NULL;
69 static Bool TIFFOK = False;
71 #define INITIALIZED_PANEL (1<<0)
73 static void loadConfigurations(WMScreen * scr, WMWindow * mainw);
75 static void savePanelData(Panel * panel);
77 static void prepareForClose(void);
79 static noreturn void quit(WMWidget *w, void *data)
81 /* Parameter not used, but tell the compiler that it is ok */
82 (void) w;
83 (void) data;
85 prepareForClose();
87 exit(0);
90 static void save(WMWidget * w, void *data)
92 int i;
93 WMPropList *p1, *p2;
94 WMPropList *keyList;
95 WMPropList *key;
96 XEvent ev;
98 /* Parameter not used, but tell the compiler that it is ok */
99 (void) data;
101 /* puts("gathering data"); */
102 for (i = 0; i < WPrefs.sectionCount; i++) {
103 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
104 if ((rec->callbacks.flags & INITIALIZED_PANEL))
105 savePanelData((Panel *) rec);
107 /* puts("compressing data"); */
108 /* compare the user dictionary with the global and remove redundant data */
109 keyList = WMGetPLDictionaryKeys(GlobalDB);
110 /* puts(WMGetPropListDescription(WindowMakerDB, False)); */
111 for (i = 0; i < WMGetPropListItemCount(keyList); i++) {
112 key = WMGetFromPLArray(keyList, i);
114 /* We don't have this value anyway, so no problem.
115 * Probably a new option */
116 p1 = WMGetFromPLDictionary(WindowMakerDB, key);
117 if (!p1)
118 continue;
119 /* The global doesn't have it, so no problem either. */
120 p2 = WMGetFromPLDictionary(GlobalDB, key);
121 if (!p2)
122 continue;
123 /* If both values are the same, don't save. */
124 if (WMIsPropListEqualTo(p1, p2))
125 WMRemoveFromPLDictionary(WindowMakerDB, key);
127 /* puts(WMGetPropListDescription(WindowMakerDB, False)); */
128 WMReleasePropList(keyList);
129 /* puts("storing data"); */
131 WMWritePropListToFile(WindowMakerDB, WindowMakerDBPath);
133 memset(&ev, 0, sizeof(XEvent));
135 ev.xclient.type = ClientMessage;
136 ev.xclient.message_type = XInternAtom(WMScreenDisplay(WMWidgetScreen(w)), "_WINDOWMAKER_COMMAND", False);
137 ev.xclient.window = DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w)));
138 ev.xclient.format = 8;
139 strncpy(ev.xclient.data.b, "Reconfigure", sizeof(ev.xclient.data.b));
141 XSendEvent(WMScreenDisplay(WMWidgetScreen(w)),
142 DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w))), False, SubstructureRedirectMask, &ev);
143 XFlush(WMScreenDisplay(WMWidgetScreen(w)));
146 static void undo(WMWidget * w, void *data)
148 PanelRec *rec = (PanelRec *) WPrefs.currentPanel;
150 /* Parameter not used, but tell the compiler that it is ok */
151 (void) w;
152 (void) data;
154 if (!rec)
155 return;
157 if (rec->callbacks.undoChanges && (rec->callbacks.flags & INITIALIZED_PANEL)) {
158 (*rec->callbacks.undoChanges) (WPrefs.currentPanel);
162 static void undoAll(WMWidget * w, void *data)
164 int i;
166 /* Parameter not used, but tell the compiler that it is ok */
167 (void) w;
168 (void) data;
170 for (i = 0; i < WPrefs.sectionCount; i++) {
171 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
173 if (rec->callbacks.undoChanges && (rec->callbacks.flags & INITIALIZED_PANEL))
174 (*rec->callbacks.undoChanges) ((Panel *) rec);
178 static void prepareForClose(void)
180 int i;
182 for (i = 0; i < WPrefs.sectionCount; i++) {
183 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
185 if (rec->callbacks.prepareForClose && (rec->callbacks.flags & INITIALIZED_PANEL))
186 (*rec->callbacks.prepareForClose) ((Panel *) rec);
190 static void toggleBalloons(WMWidget *w, void *data)
192 WMUserDefaults *udb = WMGetStandardUserDefaults();
193 Bool flag;
195 /* Parameter not used, but tell the compiler that it is ok */
196 (void) w;
197 (void) data;
199 flag = WMGetButtonSelected(WPrefs.balloonBtn);
201 WMSetBalloonEnabled(WMWidgetScreen(WPrefs.win), flag);
203 WMSetUDBoolForKey(udb, flag, "BalloonHelp");
206 static void createMainWindow(WMScreen * scr)
208 WMScroller *scroller;
209 WMFont *font;
210 char buffer[128];
212 WPrefs.win = WMCreateWindow(scr, "wprefs");
213 WMResizeWidget(WPrefs.win, 520, 390);
214 WMSetWindowTitle(WPrefs.win, _("Window Maker Preferences"));
215 WMSetWindowCloseAction(WPrefs.win, quit, NULL);
216 WMSetWindowMaxSize(WPrefs.win, 520, 390);
217 WMSetWindowMinSize(WPrefs.win, 520, 390);
218 WMSetWindowMiniwindowTitle(WPrefs.win, "Preferences");
220 WPrefs.scrollV = WMCreateScrollView(WPrefs.win);
221 WMResizeWidget(WPrefs.scrollV, 500, 87);
222 WMMoveWidget(WPrefs.scrollV, 10, 10);
223 WMSetScrollViewRelief(WPrefs.scrollV, WRSunken);
224 WMSetScrollViewHasHorizontalScroller(WPrefs.scrollV, True);
225 WMSetScrollViewHasVerticalScroller(WPrefs.scrollV, False);
226 scroller = WMGetScrollViewHorizontalScroller(WPrefs.scrollV);
227 WMSetScrollerArrowsPosition(scroller, WSANone);
229 WPrefs.buttonF = WMCreateFrame(WPrefs.win);
230 WMSetFrameRelief(WPrefs.buttonF, WRFlat);
232 WMSetScrollViewContentView(WPrefs.scrollV, WMWidgetView(WPrefs.buttonF));
234 WPrefs.undosBtn = WMCreateCommandButton(WPrefs.win);
235 WMResizeWidget(WPrefs.undosBtn, 90, 28);
236 WMMoveWidget(WPrefs.undosBtn, 135, 350);
237 WMSetButtonText(WPrefs.undosBtn, _("Revert Page"));
238 WMSetButtonAction(WPrefs.undosBtn, undo, NULL);
240 WPrefs.undoBtn = WMCreateCommandButton(WPrefs.win);
241 WMResizeWidget(WPrefs.undoBtn, 90, 28);
242 WMMoveWidget(WPrefs.undoBtn, 235, 350);
243 WMSetButtonText(WPrefs.undoBtn, _("Revert All"));
244 WMSetButtonAction(WPrefs.undoBtn, undoAll, NULL);
246 WPrefs.saveBtn = WMCreateCommandButton(WPrefs.win);
247 WMResizeWidget(WPrefs.saveBtn, 80, 28);
248 WMMoveWidget(WPrefs.saveBtn, 335, 350);
249 WMSetButtonText(WPrefs.saveBtn, _("Save"));
250 WMSetButtonAction(WPrefs.saveBtn, save, NULL);
252 WPrefs.closeBtn = WMCreateCommandButton(WPrefs.win);
253 WMResizeWidget(WPrefs.closeBtn, 80, 28);
254 WMMoveWidget(WPrefs.closeBtn, 425, 350);
255 WMSetButtonText(WPrefs.closeBtn, _("Close"));
256 WMSetButtonAction(WPrefs.closeBtn, quit, NULL);
258 WPrefs.balloonBtn = WMCreateSwitchButton(WPrefs.win);
259 WMResizeWidget(WPrefs.balloonBtn, 200, 28);
260 WMMoveWidget(WPrefs.balloonBtn, 15, 350);
261 WMSetButtonText(WPrefs.balloonBtn, _("Balloon Help"));
262 WMSetButtonAction(WPrefs.balloonBtn, toggleBalloons, NULL);
264 WMUserDefaults *udb = WMGetStandardUserDefaults();
265 Bool flag = WMGetUDBoolForKey(udb, "BalloonHelp");
267 WMSetButtonSelected(WPrefs.balloonBtn, flag);
268 WMSetBalloonEnabled(scr, flag);
271 /* banner */
272 WPrefs.banner = WMCreateFrame(WPrefs.win);
273 WMResizeWidget(WPrefs.banner, FRAME_WIDTH, FRAME_HEIGHT);
274 WMMoveWidget(WPrefs.banner, FRAME_LEFT, FRAME_TOP);
275 WMSetFrameRelief(WPrefs.banner, WRFlat);
277 font = WMCreateFont(scr, "Lucida Sans,URW Gothic L,Times New Roman,serif"
278 ":bold:pixelsize=26:antialias=true");
279 WPrefs.nameL = WMCreateLabel(WPrefs.banner);
280 WMSetLabelTextAlignment(WPrefs.nameL, WACenter);
281 WMResizeWidget(WPrefs.nameL, FRAME_WIDTH - 20, 60);
282 WMMoveWidget(WPrefs.nameL, 10, 50);
283 WMSetLabelFont(WPrefs.nameL, font);
284 WMSetLabelText(WPrefs.nameL, _("Window Maker Preferences"));
285 WMReleaseFont(font);
287 WPrefs.versionL = WMCreateLabel(WPrefs.banner);
288 WMResizeWidget(WPrefs.versionL, FRAME_WIDTH - 20, 20);
289 WMMoveWidget(WPrefs.versionL, 10, 120);
290 WMSetLabelTextAlignment(WPrefs.versionL, WACenter);
291 sprintf(buffer, _("Version %s"), VERSION);
292 WMSetLabelText(WPrefs.versionL, buffer);
294 WPrefs.statusL = WMCreateLabel(WPrefs.banner);
295 WMResizeWidget(WPrefs.statusL, FRAME_WIDTH - 20, 60);
296 WMMoveWidget(WPrefs.statusL, 10, 150);
297 WMSetLabelTextAlignment(WPrefs.statusL, WACenter);
298 WMSetLabelText(WPrefs.statusL, _("Starting..."));
300 WMMapSubwidgets(WPrefs.win);
302 WMUnmapWidget(WPrefs.undosBtn);
303 WMUnmapWidget(WPrefs.undoBtn);
304 WMUnmapWidget(WPrefs.saveBtn);
307 static void showPanel(Panel * panel)
309 PanelRec *rec = (PanelRec *) panel;
311 if (!(rec->callbacks.flags & INITIALIZED_PANEL)) {
312 (*rec->callbacks.createWidgets) (panel);
313 rec->callbacks.flags |= INITIALIZED_PANEL;
316 WMSetWindowTitle(WPrefs.win, rec->sectionName);
318 if (rec->callbacks.showPanel)
319 (*rec->callbacks.showPanel) (panel);
321 WMMapWidget(rec->box);
324 static void hidePanel(Panel * panel)
326 PanelRec *rec = (PanelRec *) panel;
328 WMUnmapWidget(rec->box);
330 if (rec->callbacks.hidePanel)
331 (*rec->callbacks.hidePanel) (panel);
334 static void savePanelData(Panel * panel)
336 PanelRec *rec = (PanelRec *) panel;
338 if (rec->callbacks.updateDomain) {
339 (*rec->callbacks.updateDomain) (panel);
343 static void changeSection(WMWidget * self, void *data)
345 /* Parameter not used, but tell the compiler that it is ok */
346 (void) self;
348 if (WPrefs.currentPanel == data)
349 return;
351 if (WPrefs.currentPanel == NULL) {
352 WMDestroyWidget(WPrefs.nameL);
353 WMDestroyWidget(WPrefs.versionL);
354 WMDestroyWidget(WPrefs.statusL);
356 WMSetFrameRelief(WPrefs.banner, WRGroove);
358 /* WMMapWidget(WPrefs.undosBtn);
359 WMMapWidget(WPrefs.undoBtn);
361 WMMapWidget(WPrefs.saveBtn);
364 showPanel(data);
366 if (WPrefs.currentPanel)
367 hidePanel(WPrefs.currentPanel);
368 WPrefs.currentPanel = data;
371 char *LocateImage(const char *name)
373 char *path;
374 char *tmp = wmalloc(strlen(name) + 8);
376 if (TIFFOK) {
377 sprintf(tmp, "%s.tiff", name);
378 path = WMPathForResourceOfType(tmp, "tiff");
379 } else {
380 sprintf(tmp, "%s.xpm", name);
381 path = WMPathForResourceOfType(tmp, "xpm");
383 wfree(tmp);
384 if (!path) {
385 wwarning(_("could not locate image file %s"), name);
388 return path;
391 void CreateImages(WMScreen *scr, RContext *rc, RImage *xis, const char *file,
392 WMPixmap **icon_normal, WMPixmap **icon_greyed)
394 RImage *icon;
395 char *path;
396 RColor gray = { 0xae, 0xaa, 0xae, 0 };
398 path = LocateImage(file);
399 if (!path)
401 *icon_normal = NULL;
402 if (icon_greyed)
403 *icon_greyed = NULL;
404 return;
407 *icon_normal = WMCreatePixmapFromFile(scr, path);
408 if (!*icon_normal)
410 wwarning(_("could not load icon %s"), path);
411 if (icon_greyed)
412 *icon_greyed = NULL;
413 wfree(path);
414 return;
417 if (!icon_greyed) // Greyed-out version not requested, we are done
419 wfree(path);
420 return;
423 icon = RLoadImage(rc, path, 0);
424 if (!icon)
426 wwarning(_("could not load icon %s"), path);
427 *icon_greyed = NULL;
428 wfree(path);
429 return;
431 RCombineImageWithColor(icon, &gray);
432 if (xis)
434 RCombineImagesWithOpaqueness(icon, xis, 180);
436 *icon_greyed = WMCreatePixmapFromRImage(scr, icon, 127);
437 if (!*icon_greyed)
439 wwarning(_("could not process icon %s: %s"), path, RMessageForError(RErrorCode));
441 RReleaseImage(icon);
442 wfree(path);
446 static WMPixmap *makeTitledIcon(WMPixmap *icon)
448 return WMRetainPixmap(icon);
451 void SetButtonAlphaImage(WMScreen *scr, WMButton *bPtr, const char *file)
453 WMPixmap *icon;
454 WMPixmap *icon2;
455 RColor color;
456 char *iconPath;
458 iconPath = LocateImage(file);
460 color.red = 0xae;
461 color.green = 0xaa;
462 color.blue = 0xae;
463 color.alpha = 0;
464 if (iconPath) {
465 icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
466 if (!icon)
467 wwarning(_("could not load icon file %s"), iconPath);
468 } else {
469 icon = NULL;
472 if (icon) {
473 icon2 = makeTitledIcon(icon);
474 if (icon)
475 WMReleasePixmap(icon);
476 } else {
477 icon2 = NULL;
480 WMSetButtonImage(bPtr, icon2);
482 if (icon2)
483 WMReleasePixmap(icon2);
485 color.red = 0xff;
486 color.green = 0xff;
487 color.blue = 0xff;
488 color.alpha = 0;
489 if (iconPath) {
490 icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
491 if (!icon)
492 wwarning(_("could not load icon file %s"), iconPath);
493 } else {
494 icon = NULL;
497 WMSetButtonAltImage(bPtr, icon);
499 if (icon)
500 WMReleasePixmap(icon);
502 if (iconPath)
503 wfree(iconPath);
506 void AddSection(Panel * panel, const char *iconFile)
508 WMButton *bPtr;
510 assert(WPrefs.sectionCount < MAX_SECTIONS);
512 bPtr = WMCreateCustomButton(WPrefs.buttonF, WBBStateLightMask | WBBStateChangeMask);
513 WMResizeWidget(bPtr, 64, 64);
514 WMMoveWidget(bPtr, WPrefs.sectionCount * 64, 0);
515 WMSetButtonImagePosition(bPtr, WIPImageOnly);
516 WMSetButtonAction(bPtr, changeSection, panel);
517 WMHangData(bPtr, panel);
519 WMSetBalloonTextForView(((PanelRec *) panel)->description, WMWidgetView(bPtr));
520 SetButtonAlphaImage(WMWidgetScreen(bPtr), bPtr, iconFile);
521 WMMapWidget(bPtr);
523 WPrefs.sectionB[WPrefs.sectionCount] = bPtr;
525 if (WPrefs.sectionCount > 0)
526 WMGroupButtons(WPrefs.sectionB[0], bPtr);
528 WPrefs.sectionCount++;
530 WMResizeWidget(WPrefs.buttonF, WPrefs.sectionCount * 64, 64);
533 void Initialize(WMScreen * scr)
535 char **list;
536 int i;
537 char *path;
539 list = RSupportedFileFormats();
540 for (i = 0; list[i] != NULL; i++) {
541 if (strcmp(list[i], "TIFF") == 0) {
542 TIFFOK = True;
543 break;
547 if (TIFFOK)
548 path = WMPathForResourceOfType("WPrefs.tiff", NULL);
549 else
550 path = WMPathForResourceOfType("WPrefs.xpm", NULL);
551 if (path) {
552 RImage *tmp;
554 tmp = RLoadImage(WMScreenRContext(scr), path, 0);
555 if (!tmp) {
556 wwarning(_("could not load image file %s:%s"), path, RMessageForError(RErrorCode));
557 } else {
558 WMSetApplicationIconImage(scr, tmp);
559 RReleaseImage(tmp);
561 wfree(path);
564 memset(&WPrefs, 0, sizeof(_WPrefs));
565 createMainWindow(scr);
567 WMRealizeWidget(WPrefs.win);
569 WMSetWindowMiniwindowImage(WPrefs.win, WMGetApplicationIconImage(scr));
571 WMMapWidget(WPrefs.win);
572 XFlush(WMScreenDisplay(scr));
573 WMSetLabelText(WPrefs.statusL, _("Loading Window Maker configuration files..."));
574 XFlush(WMScreenDisplay(scr));
575 loadConfigurations(scr, WPrefs.win);
577 WMSetLabelText(WPrefs.statusL, _("Initializing configuration panels..."));
579 InitFocus(WPrefs.banner);
580 InitWindowHandling(WPrefs.banner);
582 InitMenuPreferences(WPrefs.banner);
583 InitIcons(WPrefs.banner);
584 InitPreferences(WPrefs.banner);
586 InitPaths(WPrefs.banner);
587 InitDocks(WPrefs.banner);
588 InitWorkspace(WPrefs.banner);
589 InitConfigurations(WPrefs.banner);
591 InitMenu(WPrefs.banner);
593 #ifdef not_yet_fully_implemented
594 InitKeyboardSettings(WPrefs.banner);
595 #endif
596 InitKeyboardShortcuts(WPrefs.banner);
597 InitMouseSettings(WPrefs.banner);
599 InitAppearance(WPrefs.banner);
601 InitFontSimple(WPrefs.banner);
603 #ifdef not_yet_fully_implemented
604 InitThemes(WPrefs.banner);
605 #endif
606 InitExpert(WPrefs.banner);
608 WMRealizeWidget(WPrefs.scrollV);
610 WMSetLabelText(WPrefs.statusL, "");
613 WMWindow *GetWindow(void)
615 return WPrefs.win;
618 static void loadConfigurations(WMScreen * scr, WMWindow * mainw)
620 WMPropList *db, *gdb;
621 char *path;
622 FILE *file;
623 char buffer[1024];
624 char mbuf[1024];
625 int v1, v2, v3;
627 path = wdefaultspathfordomain("WindowMaker");
628 WindowMakerDBPath = path;
630 db = WMReadPropListFromFile(path);
631 if (db) {
632 if (!WMIsPLDictionary(db)) {
633 WMReleasePropList(db);
634 db = NULL;
635 sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), path);
636 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
638 } else {
639 sprintf(mbuf, _("Could not load Window Maker domain (%s) from defaults database."), path);
640 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
643 path = getenv("WMAKER_BIN_NAME");
644 if (!path)
645 path = "wmaker";
647 char *command;
649 command = wstrconcat(path, " --version");
650 file = popen(command, "r");
651 wfree(command);
653 if (!file || !fgets(buffer, 1023, file)) {
654 werror(_("could not extract version information from Window Maker"));
655 wfatal(_("Make sure wmaker is in your search path."));
657 WMRunAlertPanel(scr, mainw, _("Error"),
659 ("Could not extract version from Window Maker. Make sure it is correctly installed and is in your PATH environment variable."),
660 _("OK"), NULL, NULL);
661 exit(1);
663 if (file)
664 pclose(file);
666 if (sscanf(buffer, "Window Maker %i.%i.%i", &v1, &v2, &v3) != 3
667 && sscanf(buffer, "WindowMaker %i.%i.%i", &v1, &v2, &v3) != 3) {
668 WMRunAlertPanel(scr, mainw, _("Error"),
669 _("Could not extract version from Window Maker. "
670 "Make sure it is correctly installed and the path "
671 "where it installed is in the PATH environment "
672 "variable."), _("OK"), NULL, NULL);
673 exit(1);
675 if (v1 == 0 && (v2 < 18 || v3 < 0)) {
676 sprintf(mbuf, _("WPrefs only supports Window Maker 0.18.0 or newer.\n"
677 "The version installed is %i.%i.%i\n"), v1, v2, v3);
678 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
679 exit(1);
682 if (v1 > 1 || (v1 == 1 && (v2 > 0))) {
683 sprintf(mbuf,
685 ("Window Maker %i.%i.%i, which is installed in your system, is not fully supported by this version of WPrefs."),
686 v1, v2, v3);
687 WMRunAlertPanel(scr, mainw, _("Warning"), mbuf, _("OK"), NULL, NULL);
691 char *command;
693 command = wstrconcat(path, " --global_defaults_path");
694 file = popen(command, "r");
695 wfree(command);
697 if (!file || !fgets(buffer, 1023, file)) {
698 werror(_("could not run \"%s --global_defaults_path\"."), path);
699 exit(1);
700 } else {
701 char *ptr;
702 ptr = strchr(buffer, '\n');
703 if (ptr)
704 *ptr = 0;
705 strcat(buffer, "/WindowMaker");
708 if (file)
709 pclose(file);
711 gdb = WMReadPropListFromFile(buffer);
713 if (gdb) {
714 if (!WMIsPLDictionary(gdb)) {
715 WMReleasePropList(gdb);
716 gdb = NULL;
717 sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), buffer);
718 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
720 } else {
721 sprintf(mbuf, _("Could not load global Window Maker domain (%s)."), buffer);
722 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
725 if (!db) {
726 db = WMCreatePLDictionary(NULL, NULL);
728 if (!gdb) {
729 gdb = WMCreatePLDictionary(NULL, NULL);
732 GlobalDB = gdb;
734 WindowMakerDB = db;
737 WMPropList *GetObjectForKey(const char *defaultName)
739 WMPropList *object = NULL;
740 WMPropList *key = WMCreatePLString(defaultName);
742 object = WMGetFromPLDictionary(WindowMakerDB, key);
743 if (!object)
744 object = WMGetFromPLDictionary(GlobalDB, key);
746 WMReleasePropList(key);
748 return object;
751 void SetObjectForKey(WMPropList * object, const char *defaultName)
753 WMPropList *key = WMCreatePLString(defaultName);
755 WMPutInPLDictionary(WindowMakerDB, key, object);
756 WMReleasePropList(key);
759 void RemoveObjectForKey(const char *defaultName)
761 WMPropList *key = WMCreatePLString(defaultName);
763 WMRemoveFromPLDictionary(WindowMakerDB, key);
765 WMReleasePropList(key);
768 char *GetStringForKey(const char *defaultName)
770 WMPropList *val;
772 val = GetObjectForKey(defaultName);
774 if (!val)
775 return NULL;
777 if (!WMIsPLString(val))
778 return NULL;
780 return WMGetFromPLString(val);
783 WMPropList *GetArrayForKey(const char *defaultName)
785 WMPropList *val;
787 val = GetObjectForKey(defaultName);
789 if (!val)
790 return NULL;
792 if (!WMIsPLArray(val))
793 return NULL;
795 return val;
798 WMPropList *GetDictionaryForKey(const char *defaultName)
800 WMPropList *val;
802 val = GetObjectForKey(defaultName);
804 if (!val)
805 return NULL;
807 if (!WMIsPLDictionary(val))
808 return NULL;
810 return val;
813 int GetIntegerForKey(const char *defaultName)
815 WMPropList *val;
816 char *str;
817 int value;
819 val = GetObjectForKey(defaultName);
821 if (!val)
822 return 0;
824 if (!WMIsPLString(val))
825 return 0;
827 str = WMGetFromPLString(val);
828 if (!str)
829 return 0;
831 if (sscanf(str, "%i", &value) != 1)
832 return 0;
834 return value;
837 Bool GetBoolForKey(const char *defaultName)
839 int value;
840 char *str;
842 str = GetStringForKey(defaultName);
844 if (!str)
845 return False;
847 if (sscanf(str, "%i", &value) == 1 && value != 0)
848 return True;
850 if (strcasecmp(str, "YES") == 0)
851 return True;
853 if (strcasecmp(str, "Y") == 0)
854 return True;
856 return False;
859 void SetIntegerForKey(int value, const char *defaultName)
861 WMPropList *object;
862 char buffer[128];
864 sprintf(buffer, "%i", value);
865 object = WMCreatePLString(buffer);
867 SetObjectForKey(object, defaultName);
868 WMReleasePropList(object);
871 void SetStringForKey(const char *value, const char *defaultName)
873 WMPropList *object;
875 object = WMCreatePLString(value);
877 SetObjectForKey(object, defaultName);
878 WMReleasePropList(object);
881 void SetBoolForKey(Bool value, const char *defaultName)
883 static WMPropList *yes = NULL, *no = NULL;
885 if (!yes) {
886 yes = WMCreatePLString("YES");
887 no = WMCreatePLString("NO");
890 SetObjectForKey(value ? yes : no, defaultName);
893 void SetSpeedForKey(int speed, const char *defaultName)
895 char *str;
897 switch (speed) {
898 case 0:
899 str = "ultraslow";
900 break;
901 case 1:
902 str = "slow";
903 break;
904 case 2:
905 str = "medium";
906 break;
907 case 3:
908 str = "fast";
909 break;
910 case 4:
911 str = "ultrafast";
912 break;
913 default:
914 str = NULL;
917 if (str)
918 SetStringForKey(str, defaultName);
921 int GetSpeedForKey(const char *defaultName)
923 char *str;
924 int i;
926 str = GetStringForKey(defaultName);
927 if (!str)
928 return 2;
930 if (strcasecmp(str, "ultraslow") == 0)
931 i = 0;
932 else if (strcasecmp(str, "slow") == 0)
933 i = 1;
934 else if (strcasecmp(str, "medium") == 0)
935 i = 2;
936 else if (strcasecmp(str, "fast") == 0)
937 i = 3;
938 else if (strcasecmp(str, "ultrafast") == 0)
939 i = 4;
940 else {
941 wwarning(_("bad speed value for option %s; using default Medium"), defaultName);
942 i = 2;
944 return i;