added some netwm support in WINGs
[wmaker-crm.git] / WPrefs.app / WPrefs.c
blobaabe1d93a7d2b72e80f94b1039d0cf16f3bf71a9
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
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20 * USA.
24 #include "WPrefs.h"
25 #include <assert.h>
28 extern Panel *InitWindowHandling(WMScreen *scr, WMWidget *parent);
30 extern Panel *InitKeyboardSettings(WMScreen *scr, WMWidget *parent);
32 extern Panel *InitMouseSettings(WMScreen *scr, WMWidget *parent);
34 extern Panel *InitKeyboardShortcuts(WMScreen *scr, WMWidget *parent);
36 extern Panel *InitWorkspace(WMScreen *scr, WMWidget *parent);
38 extern Panel *InitFocus(WMScreen *scr, WMWidget *parent);
40 extern Panel *InitPreferences(WMScreen *scr, WMWidget *parent);
42 extern Panel *InitFont(WMScreen *scr, WMWidget *parent);
43 extern Panel *InitFontSimple(WMScreen *scr, WMWidget *parent);
45 extern Panel *InitConfigurations(WMScreen *scr, WMWidget *parent);
47 extern Panel *InitPaths(WMScreen *scr, WMWidget *parent);
49 extern Panel *InitMenu(WMScreen *scr, WMWidget *parent);
51 extern Panel *InitExpert(WMScreen *scr, WMWidget *parent);
53 extern Panel *InitMenuPreferences(WMScreen *scr, WMWidget *parent);
55 extern Panel *InitIcons(WMScreen *scr, WMWidget *parent);
57 extern Panel *InitThemes(WMScreen *scr, WMWidget *parent);
59 extern Panel *InitAppearance(WMScreen *scr, WMWidget *parent);
64 #define ICON_TITLE_FONT "sans serif:pixelsize=9"
65 #define ICON_TITLE_VFONT "sans serif:pixelsize=9:weight=100"
68 #define MAX_SECTIONS 16
71 typedef struct _WPrefs {
72 WMWindow *win;
74 WMScrollView *scrollV;
75 WMFrame *buttonF;
76 WMButton *sectionB[MAX_SECTIONS];
78 int sectionCount;
80 WMButton *saveBtn;
81 WMButton *closeBtn;
82 WMButton *undoBtn;
83 WMButton *undosBtn;
85 WMButton *balloonBtn;
87 WMFrame *banner;
88 WMLabel *nameL;
89 WMLabel *versionL;
90 WMLabel *statusL;
92 Panel *currentPanel;
93 } _WPrefs;
96 static _WPrefs WPrefs;
98 /* system wide defaults dictionary. Read-only */
99 static WMPropList *GlobalDB = NULL;
100 /* user defaults dictionary */
101 static WMPropList *WindowMakerDB = NULL;
102 static char *WindowMakerDBPath = NULL;
105 static Bool TIFFOK = False;
108 #define INITIALIZED_PANEL (1<<0)
113 static void loadConfigurations(WMScreen *scr, WMWindow *mainw);
115 static void savePanelData(Panel *panel);
117 static void prepareForClose();
119 void
120 quit(WMWidget *w, void *data)
122 prepareForClose();
124 exit(0);
128 static void
129 save(WMWidget *w, void *data)
131 int i;
132 WMPropList *p1, *p2;
133 WMPropList *keyList;
134 WMPropList *key;
135 char *msg = "Reconfigure";
136 XEvent ev;
139 /* puts("gathering data");*/
140 for (i=0; i<WPrefs.sectionCount; i++) {
141 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
142 if ((rec->callbacks.flags & INITIALIZED_PANEL))
143 savePanelData((Panel*)rec);
145 /* puts("compressing data");*/
146 /* compare the user dictionary with the global and remove redundant data */
147 keyList = WMGetPLDictionaryKeys(GlobalDB);
148 /* puts(WMGetPropListDescription(WindowMakerDB, False));*/
149 for (i=0; i<WMGetPropListItemCount(keyList); i++) {
150 key = WMGetFromPLArray(keyList, i);
152 /* We don't have this value anyway, so no problem.
153 * Probably a new option */
154 p1 = WMGetFromPLDictionary(WindowMakerDB, key);
155 if (!p1)
156 continue;
157 /* The global doesn't have it, so no problem either. */
158 p2 = WMGetFromPLDictionary(GlobalDB, key);
159 if (!p2)
160 continue;
161 /* If both values are the same, don't save. */
162 if (WMIsPropListEqualTo(p1, p2))
163 WMRemoveFromPLDictionary(WindowMakerDB, key);
165 /* puts(WMGetPropListDescription(WindowMakerDB, False));*/
166 WMReleasePropList(keyList);
167 /* puts("storing data");*/
169 WMWritePropListToFile(WindowMakerDB, WindowMakerDBPath, True);
172 memset(&ev, 0, sizeof(XEvent));
174 ev.xclient.type = ClientMessage;
175 ev.xclient.message_type = XInternAtom(WMScreenDisplay(WMWidgetScreen(w)),
176 "_WINDOWMAKER_COMMAND", False);
177 ev.xclient.window = DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w)));
178 ev.xclient.format = 8;
180 for (i = 0; i <= strlen(msg); i++) {
181 ev.xclient.data.b[i] = msg[i];
183 XSendEvent(WMScreenDisplay(WMWidgetScreen(w)),
184 DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w))),
185 False, SubstructureRedirectMask, &ev);
186 XFlush(WMScreenDisplay(WMWidgetScreen(w)));
191 static void
192 undo(WMWidget *w, void *data)
194 PanelRec *rec = (PanelRec*)WPrefs.currentPanel;
196 if (!rec)
197 return;
199 if (rec->callbacks.undoChanges
200 && (rec->callbacks.flags & INITIALIZED_PANEL)) {
201 (*rec->callbacks.undoChanges)(WPrefs.currentPanel);
206 static void
207 undoAll(WMWidget *w, void *data)
209 int i;
211 for (i=0; i<WPrefs.sectionCount; i++) {
212 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
214 if (rec->callbacks.undoChanges
215 && (rec->callbacks.flags & INITIALIZED_PANEL))
216 (*rec->callbacks.undoChanges)((Panel*)rec);
222 static void
223 prepareForClose()
225 int i;
227 for (i=0; i<WPrefs.sectionCount; i++) {
228 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
230 if (rec->callbacks.prepareForClose
231 && (rec->callbacks.flags & INITIALIZED_PANEL))
232 (*rec->callbacks.prepareForClose)((Panel*)rec);
237 void
238 toggleBalloons(WMWidget *w, void *data)
240 WMUserDefaults *udb = WMGetStandardUserDefaults();
241 Bool flag;
243 flag = WMGetButtonSelected(WPrefs.balloonBtn);
245 WMSetBalloonEnabled(WMWidgetScreen(WPrefs.win), flag);
247 WMSetUDBoolForKey(udb, flag, "BalloonHelp");
251 static void
252 createMainWindow(WMScreen *scr)
254 WMScroller *scroller;
255 WMFont *font;
256 char buffer[128];
258 WPrefs.win = WMCreateWindow(scr, "wprefs");
259 WMResizeWidget(WPrefs.win, 520, 390);
260 WMSetWindowTitle(WPrefs.win, _("Window Maker Preferences"));
261 WMSetWindowCloseAction(WPrefs.win, quit, NULL);
262 WMSetWindowMaxSize(WPrefs.win, 520, 390);
263 WMSetWindowMinSize(WPrefs.win, 520, 390);
264 WMSetWindowMiniwindowTitle(WPrefs.win, "Preferences");
266 WPrefs.scrollV = WMCreateScrollView(WPrefs.win);
267 WMResizeWidget(WPrefs.scrollV, 500, 87);
268 WMMoveWidget(WPrefs.scrollV, 10, 10);
269 WMSetScrollViewRelief(WPrefs.scrollV, WRSunken);
270 WMSetScrollViewHasHorizontalScroller(WPrefs.scrollV, True);
271 WMSetScrollViewHasVerticalScroller(WPrefs.scrollV, False);
272 scroller = WMGetScrollViewHorizontalScroller(WPrefs.scrollV);
273 WMSetScrollerArrowsPosition(scroller, WSANone);
275 WPrefs.buttonF = WMCreateFrame(WPrefs.win);
276 WMSetFrameRelief(WPrefs.buttonF, WRFlat);
278 WMSetScrollViewContentView(WPrefs.scrollV, WMWidgetView(WPrefs.buttonF));
280 WPrefs.undosBtn = WMCreateCommandButton(WPrefs.win);
281 WMResizeWidget(WPrefs.undosBtn, 90, 28);
282 WMMoveWidget(WPrefs.undosBtn, 135, 350);
283 WMSetButtonText(WPrefs.undosBtn, _("Revert Page"));
284 WMSetButtonAction(WPrefs.undosBtn, undo, NULL);
286 WPrefs.undoBtn = WMCreateCommandButton(WPrefs.win);
287 WMResizeWidget(WPrefs.undoBtn, 90, 28);
288 WMMoveWidget(WPrefs.undoBtn, 235, 350);
289 WMSetButtonText(WPrefs.undoBtn, _("Revert All"));
290 WMSetButtonAction(WPrefs.undoBtn, undoAll, NULL);
292 WPrefs.saveBtn = WMCreateCommandButton(WPrefs.win);
293 WMResizeWidget(WPrefs.saveBtn, 80, 28);
294 WMMoveWidget(WPrefs.saveBtn, 335, 350);
295 WMSetButtonText(WPrefs.saveBtn, _("Save"));
296 WMSetButtonAction(WPrefs.saveBtn, save, NULL);
298 WPrefs.closeBtn = WMCreateCommandButton(WPrefs.win);
299 WMResizeWidget(WPrefs.closeBtn, 80, 28);
300 WMMoveWidget(WPrefs.closeBtn, 425, 350);
301 WMSetButtonText(WPrefs.closeBtn, _("Close"));
302 WMSetButtonAction(WPrefs.closeBtn, quit, NULL);
305 WPrefs.balloonBtn = WMCreateSwitchButton(WPrefs.win);
306 WMResizeWidget(WPrefs.balloonBtn, 200, 28);
307 WMMoveWidget(WPrefs.balloonBtn, 15, 350);
308 WMSetButtonText(WPrefs.balloonBtn, _("Balloon Help"));
309 WMSetButtonAction(WPrefs.balloonBtn, toggleBalloons, NULL);
311 WMUserDefaults *udb = WMGetStandardUserDefaults();
312 Bool flag = WMGetUDBoolForKey(udb, "BalloonHelp");
314 WMSetButtonSelected(WPrefs.balloonBtn, flag);
315 WMSetBalloonEnabled(scr, flag);
318 /* banner */
319 WPrefs.banner = WMCreateFrame(WPrefs.win);
320 WMResizeWidget(WPrefs.banner, FRAME_WIDTH, FRAME_HEIGHT);
321 WMMoveWidget(WPrefs.banner, FRAME_LEFT, FRAME_TOP);
322 WMSetFrameRelief(WPrefs.banner, WRFlat);
324 font = WMCreateFont(scr, "Lucida Sans,URW Gothic L,Times New Roman,serif"
325 ":bold:pixelsize=26:antialias=true");
326 WPrefs.nameL = WMCreateLabel(WPrefs.banner);
327 WMSetLabelTextAlignment(WPrefs.nameL, WACenter);
328 WMResizeWidget(WPrefs.nameL, FRAME_WIDTH-20, 60);
329 WMMoveWidget(WPrefs.nameL, 10, 50);
330 WMSetLabelFont(WPrefs.nameL, font);
331 WMSetLabelText(WPrefs.nameL, _("Window Maker Preferences"));
332 WMReleaseFont(font);
334 WPrefs.versionL = WMCreateLabel(WPrefs.banner);
335 WMResizeWidget(WPrefs.versionL, FRAME_WIDTH-20, 20);
336 WMMoveWidget(WPrefs.versionL, 10, 120);
337 WMSetLabelTextAlignment(WPrefs.versionL, WACenter);
338 sprintf(buffer, _("Version %s"), VERSION);
339 WMSetLabelText(WPrefs.versionL, buffer);
341 WPrefs.statusL = WMCreateLabel(WPrefs.banner);
342 WMResizeWidget(WPrefs.statusL, FRAME_WIDTH-20, 60);
343 WMMoveWidget(WPrefs.statusL, 10, 150);
344 WMSetLabelTextAlignment(WPrefs.statusL, WACenter);
345 WMSetLabelText(WPrefs.statusL, _("Starting..."));
349 WMMapSubwidgets(WPrefs.win);
351 WMUnmapWidget(WPrefs.undosBtn);
352 WMUnmapWidget(WPrefs.undoBtn);
353 WMUnmapWidget(WPrefs.saveBtn);
357 static void
358 showPanel(Panel *panel)
360 PanelRec *rec = (PanelRec*)panel;
362 if (!(rec->callbacks.flags & INITIALIZED_PANEL)) {
363 (*rec->callbacks.createWidgets)(panel);
364 rec->callbacks.flags |= INITIALIZED_PANEL;
367 WMSetWindowTitle(WPrefs.win, rec->sectionName);
369 if (rec->callbacks.showPanel)
370 (*rec->callbacks.showPanel)(panel);
372 WMMapWidget(rec->box);
377 static void
378 hidePanel(Panel *panel)
380 PanelRec *rec = (PanelRec*)panel;
382 WMUnmapWidget(rec->box);
384 if (rec->callbacks.hidePanel)
385 (*rec->callbacks.hidePanel)(panel);
389 static void
390 savePanelData(Panel *panel)
392 PanelRec *rec = (PanelRec*)panel;
394 if (rec->callbacks.updateDomain) {
395 (*rec->callbacks.updateDomain)(panel);
400 static void
401 changeSection(WMWidget *self, void *data)
403 if (WPrefs.currentPanel == data)
404 return;
406 if (WPrefs.currentPanel == NULL) {
407 WMDestroyWidget(WPrefs.nameL);
408 WMDestroyWidget(WPrefs.versionL);
409 WMDestroyWidget(WPrefs.statusL);
411 WMSetFrameRelief(WPrefs.banner, WRGroove);
413 /* WMMapWidget(WPrefs.undosBtn);
414 WMMapWidget(WPrefs.undoBtn);
416 WMMapWidget(WPrefs.saveBtn);
419 showPanel(data);
421 if (WPrefs.currentPanel)
422 hidePanel(WPrefs.currentPanel);
423 WPrefs.currentPanel = data;
428 char*
429 LocateImage(char *name)
431 char *path;
432 char *tmp = wmalloc(strlen(name)+8);
434 if (TIFFOK) {
435 sprintf(tmp, "%s.tiff", name);
436 path = WMPathForResourceOfType(tmp, "tiff");
437 } else {
438 sprintf(tmp, "%s.xpm", name);
439 path = WMPathForResourceOfType(tmp, "xpm");
441 wfree(tmp);
442 if (!path) {
443 wwarning(_("could not locate image file %s\n"), name);
446 return path;
451 static WMPixmap*
452 makeTitledIcon(WMScreen *scr, WMPixmap *icon, char *title1, char *title2)
454 return WMRetainPixmap(icon);
456 #if 0
457 static GC gc = NULL;
458 static XFontStruct *hfont = NULL;
459 static XFontStruct *vfont = NULL;
460 WMPixmap *tmp;
461 Pixmap pix, mask;
462 Display *dpy = WMScreenDisplay(scr);
463 WMColor *black = WMBlackColor(scr);
464 GC fgc;
465 WMSize size = WMGetPixmapSize(icon);
468 tmp = WMCreatePixmap(scr, 60, 60, WMScreenDepth(scr), True);
470 pix = WMGetPixmapXID(tmp);
471 mask = WMGetPixmapMaskXID(tmp);
473 if (gc == NULL) {
474 gc = XCreateGC(dpy, mask, 0, NULL);
476 hfont = XLoadQueryFont(dpy, ICON_TITLE_FONT);
477 vfont = XLoadQueryFont(dpy, ICON_TITLE_VFONT);
480 if (hfont == NULL) {
481 return WMRetainPixmap(icon);
484 XSetForeground(dpy, gc, 0);
485 XFillRectangle(dpy, mask, gc, 0, 0, 60, 60);
487 fgc = WMColorGC(black);
489 XSetForeground(dpy, gc, 1);
491 XCopyArea(dpy, WMGetPixmapXID(icon), pix, fgc, 0, 0,
492 size.width, size.height, 12, 12);
494 if (WMGetPixmapMaskXID(icon) != None)
495 XCopyPlane(dpy, WMGetPixmapMaskXID(icon), mask, gc, 0, 0,
496 size.width, size.height, 12, 12, 1);
497 else
498 XFillRectangle(dpy, mask, gc, 12, 12, 48, 48);
501 if (title1) {
502 XSetFont(dpy, fgc, vfont->fid);
503 XSetFont(dpy, gc, vfont->fid);
505 XDrawString(dpy, pix, fgc, 0, vfont->ascent,
506 title1, strlen(title1));
508 XDrawString(dpy, mask, gc, 0, vfont->ascent,
509 title1, strlen(title1));
512 if (title2) {
513 XSetFont(dpy, fgc, hfont->fid);
514 XSetFont(dpy, gc, hfont->fid);
516 XDrawString(dpy, pix, fgc, (title1 ? 12 : 0), hfont->ascent,
517 title2, strlen(title2));
519 XDrawString(dpy, mask, gc, (title1 ? 12 : 0), hfont->ascent,
520 title2, strlen(title2));
523 return tmp;
524 #endif
528 void
529 SetButtonAlphaImage(WMScreen *scr, WMButton *bPtr, char *file,
530 char *title1, char *title2)
532 WMPixmap *icon;
533 WMPixmap *icon2;
534 RColor color;
535 char *iconPath;
537 iconPath = LocateImage(file);
539 color.red = 0xae;
540 color.green = 0xaa;
541 color.blue = 0xae;
542 color.alpha = 0;
543 if (iconPath) {
544 icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
545 if (!icon)
546 wwarning(_("could not load icon file %s"), iconPath);
547 } else {
548 icon = NULL;
551 if (icon) {
552 icon2 = makeTitledIcon(scr, icon, title1, title2);
553 if (icon)
554 WMReleasePixmap(icon);
555 } else {
556 icon2 = NULL;
559 WMSetButtonImage(bPtr, icon2);
561 if (icon2)
562 WMReleasePixmap(icon2);
564 color.red = 0xff;
565 color.green = 0xff;
566 color.blue = 0xff;
567 color.alpha = 0;
568 if (iconPath) {
569 icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
570 if (!icon)
571 wwarning(_("could not load icon file %s"), iconPath);
572 } else {
573 icon = NULL;
576 WMSetButtonAltImage(bPtr, icon);
578 if (icon)
579 WMReleasePixmap(icon);
581 if (iconPath)
582 wfree(iconPath);
586 void
587 AddSection(Panel *panel, char *iconFile)
589 WMButton *bPtr;
591 assert(WPrefs.sectionCount < MAX_SECTIONS);
594 bPtr = WMCreateCustomButton(WPrefs.buttonF, WBBStateLightMask
595 |WBBStateChangeMask);
596 WMResizeWidget(bPtr, 64, 64);
597 WMMoveWidget(bPtr, WPrefs.sectionCount*64, 0);
598 WMSetButtonImagePosition(bPtr, WIPImageOnly);
599 WMSetButtonAction(bPtr, changeSection, panel);
600 WMHangData(bPtr, panel);
602 WMSetBalloonTextForView(((PanelRec*)panel)->description,
603 WMWidgetView(bPtr));
606 char *t1, *t2;
608 t1 = wstrdup(((PanelRec*)panel)->sectionName);
609 t2 = strchr(t1, ' ');
610 if (t2) {
611 *t2 = 0;
612 t2++;
614 SetButtonAlphaImage(WMWidgetScreen(bPtr), bPtr, iconFile,
615 t1, t2);
616 wfree(t1);
618 WMMapWidget(bPtr);
620 WPrefs.sectionB[WPrefs.sectionCount] = bPtr;
622 if (WPrefs.sectionCount > 0) {
623 WMGroupButtons(WPrefs.sectionB[0], bPtr);
626 WPrefs.sectionCount++;
628 WMResizeWidget(WPrefs.buttonF, WPrefs.sectionCount*64, 64);
632 void
633 Initialize(WMScreen *scr)
635 char **list;
636 int i;
637 char *path;
639 list = RSupportedFileFormats();
640 for (i=0; list[i]!=NULL; i++) {
641 if (strcmp(list[i], "TIFF")==0) {
642 TIFFOK = True;
643 break;
647 if (TIFFOK)
648 path = WMPathForResourceOfType("WPrefs.tiff", NULL);
649 else
650 path = WMPathForResourceOfType("WPrefs.xpm", NULL);
651 if (path) {
652 RImage *tmp;
654 tmp = RLoadImage(WMScreenRContext(scr), path, 0);
655 if (!tmp) {
656 wwarning(_("could not load image file %s:%s"), path,
657 RMessageForError(RErrorCode));
658 } else {
659 WMSetApplicationIconImage(scr, tmp);
660 RReleaseImage(tmp);
662 wfree(path);
665 memset(&WPrefs, 0, sizeof(_WPrefs));
666 createMainWindow(scr);
668 WMRealizeWidget(WPrefs.win);
670 WMSetWindowMiniwindowImage(WPrefs.win, WMGetApplicationIconImage(scr));
672 WMMapWidget(WPrefs.win);
673 XFlush(WMScreenDisplay(scr));
674 WMSetLabelText(WPrefs.statusL, _("Loading Window Maker configuration files..."));
675 XFlush(WMScreenDisplay(scr));
676 loadConfigurations(scr, WPrefs.win);
678 WMSetLabelText(WPrefs.statusL, _("Initializing configuration panels..."));
680 InitFocus(scr, WPrefs.banner);
681 InitWindowHandling(scr, WPrefs.banner);
683 InitMenuPreferences(scr, WPrefs.banner);
684 InitIcons(scr, WPrefs.banner);
685 InitPreferences(scr, WPrefs.banner);
687 InitPaths(scr, WPrefs.banner);
688 InitWorkspace(scr, WPrefs.banner);
689 InitConfigurations(scr, WPrefs.banner);
691 InitMenu(scr, WPrefs.banner);
693 #ifdef not_yet_fully_implemented
694 InitKeyboardSettings(scr, WPrefs.banner);
695 #endif
696 InitKeyboardShortcuts(scr, WPrefs.banner);
697 InitMouseSettings(scr, WPrefs.banner);
699 InitAppearance(scr, WPrefs.banner);
701 InitFontSimple(scr, WPrefs.banner);
703 #ifdef not_yet_fully_implemented
704 InitThemes(scr, WPrefs.banner);
705 #endif
706 InitExpert(scr, WPrefs.banner);
708 WMRealizeWidget(WPrefs.scrollV);
710 WMSetLabelText(WPrefs.statusL, "");
714 WMWindow*
715 GetWindow(Panel *panel)
717 return WPrefs.win;
721 static void
722 loadConfigurations(WMScreen *scr, WMWindow *mainw)
724 WMPropList *db, *gdb;
725 char *path;
726 FILE *file;
727 char buffer[1024];
728 char mbuf[1024];
729 int v1, v2, v3;
731 path = wdefaultspathfordomain("WindowMaker");
732 WindowMakerDBPath = path;
734 db = WMReadPropListFromFile(path);
735 if (db) {
736 if (!WMIsPLDictionary(db)) {
737 WMReleasePropList(db);
738 db = NULL;
739 sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), path);
740 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
742 } else {
743 sprintf(mbuf, _("Could not load Window Maker domain (%s) from defaults database."),
744 path);
745 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
748 path = getenv("WMAKER_BIN_NAME");
749 if (!path)
750 path = "wmaker";
752 char *command;
754 command = wstrconcat(path, " --version");
755 file = popen(command, "r");
756 wfree(command);
758 if (!file || !fgets(buffer, 1023, file)) {
759 wsyserror(_("could not extract version information from Window Maker"));
760 wfatal(_("Make sure wmaker is in your search path."));
762 WMRunAlertPanel(scr, mainw, _("Error"),
763 _("Could not extract version from Window Maker. Make sure it is correctly installed and is in your PATH environment variable."),
764 _("OK"), NULL, NULL);
765 exit(1);
767 if (file)
768 pclose(file);
770 if (sscanf(buffer, "Window Maker %i.%i.%i",&v1,&v2,&v3)!=3
771 && sscanf(buffer, "WindowMaker %i.%i.%i",&v1,&v2,&v3)!=3) {
772 WMRunAlertPanel(scr, mainw, _("Error"),
773 _("Could not extract version from Window Maker. "
774 "Make sure it is correctly installed and the path "
775 "where it installed is in the PATH environment "
776 "variable."), _("OK"), NULL, NULL);
777 exit(1);
779 if (v1 == 0 && (v2 < 18 || v3 < 0)) {
780 sprintf(mbuf, _("WPrefs only supports Window Maker 0.18.0 or newer.\n"
781 "The version installed is %i.%i.%i\n"), v1, v2, v3);
782 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
783 exit(1);
786 if (v1 > 1 || (v1 == 1 && (v2 > 0))) {
787 sprintf(mbuf, _("Window Maker %i.%i.%i, which is installed in your system, is not fully supported by this version of WPrefs."),
788 v1, v2, v3);
789 WMRunAlertPanel(scr, mainw, _("Warning"), mbuf, _("OK"), NULL, NULL);
793 char *command;
795 command = wstrconcat(path, " --global_defaults_path");
796 file = popen(command, "r");
797 wfree(command);
799 if (!file || !fgets(buffer, 1023, file)) {
800 wsyserror(_("could not run \"%s --global_defaults_path\"."), path);
801 exit(1);
802 } else {
803 char *ptr;
804 ptr = strchr(buffer, '\n');
805 if (ptr)
806 *ptr = 0;
807 strcat(buffer, "/WindowMaker");
810 if (file)
811 pclose(file);
813 gdb = WMReadPropListFromFile(buffer);
815 if (gdb) {
816 if (!WMIsPLDictionary(gdb)) {
817 WMReleasePropList(gdb);
818 gdb = NULL;
819 sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), buffer);
820 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
822 } else {
823 sprintf(mbuf, _("Could not load global Window Maker domain (%s)."),
824 buffer);
825 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
828 if (!db) {
829 db = WMCreatePLDictionary(NULL, NULL);
831 if (!gdb) {
832 gdb = WMCreatePLDictionary(NULL, NULL);
835 GlobalDB = gdb;
837 WindowMakerDB = db;
841 WMPropList*
842 GetObjectForKey(char *defaultName)
844 WMPropList *object = NULL;
845 WMPropList *key = WMCreatePLString(defaultName);
847 object = WMGetFromPLDictionary(WindowMakerDB, key);
848 if (!object)
849 object = WMGetFromPLDictionary(GlobalDB, key);
851 WMReleasePropList(key);
853 return object;
857 void
858 SetObjectForKey(WMPropList *object, char *defaultName)
860 WMPropList *key = WMCreatePLString(defaultName);
862 WMPutInPLDictionary(WindowMakerDB, key, object);
863 WMReleasePropList(key);
867 void
868 RemoveObjectForKey(char *defaultName)
870 WMPropList *key = WMCreatePLString(defaultName);
872 WMRemoveFromPLDictionary(WindowMakerDB, key);
874 WMReleasePropList(key);
878 char*
879 GetStringForKey(char *defaultName)
881 WMPropList *val;
883 val = GetObjectForKey(defaultName);
885 if (!val)
886 return NULL;
888 if (!WMIsPLString(val))
889 return NULL;
891 return WMGetFromPLString(val);
896 WMPropList*
897 GetArrayForKey(char *defaultName)
899 WMPropList *val;
901 val = GetObjectForKey(defaultName);
903 if (!val)
904 return NULL;
906 if (!WMIsPLArray(val))
907 return NULL;
909 return val;
913 WMPropList*
914 GetDictionaryForKey(char *defaultName)
916 WMPropList *val;
918 val = GetObjectForKey(defaultName);
920 if (!val)
921 return NULL;
923 if (!WMIsPLDictionary(val))
924 return NULL;
926 return val;
931 GetIntegerForKey(char *defaultName)
933 WMPropList *val;
934 char *str;
935 int value;
937 val = GetObjectForKey(defaultName);
939 if (!val)
940 return 0;
942 if (!WMIsPLString(val))
943 return 0;
945 str = WMGetFromPLString(val);
946 if (!str)
947 return 0;
949 if (sscanf(str, "%i", &value)!=1)
950 return 0;
952 return value;
956 Bool
957 GetBoolForKey(char *defaultName)
959 int value;
960 char *str;
962 str = GetStringForKey(defaultName);
964 if (!str)
965 return False;
967 if (sscanf(str, "%i", &value)==1 && value!=0)
968 return True;
970 if (strcasecmp(str, "YES")==0)
971 return True;
973 if (strcasecmp(str, "Y")==0)
974 return True;
976 return False;
980 void
981 SetIntegerForKey(int value, char *defaultName)
983 WMPropList *object;
984 char buffer[128];
986 sprintf(buffer, "%i", value);
987 object = WMCreatePLString(buffer);
989 SetObjectForKey(object, defaultName);
990 WMReleasePropList(object);
995 void
996 SetStringForKey(char *value, char *defaultName)
998 WMPropList *object;
1000 object = WMCreatePLString(value);
1002 SetObjectForKey(object, defaultName);
1003 WMReleasePropList(object);
1007 void
1008 SetBoolForKey(Bool value, char *defaultName)
1010 static WMPropList *yes = NULL, *no = NULL;
1012 if (!yes) {
1013 yes = WMCreatePLString("YES");
1014 no = WMCreatePLString("NO");
1017 SetObjectForKey(value ? yes : no, defaultName);
1021 void
1022 SetSpeedForKey(int speed, char *defaultName)
1024 char *str;
1026 switch (speed) {
1027 case 0:
1028 str = "ultraslow";
1029 break;
1030 case 1:
1031 str = "slow";
1032 break;
1033 case 2:
1034 str = "medium";
1035 break;
1036 case 3:
1037 str = "fast";
1038 break;
1039 case 4:
1040 str = "ultrafast";
1041 break;
1042 default:
1043 str = NULL;
1046 if (str)
1047 SetStringForKey(str, defaultName);
1052 GetSpeedForKey(char *defaultName)
1054 char *str;
1055 int i;
1057 str = GetStringForKey(defaultName);
1058 if (!str)
1059 return 2;
1061 if (strcasecmp(str, "ultraslow")==0)
1062 i = 0;
1063 else if (strcasecmp(str, "slow")==0)
1064 i = 1;
1065 else if (strcasecmp(str, "medium")==0)
1066 i = 2;
1067 else if (strcasecmp(str, "fast")==0)
1068 i = 3;
1069 else if (strcasecmp(str, "ultrafast")==0)
1070 i = 4;
1071 else {
1072 wwarning(_("bad speed value for option %s\n. Using default Medium"),
1073 defaultName);
1074 i = 2;
1076 return i;