new icon change
[wmaker-crm.git] / WPrefs.app / WPrefs.c
blob4da15c9efa3f036900a6935860c771c0b52392bc
1 /* WPrefs.c- main window and other basic stuff
2 *
3 * WPrefs - Window Maker Preferences Program
4 *
5 * Copyright (c) 1998 Alfredo K. Kojima
6 *
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, WMWindow *win);
30 extern Panel *InitKeyboardSettings(WMScreen *scr, WMWindow *win);
32 extern Panel *InitMouseSettings(WMScreen *scr, WMWindow *win);
34 extern Panel *InitKeyboardShortcuts(WMScreen *scr, WMWindow *win);
36 extern Panel *InitWorkspace(WMScreen *scr, WMWindow *win);
38 extern Panel *InitFocus(WMScreen *scr, WMWindow *win);
40 extern Panel *InitPreferences(WMScreen *scr, WMWindow *win);
42 extern Panel *InitFont(WMScreen *scr, WMWindow *win);
44 extern Panel *InitConfigurations(WMScreen *scr, WMWindow *win);
46 extern Panel *InitPaths(WMScreen *scr, WMWindow *win);
48 extern Panel *InitMenu(WMScreen *scr, WMWindow *win);
50 extern Panel *InitExpert(WMScreen *scr, WMWindow *win);
52 extern Panel *InitMenuPreferences(WMScreen *scr, WMWindow *win);
54 extern Panel *InitIcons(WMScreen *scr, WMWindow *win);
56 extern Panel *InitThemes(WMScreen *scr, WMWindow *win);
58 extern Panel *InitAppearance(WMScreen *scr, WMWindow *win);
63 #define ICON_TITLE_FONT "-adobe-helvetica-bold-r-*-*-10-*"
64 #define ICON_TITLE_VFONT "-adobe-helvetica-bold-r-*-*-10-[]-*"
67 #define MAX_SECTIONS 16
70 typedef struct _WPrefs {
71 WMWindow *win;
73 WMScrollView *scrollV;
74 WMFrame *buttonF;
75 WMButton *sectionB[MAX_SECTIONS];
77 int sectionCount;
79 WMButton *saveBtn;
80 WMButton *closeBtn;
81 WMButton *undoBtn;
82 WMButton *undosBtn;
84 WMButton *balloonBtn;
86 WMFrame *banner;
87 WMLabel *nameL;
88 WMLabel *versionL;
89 WMLabel *creditsL;
90 WMLabel *statusL;
92 Panel *currentPanel;
93 } _WPrefs;
96 static _WPrefs WPrefs;
98 /* system wide defaults dictionary. Read-only */
99 static proplist_t GlobalDB = NULL;
100 /* user defaults dictionary */
101 static proplist_t WindowMakerDB = NULL;
104 static Bool TIFFOK = False;
107 #define INITIALIZED_PANEL (1<<0)
112 static void loadConfigurations(WMScreen *scr, WMWindow *mainw);
114 static void savePanelData(Panel *panel);
116 static void prepareForClose();
118 void
119 quit(WMWidget *w, void *data)
121 prepareForClose();
123 exit(0);
127 static void
128 save(WMWidget *w, void *data)
130 int i;
131 proplist_t p1, p2;
132 proplist_t keyList;
133 proplist_t key;
134 char *msg = "Reconfigure";
135 XEvent ev;
138 /* puts("gathering data");*/
139 for (i=0; i<WPrefs.sectionCount; i++) {
140 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
141 if ((rec->callbacks.flags & INITIALIZED_PANEL))
142 savePanelData((Panel*)rec);
144 /* puts("compressing data");*/
145 /* compare the user dictionary with the global and remove redundant data */
146 keyList = PLGetAllDictionaryKeys(GlobalDB);
147 /* puts(PLGetDescription(WindowMakerDB));*/
148 for (i=0; i<PLGetNumberOfElements(keyList); i++) {
149 key = PLGetArrayElement(keyList, i);
151 /* We don't have this value anyway, so no problem.
152 * Probably a new option */
153 p1 = PLGetDictionaryEntry(WindowMakerDB, key);
154 if (!p1)
155 continue;
156 /* The global doesn't have it, so no problem either. */
157 p2 = PLGetDictionaryEntry(GlobalDB, key);
158 if (!p2)
159 continue;
160 /* If both values are the same, don't save. */
161 if (PLIsEqual(p1, p2))
162 PLRemoveDictionaryEntry(WindowMakerDB, key);
164 /* puts(PLGetDescription(WindowMakerDB));*/
165 PLRelease(keyList);
166 /* puts("storing data");*/
168 PLSave(WindowMakerDB, YES);
171 memset(&ev, 0, sizeof(XEvent));
173 ev.xclient.type = ClientMessage;
174 ev.xclient.message_type = XInternAtom(WMScreenDisplay(WMWidgetScreen(w)),
175 "_WINDOWMAKER_COMMAND", False);
176 ev.xclient.window = DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w)));
177 ev.xclient.format = 8;
179 for (i = 0; i <= strlen(msg); i++) {
180 ev.xclient.data.b[i] = msg[i];
182 XSendEvent(WMScreenDisplay(WMWidgetScreen(w)),
183 DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w))),
184 False, SubstructureRedirectMask, &ev);
185 XFlush(WMScreenDisplay(WMWidgetScreen(w)));
190 static void
191 undo(WMWidget *w, void *data)
193 PanelRec *rec = (PanelRec*)WPrefs.currentPanel;
195 if (!rec)
196 return;
198 if (rec->callbacks.undoChanges
199 && (rec->callbacks.flags & INITIALIZED_PANEL)) {
200 (*rec->callbacks.undoChanges)(WPrefs.currentPanel);
205 static void
206 undoAll(WMWidget *w, void *data)
208 int i;
210 for (i=0; i<WPrefs.sectionCount; i++) {
211 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
213 if (rec->callbacks.undoChanges
214 && (rec->callbacks.flags & INITIALIZED_PANEL))
215 (*rec->callbacks.undoChanges)((Panel*)rec);
221 static void
222 prepareForClose()
224 int i;
226 for (i=0; i<WPrefs.sectionCount; i++) {
227 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
229 if (rec->callbacks.prepareForClose
230 && (rec->callbacks.flags & INITIALIZED_PANEL))
231 (*rec->callbacks.prepareForClose)((Panel*)rec);
236 void
237 toggleBalloons(WMWidget *w, void *data)
239 WMUserDefaults *udb = WMGetStandardUserDefaults();
240 Bool flag;
242 flag = WMGetButtonSelected(WPrefs.balloonBtn);
244 WMSetBalloonEnabled(WMWidgetScreen(WPrefs.win), flag);
246 WMSetUDBoolForKey(udb, flag, "BalloonHelp");
250 static void
251 createMainWindow(WMScreen *scr)
253 WMScroller *scroller;
254 WMFont *font;
255 char buffer[128];
257 WPrefs.win = WMCreateWindow(scr, "wprefs");
258 WMResizeWidget(WPrefs.win, 520, 390);
259 WMSetWindowTitle(WPrefs.win, _("Window Maker Preferences"));
260 WMSetWindowCloseAction(WPrefs.win, quit, NULL);
261 WMSetWindowMaxSize(WPrefs.win, 520, 390);
262 WMSetWindowMinSize(WPrefs.win, 520, 390);
263 WMSetWindowMiniwindowTitle(WPrefs.win, "Preferences");
264 WMSetWindowMiniwindowImage(WPrefs.win, WMGetApplicationIconImage(scr));
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, "-*-times-bold-r-*-*-24-*-*-*-*-*-*-*,"
325 "-*-fixed-medium-r-normal-*-24-*");
326 if (!font)
327 font = WMBoldSystemFontOfSize(scr, 24);
328 WPrefs.nameL = WMCreateLabel(WPrefs.banner);
329 WMSetLabelTextAlignment(WPrefs.nameL, WACenter);
330 WMResizeWidget(WPrefs.nameL, FRAME_WIDTH-20, 30);
331 WMMoveWidget(WPrefs.nameL, 10, 25);
332 WMSetLabelFont(WPrefs.nameL, font);
333 WMSetLabelText(WPrefs.nameL, _("Window Maker Preferences Utility"));
334 WMReleaseFont(font);
336 WPrefs.versionL = WMCreateLabel(WPrefs.banner);
337 WMResizeWidget(WPrefs.versionL, FRAME_WIDTH-20, 20);
338 WMMoveWidget(WPrefs.versionL, 10, 65);
339 WMSetLabelTextAlignment(WPrefs.versionL, WACenter);
340 sprintf(buffer, _("Version %s for Window Maker %s or newer"), WVERSION,
341 WMVERSION);
342 WMSetLabelText(WPrefs.versionL, buffer);
344 WPrefs.statusL = WMCreateLabel(WPrefs.banner);
345 WMResizeWidget(WPrefs.statusL, FRAME_WIDTH-20, 60);
346 WMMoveWidget(WPrefs.statusL, 10, 100);
347 WMSetLabelTextAlignment(WPrefs.statusL, WACenter);
348 WMSetLabelText(WPrefs.statusL, _("Starting..."));
350 WPrefs.creditsL = WMCreateLabel(WPrefs.banner);
351 WMResizeWidget(WPrefs.creditsL, FRAME_WIDTH-20, 60);
352 WMMoveWidget(WPrefs.creditsL, 10, FRAME_HEIGHT-60);
353 WMSetLabelTextAlignment(WPrefs.creditsL, WACenter);
354 WMSetLabelText(WPrefs.creditsL, _("Programming/Design: Alfredo K. Kojima\n"
355 "Artwork: Marco van Hylckama Vlieg and Largo\n"
356 "More Programming: James Thompson"));
359 WMMapSubwidgets(WPrefs.win);
361 WMUnmapWidget(WPrefs.undosBtn);
362 WMUnmapWidget(WPrefs.undoBtn);
363 WMUnmapWidget(WPrefs.saveBtn);
367 static void
368 showPanel(Panel *panel)
370 PanelRec *rec = (PanelRec*)panel;
372 if (!(rec->callbacks.flags & INITIALIZED_PANEL)) {
373 (*rec->callbacks.createWidgets)(panel);
374 rec->callbacks.flags |= INITIALIZED_PANEL;
377 WMSetWindowTitle(WPrefs.win, rec->sectionName);
379 WMMapWidget(rec->frame);
384 static void
385 hidePanel(Panel *panel)
387 PanelRec *rec = (PanelRec*)panel;
389 WMUnmapWidget(rec->frame);
393 static void
394 savePanelData(Panel *panel)
396 PanelRec *rec = (PanelRec*)panel;
398 if (rec->callbacks.updateDomain) {
399 (*rec->callbacks.updateDomain)(panel);
404 static void
405 changeSection(WMWidget *self, void *data)
407 if (WPrefs.banner) {
408 WMDestroyWidget(WPrefs.banner);
409 WPrefs.banner = NULL;
410 /* WMMapWidget(WPrefs.undosBtn);
411 WMMapWidget(WPrefs.undoBtn);
413 WMMapWidget(WPrefs.saveBtn);
416 showPanel(data);
418 if (WPrefs.currentPanel)
419 hidePanel(WPrefs.currentPanel);
420 WPrefs.currentPanel = data;
427 char*
428 LocateImage(char *name)
430 char *path;
431 char *tmp = wmalloc(strlen(name)+8);
433 if (TIFFOK) {
434 sprintf(tmp, "%s.tiff", name);
435 path = WMPathForResourceOfType(tmp, "tiff");
436 } else {
437 sprintf(tmp, "%s.xpm", name);
438 path = WMPathForResourceOfType(tmp, "xpm");
440 free(tmp);
441 if (!path) {
442 wwarning(_("could not locate image file %s\n"), name);
445 return path;
450 static WMPixmap*
451 makeTitledIcon(WMScreen *scr, WMPixmap *icon, char *title1, char *title2)
453 return WMRetainPixmap(icon);
455 #if 0
456 static GC gc = NULL;
457 static XFontStruct *hfont = NULL;
458 static XFontStruct *vfont = NULL;
459 WMPixmap *tmp;
460 Pixmap pix, mask;
461 Display *dpy = WMScreenDisplay(scr);
462 WMColor *black = WMBlackColor(scr);
463 GC fgc;
464 WMSize size = WMGetPixmapSize(icon);
467 tmp = WMCreatePixmap(scr, 60, 60, WMScreenDepth(scr), True);
469 pix = WMGetPixmapXID(tmp);
470 mask = WMGetPixmapMaskXID(tmp);
472 if (gc == NULL) {
473 gc = XCreateGC(dpy, mask, 0, NULL);
475 hfont = XLoadQueryFont(dpy, ICON_TITLE_FONT);
476 vfont = XLoadQueryFont(dpy, ICON_TITLE_VFONT);
479 if (hfont == NULL) {
480 return WMRetainPixmap(icon);
483 XSetForeground(dpy, gc, 0);
484 XFillRectangle(dpy, mask, gc, 0, 0, 60, 60);
486 fgc = WMColorGC(black);
488 XSetForeground(dpy, gc, 1);
490 XCopyArea(dpy, WMGetPixmapXID(icon), pix, fgc, 0, 0,
491 size.width, size.height, 12, 12);
493 if (WMGetPixmapMaskXID(icon) != None)
494 XCopyPlane(dpy, WMGetPixmapMaskXID(icon), mask, gc, 0, 0,
495 size.width, size.height, 12, 12, 1);
496 else
497 XFillRectangle(dpy, mask, gc, 12, 12, 48, 48);
500 if (title1) {
501 XSetFont(dpy, fgc, vfont->fid);
502 XSetFont(dpy, gc, vfont->fid);
504 XDrawString(dpy, pix, fgc, 0, vfont->ascent,
505 title1, strlen(title1));
507 XDrawString(dpy, mask, gc, 0, vfont->ascent,
508 title1, strlen(title1));
511 if (title2) {
512 XSetFont(dpy, fgc, hfont->fid);
513 XSetFont(dpy, gc, hfont->fid);
515 XDrawString(dpy, pix, fgc, (title1 ? 12 : 0), hfont->ascent,
516 title2, strlen(title2));
518 XDrawString(dpy, mask, gc, (title1 ? 12 : 0), hfont->ascent,
519 title2, strlen(title2));
522 return tmp;
523 #endif
527 void
528 SetButtonAlphaImage(WMScreen *scr, WMButton *bPtr, char *file,
529 char *title1, char *title2)
531 WMPixmap *icon;
532 WMPixmap *icon2;
533 RColor color;
534 char *iconPath;
536 iconPath = LocateImage(file);
538 color.red = 0xae;
539 color.green = 0xaa;
540 color.blue = 0xae;
541 color.alpha = 0;
542 if (iconPath) {
543 icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
544 if (!icon)
545 wwarning(_("could not load icon file %s"), iconPath);
546 } else {
547 icon = NULL;
550 if (icon) {
551 icon2 = makeTitledIcon(scr, icon, title1, title2);
552 if (icon)
553 WMReleasePixmap(icon);
554 } else {
555 icon2 = NULL;
558 WMSetButtonImage(bPtr, icon2);
560 if (icon2)
561 WMReleasePixmap(icon2);
563 color.red = 0xff;
564 color.green = 0xff;
565 color.blue = 0xff;
566 color.alpha = 0;
567 if (iconPath) {
568 icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
569 if (!icon)
570 wwarning(_("could not load icon file %s"), iconPath);
571 } else {
572 icon = NULL;
575 WMSetButtonAltImage(bPtr, icon);
577 if (icon)
578 WMReleasePixmap(icon);
580 if (iconPath)
581 free(iconPath);
585 void
586 AddSection(Panel *panel, char *iconFile)
588 WMButton *bPtr;
590 assert(WPrefs.sectionCount < MAX_SECTIONS);
593 bPtr = WMCreateCustomButton(WPrefs.buttonF, WBBStateLightMask
594 |WBBStateChangeMask);
595 WMResizeWidget(bPtr, 64, 64);
596 WMMoveWidget(bPtr, WPrefs.sectionCount*64, 0);
597 WMSetButtonImagePosition(bPtr, WIPImageOnly);
598 WMSetButtonAction(bPtr, changeSection, panel);
599 WMHangData(bPtr, panel);
601 WMSetBalloonTextForView(((PanelRec*)panel)->description,
602 WMWidgetView(bPtr));
605 char *t1, *t2;
607 t1 = wstrdup(((PanelRec*)panel)->sectionName);
608 t2 = strchr(t1, ' ');
609 if (t2) {
610 *t2 = 0;
611 t2++;
613 SetButtonAlphaImage(WMWidgetScreen(bPtr), bPtr, iconFile,
614 t1, t2);
615 free(t1);
617 WMMapWidget(bPtr);
619 WPrefs.sectionB[WPrefs.sectionCount] = bPtr;
621 if (WPrefs.sectionCount > 0) {
622 WMGroupButtons(WPrefs.sectionB[0], bPtr);
625 WPrefs.sectionCount++;
627 WMResizeWidget(WPrefs.buttonF, WPrefs.sectionCount*64, 64);
631 void
632 Initialize(WMScreen *scr)
634 char **list;
635 int i;
636 char *path;
637 WMPixmap *icon;
640 list = RSupportedFileFormats();
641 for (i=0; list[i]!=NULL; i++) {
642 if (strcmp(list[i], "TIFF")==0) {
643 TIFFOK = True;
644 break;
648 if (TIFFOK)
649 path = WMPathForResourceOfType("WPrefs.tiff", NULL);
650 else
651 path = WMPathForResourceOfType("WPrefs.xpm", NULL);
652 if (path) {
653 RImage *tmp;
655 tmp = RLoadImage(WMScreenRContext(scr), path, 0);
656 if (!tmp) {
657 wwarning(_("could not load image file %s:%s"), path,
658 RMessageForError(RErrorCode));
659 } else {
660 icon = WMCreatePixmapFromRImage(scr, tmp, 0);
661 RDestroyImage(tmp);
662 if (icon) {
663 WMSetApplicationIconImage(scr, icon);
664 WMReleasePixmap(icon);
667 free(path);
670 memset(&WPrefs, 0, sizeof(_WPrefs));
671 createMainWindow(scr);
673 WMRealizeWidget(WPrefs.win);
674 WMMapWidget(WPrefs.win);
675 XFlush(WMScreenDisplay(scr));
676 WMSetLabelText(WPrefs.statusL, _("Loading Window Maker configuration files..."));
677 XFlush(WMScreenDisplay(scr));
678 loadConfigurations(scr, WPrefs.win);
680 WMSetLabelText(WPrefs.statusL, _("Initializing configuration panels..."));
682 InitWindowHandling(scr, WPrefs.win);
683 InitFocus(scr, WPrefs.win);
684 InitMenuPreferences(scr, WPrefs.win);
685 InitIcons(scr, WPrefs.win);
686 InitPreferences(scr, WPrefs.win);
688 InitPaths(scr, WPrefs.win);
689 InitWorkspace(scr, WPrefs.win);
690 InitConfigurations(scr, WPrefs.win);
692 InitMenu(scr, WPrefs.win);
694 #ifdef not_yet_fully_implemented
695 InitKeyboardSettings(scr, WPrefs.win);
696 #endif
697 InitKeyboardShortcuts(scr, WPrefs.win);
698 InitMouseSettings(scr, WPrefs.win);
700 InitAppearance(scr, WPrefs.win);
702 #ifdef akk
703 InitFont(scr, WPrefs.win);
704 #endif
705 #ifdef not_yet_fully_implemented
706 InitThemes(scr, WPrefs.win);
707 #endif
708 InitExpert(scr, WPrefs.win);
710 WMRealizeWidget(WPrefs.scrollV);
712 WMSetLabelText(WPrefs.statusL,
713 _("WPrefs is free software and is distributed WITHOUT ANY\n"
714 "WARRANTY under the terms of the GNU General Public License.\n"
715 "The icons in this program are licensed through the\n"
716 "OpenContent License."));
720 WMWindow*
721 GetWindow(Panel *panel)
723 return WPrefs.win;
727 static void
728 loadConfigurations(WMScreen *scr, WMWindow *mainw)
730 proplist_t db, gdb;
731 char *path;
732 FILE *file;
733 char buffer[1024];
734 char mbuf[1024];
735 int v1, v2, v3;
737 path = wdefaultspathfordomain("WindowMaker");
739 db = PLGetProplistWithPath(path);
740 if (db) {
741 if (!PLIsDictionary(db)) {
742 PLRelease(db);
743 db = NULL;
744 sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), path);
745 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
747 } else {
748 sprintf(mbuf, _("Could not load Window Maker domain (%s) from defaults database."),
749 path);
750 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
752 free(path);
754 path = getenv("WMAKER_BIN_NAME");
755 if (!path)
756 path = "wmaker";
757 path = wstrappend(path, " --version");
759 file = popen(path, "r");
760 if (!file || !fgets(buffer, 1023, file)) {
761 wsyserror(_("could not extract version information from Window Maker"));
762 wfatal(_("Make sure wmaker is in your search path."));
764 WMRunAlertPanel(scr, mainw, _("Error"),
765 _("Could not extract version from Window Maker. Make sure it is correctly installed and is in your PATH environment variable."),
766 _("OK"), NULL, NULL);
767 exit(1);
769 if (file)
770 pclose(file);
772 if (sscanf(buffer, "Window Maker %i.%i.%i",&v1,&v2,&v3)!=3
773 && sscanf(buffer, "WindowMaker %i.%i.%i",&v1,&v2,&v3)!=3) {
774 WMRunAlertPanel(scr, mainw, _("Error"),
775 _("Could not extract version from Window Maker. "
776 "Make sure it is correctly installed and the path "
777 "where it installed is in the PATH environment "
778 "variable."), _("OK"), NULL, NULL);
779 exit(1);
781 if (v1 == 0 && (v2 < 18 || v3 < 0)) {
782 sprintf(mbuf, _("WPrefs only supports Window Maker 0.18.0 or newer.\n"
783 "The version installed is %i.%i.%i\n"), v1, v2, v3);
784 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
785 exit(1);
788 if (v1 > 1 || (v1 == 1 && (v2 > 0))) {
789 sprintf(mbuf, _("Window Maker %i.%i.%i, which is installed in your system, is not fully supported by this version of WPrefs."),
790 v1, v2, v3);
791 WMRunAlertPanel(scr, mainw, _("Warning"), mbuf, _("OK"), NULL, NULL);
794 file = popen("wmaker --global_defaults_path", "r");
795 if (!file || !fgets(buffer, 1023, file)) {
796 wsyserror(_("could not run \"wmaker --global_defaults_path\"."));
797 exit(1);
798 } else {
799 char *ptr;
800 ptr = strchr(buffer, '\n');
801 if (ptr)
802 *ptr = 0;
803 strcat(buffer, "/WindowMaker");
806 if (file)
807 pclose(file);
809 gdb = PLGetProplistWithPath(buffer);
810 if (gdb) {
811 if (!PLIsDictionary(gdb)) {
812 PLRelease(gdb);
813 gdb = NULL;
814 sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), buffer);
815 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
817 } else {
818 sprintf(mbuf, _("Could not load global Window Maker domain (%s)."),
819 buffer);
820 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
823 if (!db) {
824 db = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
826 if (!gdb) {
827 gdb = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
830 GlobalDB = gdb;
832 WindowMakerDB = db;
836 proplist_t
837 GetObjectForKey(char *defaultName)
839 proplist_t object = NULL;
840 proplist_t key = PLMakeString(defaultName);
842 object = PLGetDictionaryEntry(WindowMakerDB, key);
843 if (!object)
844 object = PLGetDictionaryEntry(GlobalDB, key);
846 PLRelease(key);
848 return object;
852 void
853 SetObjectForKey(proplist_t object, char *defaultName)
855 proplist_t key = PLMakeString(defaultName);
857 PLInsertDictionaryEntry(WindowMakerDB, key, object);
858 PLRelease(key);
862 void
863 RemoveObjectForKey(char *defaultName)
865 proplist_t key = PLMakeString(defaultName);
867 PLRemoveDictionaryEntry(WindowMakerDB, key);
869 PLRelease(key);
873 char*
874 GetStringForKey(char *defaultName)
876 proplist_t val;
878 val = GetObjectForKey(defaultName);
880 if (!val)
881 return NULL;
883 if (!PLIsString(val))
884 return NULL;
886 return PLGetString(val);
891 proplist_t
892 GetArrayForKey(char *defaultName)
894 proplist_t val;
896 val = GetObjectForKey(defaultName);
898 if (!val)
899 return NULL;
901 if (!PLIsArray(val))
902 return NULL;
904 return val;
908 proplist_t
909 GetDictionaryForKey(char *defaultName)
911 proplist_t val;
913 val = GetObjectForKey(defaultName);
915 if (!val)
916 return NULL;
918 if (!PLIsDictionary(val))
919 return NULL;
921 return val;
926 GetIntegerForKey(char *defaultName)
928 proplist_t val;
929 char *str;
930 int value;
932 val = GetObjectForKey(defaultName);
934 if (!val)
935 return 0;
937 if (!PLIsString(val))
938 return 0;
940 str = PLGetString(val);
941 if (!str)
942 return 0;
944 if (sscanf(str, "%i", &value)!=1)
945 return 0;
947 return value;
951 Bool
952 GetBoolForKey(char *defaultName)
954 int value;
955 char *str;
957 str = GetStringForKey(defaultName);
959 if (!str)
960 return False;
962 if (sscanf(str, "%i", &value)==1 && value!=0)
963 return True;
965 if (strcasecmp(str, "YES")==0)
966 return True;
968 if (strcasecmp(str, "Y")==0)
969 return True;
971 return False;
975 void
976 SetIntegerForKey(int value, char *defaultName)
978 proplist_t object;
979 char buffer[128];
981 sprintf(buffer, "%i", value);
982 object = PLMakeString(buffer);
984 SetObjectForKey(object, defaultName);
985 PLRelease(object);
990 void
991 SetStringForKey(char *value, char *defaultName)
993 proplist_t object;
995 object = PLMakeString(value);
997 SetObjectForKey(object, defaultName);
998 PLRelease(object);
1002 void
1003 SetBoolForKey(Bool value, char *defaultName)
1005 static proplist_t yes = NULL, no = NULL;
1007 if (!yes) {
1008 yes = PLMakeString("YES");
1009 no = PLMakeString("NO");
1012 SetObjectForKey(value ? yes : no, defaultName);
1016 void
1017 SetSpeedForKey(int speed, char *defaultName)
1019 char *str;
1021 switch (speed) {
1022 case 0:
1023 str = "ultraslow";
1024 break;
1025 case 1:
1026 str = "slow";
1027 break;
1028 case 2:
1029 str = "medium";
1030 break;
1031 case 3:
1032 str = "fast";
1033 break;
1034 case 4:
1035 str = "ultrafast";
1036 break;
1037 default:
1038 str = NULL;
1041 if (str)
1042 SetStringForKey(str, defaultName);
1047 GetSpeedForKey(char *defaultName)
1049 char *str;
1050 int i;
1052 str = GetStringForKey(defaultName);
1053 if (!str)
1054 return 2;
1056 if (strcasecmp(str, "ultraslow")==0)
1057 i = 0;
1058 else if (strcasecmp(str, "slow")==0)
1059 i = 1;
1060 else if (strcasecmp(str, "medium")==0)
1061 i = 2;
1062 else if (strcasecmp(str, "fast")==0)
1063 i = 3;
1064 else if (strcasecmp(str, "ultrafast")==0)
1065 i = 4;
1066 else {
1067 wwarning(_("bad speed value for option %s\n. Using default Medium"),
1068 defaultName);
1069 i = 2;
1071 return i;