Small fix for wmaker nightly build script 2
[wmaker-crm.git] / WPrefs.app / WPrefs.c
blob5b956f1beebd5fdc376f118f5ddcb50b5c469c12
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.
23 #include "WPrefs.h"
24 #include <assert.h>
26 extern Panel *InitWindowHandling(WMScreen * scr, WMWidget * parent);
28 extern Panel *InitKeyboardSettings(WMScreen * scr, WMWidget * parent);
30 extern Panel *InitMouseSettings(WMScreen * scr, WMWidget * parent);
32 extern Panel *InitKeyboardShortcuts(WMScreen * scr, WMWidget * parent);
34 extern Panel *InitWorkspace(WMScreen * scr, WMWidget * parent);
36 extern Panel *InitFocus(WMScreen * scr, WMWidget * parent);
38 extern Panel *InitPreferences(WMScreen * scr, WMWidget * parent);
40 extern Panel *InitFont(WMScreen * scr, WMWidget * parent);
41 extern Panel *InitFontSimple(WMScreen * scr, WMWidget * parent);
43 extern Panel *InitConfigurations(WMScreen * scr, WMWidget * parent);
45 extern Panel *InitPaths(WMScreen * scr, WMWidget * parent);
47 extern Panel *InitMenu(WMScreen * scr, WMWidget * parent);
49 extern Panel *InitExpert(WMScreen * scr, WMWidget * parent);
51 extern Panel *InitMenuPreferences(WMScreen * scr, WMWidget * parent);
53 extern Panel *InitIcons(WMScreen * scr, WMWidget * parent);
55 extern Panel *InitThemes(WMScreen * scr, WMWidget * parent);
57 extern Panel *InitAppearance(WMScreen * scr, WMWidget * parent);
59 #define ICON_TITLE_FONT "sans serif:pixelsize=9"
60 #define ICON_TITLE_VFONT "sans serif:pixelsize=9:weight=100"
62 #define MAX_SECTIONS 16
64 typedef struct _WPrefs {
65 WMWindow *win;
67 WMScrollView *scrollV;
68 WMFrame *buttonF;
69 WMButton *sectionB[MAX_SECTIONS];
71 int sectionCount;
73 WMButton *saveBtn;
74 WMButton *closeBtn;
75 WMButton *undoBtn;
76 WMButton *undosBtn;
78 WMButton *balloonBtn;
80 WMFrame *banner;
81 WMLabel *nameL;
82 WMLabel *versionL;
83 WMLabel *statusL;
85 Panel *currentPanel;
86 } _WPrefs;
88 static _WPrefs WPrefs;
90 /* system wide defaults dictionary. Read-only */
91 static WMPropList *GlobalDB = NULL;
92 /* user defaults dictionary */
93 static WMPropList *WindowMakerDB = NULL;
94 static char *WindowMakerDBPath = NULL;
96 static Bool TIFFOK = False;
98 #define INITIALIZED_PANEL (1<<0)
100 static void loadConfigurations(WMScreen * scr, WMWindow * mainw);
102 static void savePanelData(Panel * panel);
104 static void prepareForClose();
106 void quit(WMWidget * w, void *data)
108 prepareForClose();
110 exit(0);
113 static void save(WMWidget * w, void *data)
115 int i;
116 WMPropList *p1, *p2;
117 WMPropList *keyList;
118 WMPropList *key;
119 char *msg = "Reconfigure";
120 XEvent ev;
122 /* puts("gathering data"); */
123 for (i = 0; i < WPrefs.sectionCount; i++) {
124 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
125 if ((rec->callbacks.flags & INITIALIZED_PANEL))
126 savePanelData((Panel *) rec);
128 /* puts("compressing data"); */
129 /* compare the user dictionary with the global and remove redundant data */
130 keyList = WMGetPLDictionaryKeys(GlobalDB);
131 /* puts(WMGetPropListDescription(WindowMakerDB, False)); */
132 for (i = 0; i < WMGetPropListItemCount(keyList); i++) {
133 key = WMGetFromPLArray(keyList, i);
135 /* We don't have this value anyway, so no problem.
136 * Probably a new option */
137 p1 = WMGetFromPLDictionary(WindowMakerDB, key);
138 if (!p1)
139 continue;
140 /* The global doesn't have it, so no problem either. */
141 p2 = WMGetFromPLDictionary(GlobalDB, key);
142 if (!p2)
143 continue;
144 /* If both values are the same, don't save. */
145 if (WMIsPropListEqualTo(p1, p2))
146 WMRemoveFromPLDictionary(WindowMakerDB, key);
148 /* puts(WMGetPropListDescription(WindowMakerDB, False)); */
149 WMReleasePropList(keyList);
150 /* puts("storing data"); */
152 WMWritePropListToFile(WindowMakerDB, WindowMakerDBPath, True);
154 memset(&ev, 0, sizeof(XEvent));
156 ev.xclient.type = ClientMessage;
157 ev.xclient.message_type = XInternAtom(WMScreenDisplay(WMWidgetScreen(w)), "_WINDOWMAKER_COMMAND", False);
158 ev.xclient.window = DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w)));
159 ev.xclient.format = 8;
161 for (i = 0; i <= strlen(msg); i++) {
162 ev.xclient.data.b[i] = msg[i];
164 XSendEvent(WMScreenDisplay(WMWidgetScreen(w)),
165 DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w))), False, SubstructureRedirectMask, &ev);
166 XFlush(WMScreenDisplay(WMWidgetScreen(w)));
169 static void undo(WMWidget * w, void *data)
171 PanelRec *rec = (PanelRec *) WPrefs.currentPanel;
173 if (!rec)
174 return;
176 if (rec->callbacks.undoChanges && (rec->callbacks.flags & INITIALIZED_PANEL)) {
177 (*rec->callbacks.undoChanges) (WPrefs.currentPanel);
181 static void undoAll(WMWidget * w, void *data)
183 int i;
185 for (i = 0; i < WPrefs.sectionCount; i++) {
186 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
188 if (rec->callbacks.undoChanges && (rec->callbacks.flags & INITIALIZED_PANEL))
189 (*rec->callbacks.undoChanges) ((Panel *) rec);
193 static void prepareForClose()
195 int i;
197 for (i = 0; i < WPrefs.sectionCount; i++) {
198 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
200 if (rec->callbacks.prepareForClose && (rec->callbacks.flags & INITIALIZED_PANEL))
201 (*rec->callbacks.prepareForClose) ((Panel *) rec);
205 void toggleBalloons(WMWidget * w, void *data)
207 WMUserDefaults *udb = WMGetStandardUserDefaults();
208 Bool flag;
210 flag = WMGetButtonSelected(WPrefs.balloonBtn);
212 WMSetBalloonEnabled(WMWidgetScreen(WPrefs.win), flag);
214 WMSetUDBoolForKey(udb, flag, "BalloonHelp");
217 static void createMainWindow(WMScreen * scr)
219 WMScroller *scroller;
220 WMFont *font;
221 char buffer[128];
223 WPrefs.win = WMCreateWindow(scr, "wprefs");
224 WMResizeWidget(WPrefs.win, 520, 390);
225 WMSetWindowTitle(WPrefs.win, _("Window Maker Preferences"));
226 WMSetWindowCloseAction(WPrefs.win, quit, NULL);
227 WMSetWindowMaxSize(WPrefs.win, 520, 390);
228 WMSetWindowMinSize(WPrefs.win, 520, 390);
229 WMSetWindowMiniwindowTitle(WPrefs.win, "Preferences");
231 WPrefs.scrollV = WMCreateScrollView(WPrefs.win);
232 WMResizeWidget(WPrefs.scrollV, 500, 87);
233 WMMoveWidget(WPrefs.scrollV, 10, 10);
234 WMSetScrollViewRelief(WPrefs.scrollV, WRSunken);
235 WMSetScrollViewHasHorizontalScroller(WPrefs.scrollV, True);
236 WMSetScrollViewHasVerticalScroller(WPrefs.scrollV, False);
237 scroller = WMGetScrollViewHorizontalScroller(WPrefs.scrollV);
238 WMSetScrollerArrowsPosition(scroller, WSANone);
240 WPrefs.buttonF = WMCreateFrame(WPrefs.win);
241 WMSetFrameRelief(WPrefs.buttonF, WRFlat);
243 WMSetScrollViewContentView(WPrefs.scrollV, WMWidgetView(WPrefs.buttonF));
245 WPrefs.undosBtn = WMCreateCommandButton(WPrefs.win);
246 WMResizeWidget(WPrefs.undosBtn, 90, 28);
247 WMMoveWidget(WPrefs.undosBtn, 135, 350);
248 WMSetButtonText(WPrefs.undosBtn, _("Revert Page"));
249 WMSetButtonAction(WPrefs.undosBtn, undo, NULL);
251 WPrefs.undoBtn = WMCreateCommandButton(WPrefs.win);
252 WMResizeWidget(WPrefs.undoBtn, 90, 28);
253 WMMoveWidget(WPrefs.undoBtn, 235, 350);
254 WMSetButtonText(WPrefs.undoBtn, _("Revert All"));
255 WMSetButtonAction(WPrefs.undoBtn, undoAll, NULL);
257 WPrefs.saveBtn = WMCreateCommandButton(WPrefs.win);
258 WMResizeWidget(WPrefs.saveBtn, 80, 28);
259 WMMoveWidget(WPrefs.saveBtn, 335, 350);
260 WMSetButtonText(WPrefs.saveBtn, _("Save"));
261 WMSetButtonAction(WPrefs.saveBtn, save, NULL);
263 WPrefs.closeBtn = WMCreateCommandButton(WPrefs.win);
264 WMResizeWidget(WPrefs.closeBtn, 80, 28);
265 WMMoveWidget(WPrefs.closeBtn, 425, 350);
266 WMSetButtonText(WPrefs.closeBtn, _("Close"));
267 WMSetButtonAction(WPrefs.closeBtn, quit, NULL);
269 WPrefs.balloonBtn = WMCreateSwitchButton(WPrefs.win);
270 WMResizeWidget(WPrefs.balloonBtn, 200, 28);
271 WMMoveWidget(WPrefs.balloonBtn, 15, 350);
272 WMSetButtonText(WPrefs.balloonBtn, _("Balloon Help"));
273 WMSetButtonAction(WPrefs.balloonBtn, toggleBalloons, NULL);
275 WMUserDefaults *udb = WMGetStandardUserDefaults();
276 Bool flag = WMGetUDBoolForKey(udb, "BalloonHelp");
278 WMSetButtonSelected(WPrefs.balloonBtn, flag);
279 WMSetBalloonEnabled(scr, flag);
282 /* banner */
283 WPrefs.banner = WMCreateFrame(WPrefs.win);
284 WMResizeWidget(WPrefs.banner, FRAME_WIDTH, FRAME_HEIGHT);
285 WMMoveWidget(WPrefs.banner, FRAME_LEFT, FRAME_TOP);
286 WMSetFrameRelief(WPrefs.banner, WRFlat);
288 font = WMCreateFont(scr, "Lucida Sans,URW Gothic L,Times New Roman,serif"
289 ":bold:pixelsize=26:antialias=true");
290 WPrefs.nameL = WMCreateLabel(WPrefs.banner);
291 WMSetLabelTextAlignment(WPrefs.nameL, WACenter);
292 WMResizeWidget(WPrefs.nameL, FRAME_WIDTH - 20, 60);
293 WMMoveWidget(WPrefs.nameL, 10, 50);
294 WMSetLabelFont(WPrefs.nameL, font);
295 WMSetLabelText(WPrefs.nameL, _("Window Maker Preferences"));
296 WMReleaseFont(font);
298 WPrefs.versionL = WMCreateLabel(WPrefs.banner);
299 WMResizeWidget(WPrefs.versionL, FRAME_WIDTH - 20, 20);
300 WMMoveWidget(WPrefs.versionL, 10, 120);
301 WMSetLabelTextAlignment(WPrefs.versionL, WACenter);
302 sprintf(buffer, _("Version %s"), VERSION);
303 WMSetLabelText(WPrefs.versionL, buffer);
305 WPrefs.statusL = WMCreateLabel(WPrefs.banner);
306 WMResizeWidget(WPrefs.statusL, FRAME_WIDTH - 20, 60);
307 WMMoveWidget(WPrefs.statusL, 10, 150);
308 WMSetLabelTextAlignment(WPrefs.statusL, WACenter);
309 WMSetLabelText(WPrefs.statusL, _("Starting..."));
311 WMMapSubwidgets(WPrefs.win);
313 WMUnmapWidget(WPrefs.undosBtn);
314 WMUnmapWidget(WPrefs.undoBtn);
315 WMUnmapWidget(WPrefs.saveBtn);
318 static void showPanel(Panel * panel)
320 PanelRec *rec = (PanelRec *) panel;
322 if (!(rec->callbacks.flags & INITIALIZED_PANEL)) {
323 (*rec->callbacks.createWidgets) (panel);
324 rec->callbacks.flags |= INITIALIZED_PANEL;
327 WMSetWindowTitle(WPrefs.win, rec->sectionName);
329 if (rec->callbacks.showPanel)
330 (*rec->callbacks.showPanel) (panel);
332 WMMapWidget(rec->box);
335 static void hidePanel(Panel * panel)
337 PanelRec *rec = (PanelRec *) panel;
339 WMUnmapWidget(rec->box);
341 if (rec->callbacks.hidePanel)
342 (*rec->callbacks.hidePanel) (panel);
345 static void savePanelData(Panel * panel)
347 PanelRec *rec = (PanelRec *) panel;
349 if (rec->callbacks.updateDomain) {
350 (*rec->callbacks.updateDomain) (panel);
354 static void changeSection(WMWidget * self, void *data)
356 if (WPrefs.currentPanel == data)
357 return;
359 if (WPrefs.currentPanel == NULL) {
360 WMDestroyWidget(WPrefs.nameL);
361 WMDestroyWidget(WPrefs.versionL);
362 WMDestroyWidget(WPrefs.statusL);
364 WMSetFrameRelief(WPrefs.banner, WRGroove);
366 /* WMMapWidget(WPrefs.undosBtn);
367 WMMapWidget(WPrefs.undoBtn);
369 WMMapWidget(WPrefs.saveBtn);
372 showPanel(data);
374 if (WPrefs.currentPanel)
375 hidePanel(WPrefs.currentPanel);
376 WPrefs.currentPanel = data;
379 char *LocateImage(char *name)
381 char *path;
382 char *tmp = wmalloc(strlen(name) + 8);
384 if (TIFFOK) {
385 sprintf(tmp, "%s.tiff", name);
386 path = WMPathForResourceOfType(tmp, "tiff");
387 } else {
388 sprintf(tmp, "%s.xpm", name);
389 path = WMPathForResourceOfType(tmp, "xpm");
391 wfree(tmp);
392 if (!path) {
393 wwarning(_("could not locate image file %s\n"), name);
396 return path;
399 static WMPixmap *makeTitledIcon(WMScreen * scr, WMPixmap * icon, char *title1, char *title2)
401 return WMRetainPixmap(icon);
403 #if 0
404 static GC gc = NULL;
405 static XFontStruct *hfont = NULL;
406 static XFontStruct *vfont = NULL;
407 WMPixmap *tmp;
408 Pixmap pix, mask;
409 Display *dpy = WMScreenDisplay(scr);
410 WMColor *black = WMBlackColor(scr);
411 GC fgc;
412 WMSize size = WMGetPixmapSize(icon);
414 tmp = WMCreatePixmap(scr, 60, 60, WMScreenDepth(scr), True);
416 pix = WMGetPixmapXID(tmp);
417 mask = WMGetPixmapMaskXID(tmp);
419 if (gc == NULL) {
420 gc = XCreateGC(dpy, mask, 0, NULL);
422 hfont = XLoadQueryFont(dpy, ICON_TITLE_FONT);
423 vfont = XLoadQueryFont(dpy, ICON_TITLE_VFONT);
426 if (hfont == NULL) {
427 return WMRetainPixmap(icon);
430 XSetForeground(dpy, gc, 0);
431 XFillRectangle(dpy, mask, gc, 0, 0, 60, 60);
433 fgc = WMColorGC(black);
435 XSetForeground(dpy, gc, 1);
437 XCopyArea(dpy, WMGetPixmapXID(icon), pix, fgc, 0, 0, size.width, size.height, 12, 12);
439 if (WMGetPixmapMaskXID(icon) != None)
440 XCopyPlane(dpy, WMGetPixmapMaskXID(icon), mask, gc, 0, 0, size.width, size.height, 12, 12, 1);
441 else
442 XFillRectangle(dpy, mask, gc, 12, 12, 48, 48);
444 if (title1) {
445 XSetFont(dpy, fgc, vfont->fid);
446 XSetFont(dpy, gc, vfont->fid);
448 XDrawString(dpy, pix, fgc, 0, vfont->ascent, title1, strlen(title1));
450 XDrawString(dpy, mask, gc, 0, vfont->ascent, title1, strlen(title1));
453 if (title2) {
454 XSetFont(dpy, fgc, hfont->fid);
455 XSetFont(dpy, gc, hfont->fid);
457 XDrawString(dpy, pix, fgc, (title1 ? 12 : 0), hfont->ascent, title2, strlen(title2));
459 XDrawString(dpy, mask, gc, (title1 ? 12 : 0), hfont->ascent, title2, strlen(title2));
462 return tmp;
463 #endif
466 void SetButtonAlphaImage(WMScreen * scr, WMButton * bPtr, char *file, char *title1, char *title2)
468 WMPixmap *icon;
469 WMPixmap *icon2;
470 RColor color;
471 char *iconPath;
473 iconPath = LocateImage(file);
475 color.red = 0xae;
476 color.green = 0xaa;
477 color.blue = 0xae;
478 color.alpha = 0;
479 if (iconPath) {
480 icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
481 if (!icon)
482 wwarning(_("could not load icon file %s"), iconPath);
483 } else {
484 icon = NULL;
487 if (icon) {
488 icon2 = makeTitledIcon(scr, icon, title1, title2);
489 if (icon)
490 WMReleasePixmap(icon);
491 } else {
492 icon2 = NULL;
495 WMSetButtonImage(bPtr, icon2);
497 if (icon2)
498 WMReleasePixmap(icon2);
500 color.red = 0xff;
501 color.green = 0xff;
502 color.blue = 0xff;
503 color.alpha = 0;
504 if (iconPath) {
505 icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
506 if (!icon)
507 wwarning(_("could not load icon file %s"), iconPath);
508 } else {
509 icon = NULL;
512 WMSetButtonAltImage(bPtr, icon);
514 if (icon)
515 WMReleasePixmap(icon);
517 if (iconPath)
518 wfree(iconPath);
521 void AddSection(Panel * panel, char *iconFile)
523 WMButton *bPtr;
525 assert(WPrefs.sectionCount < MAX_SECTIONS);
527 bPtr = WMCreateCustomButton(WPrefs.buttonF, WBBStateLightMask | WBBStateChangeMask);
528 WMResizeWidget(bPtr, 64, 64);
529 WMMoveWidget(bPtr, WPrefs.sectionCount * 64, 0);
530 WMSetButtonImagePosition(bPtr, WIPImageOnly);
531 WMSetButtonAction(bPtr, changeSection, panel);
532 WMHangData(bPtr, panel);
534 WMSetBalloonTextForView(((PanelRec *) panel)->description, WMWidgetView(bPtr));
537 char *t1, *t2;
539 t1 = wstrdup(((PanelRec *) panel)->sectionName);
540 t2 = strchr(t1, ' ');
541 if (t2) {
542 *t2 = 0;
543 t2++;
545 SetButtonAlphaImage(WMWidgetScreen(bPtr), bPtr, iconFile, t1, t2);
546 wfree(t1);
548 WMMapWidget(bPtr);
550 WPrefs.sectionB[WPrefs.sectionCount] = bPtr;
552 if (WPrefs.sectionCount > 0) {
553 WMGroupButtons(WPrefs.sectionB[0], bPtr);
556 WPrefs.sectionCount++;
558 WMResizeWidget(WPrefs.buttonF, WPrefs.sectionCount * 64, 64);
561 void Initialize(WMScreen * scr)
563 char **list;
564 int i;
565 char *path;
567 list = RSupportedFileFormats();
568 for (i = 0; list[i] != NULL; i++) {
569 if (strcmp(list[i], "TIFF") == 0) {
570 TIFFOK = True;
571 break;
575 if (TIFFOK)
576 path = WMPathForResourceOfType("WPrefs.tiff", NULL);
577 else
578 path = WMPathForResourceOfType("WPrefs.xpm", NULL);
579 if (path) {
580 RImage *tmp;
582 tmp = RLoadImage(WMScreenRContext(scr), path, 0);
583 if (!tmp) {
584 wwarning(_("could not load image file %s:%s"), path, RMessageForError(RErrorCode));
585 } else {
586 WMSetApplicationIconImage(scr, tmp);
587 RReleaseImage(tmp);
589 wfree(path);
592 memset(&WPrefs, 0, sizeof(_WPrefs));
593 createMainWindow(scr);
595 WMRealizeWidget(WPrefs.win);
597 WMSetWindowMiniwindowImage(WPrefs.win, WMGetApplicationIconImage(scr));
599 WMMapWidget(WPrefs.win);
600 XFlush(WMScreenDisplay(scr));
601 WMSetLabelText(WPrefs.statusL, _("Loading Window Maker configuration files..."));
602 XFlush(WMScreenDisplay(scr));
603 loadConfigurations(scr, WPrefs.win);
605 WMSetLabelText(WPrefs.statusL, _("Initializing configuration panels..."));
607 InitFocus(scr, WPrefs.banner);
608 InitWindowHandling(scr, WPrefs.banner);
610 InitMenuPreferences(scr, WPrefs.banner);
611 InitIcons(scr, WPrefs.banner);
612 InitPreferences(scr, WPrefs.banner);
614 InitPaths(scr, WPrefs.banner);
615 InitWorkspace(scr, WPrefs.banner);
616 InitConfigurations(scr, WPrefs.banner);
618 InitMenu(scr, WPrefs.banner);
620 #ifdef not_yet_fully_implemented
621 InitKeyboardSettings(scr, WPrefs.banner);
622 #endif
623 InitKeyboardShortcuts(scr, WPrefs.banner);
624 InitMouseSettings(scr, WPrefs.banner);
626 InitAppearance(scr, WPrefs.banner);
628 InitFontSimple(scr, WPrefs.banner);
630 #ifdef not_yet_fully_implemented
631 InitThemes(scr, WPrefs.banner);
632 #endif
633 InitExpert(scr, WPrefs.banner);
635 WMRealizeWidget(WPrefs.scrollV);
637 WMSetLabelText(WPrefs.statusL, "");
640 WMWindow *GetWindow(Panel * panel)
642 return WPrefs.win;
645 static void loadConfigurations(WMScreen * scr, WMWindow * mainw)
647 WMPropList *db, *gdb;
648 char *path;
649 FILE *file;
650 char buffer[1024];
651 char mbuf[1024];
652 int v1, v2, v3;
654 path = wdefaultspathfordomain("WindowMaker");
655 WindowMakerDBPath = path;
657 db = WMReadPropListFromFile(path);
658 if (db) {
659 if (!WMIsPLDictionary(db)) {
660 WMReleasePropList(db);
661 db = NULL;
662 sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), path);
663 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
665 } else {
666 sprintf(mbuf, _("Could not load Window Maker domain (%s) from defaults database."), path);
667 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
670 path = getenv("WMAKER_BIN_NAME");
671 if (!path)
672 path = "wmaker";
674 char *command;
676 command = wstrconcat(path, " --version");
677 file = popen(command, "r");
678 wfree(command);
680 if (!file || !fgets(buffer, 1023, file)) {
681 wsyserror(_("could not extract version information from Window Maker"));
682 wfatal(_("Make sure wmaker is in your search path."));
684 WMRunAlertPanel(scr, mainw, _("Error"),
686 ("Could not extract version from Window Maker. Make sure it is correctly installed and is in your PATH environment variable."),
687 _("OK"), NULL, NULL);
688 exit(1);
690 if (file)
691 pclose(file);
693 if (sscanf(buffer, "Window Maker %i.%i.%i", &v1, &v2, &v3) != 3
694 && sscanf(buffer, "WindowMaker %i.%i.%i", &v1, &v2, &v3) != 3) {
695 WMRunAlertPanel(scr, mainw, _("Error"),
696 _("Could not extract version from Window Maker. "
697 "Make sure it is correctly installed and the path "
698 "where it installed is in the PATH environment "
699 "variable."), _("OK"), NULL, NULL);
700 exit(1);
702 if (v1 == 0 && (v2 < 18 || v3 < 0)) {
703 sprintf(mbuf, _("WPrefs only supports Window Maker 0.18.0 or newer.\n"
704 "The version installed is %i.%i.%i\n"), v1, v2, v3);
705 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
706 exit(1);
709 if (v1 > 1 || (v1 == 1 && (v2 > 0))) {
710 sprintf(mbuf,
712 ("Window Maker %i.%i.%i, which is installed in your system, is not fully supported by this version of WPrefs."),
713 v1, v2, v3);
714 WMRunAlertPanel(scr, mainw, _("Warning"), mbuf, _("OK"), NULL, NULL);
718 char *command;
720 command = wstrconcat(path, " --global_defaults_path");
721 file = popen(command, "r");
722 wfree(command);
724 if (!file || !fgets(buffer, 1023, file)) {
725 wsyserror(_("could not run \"%s --global_defaults_path\"."), path);
726 exit(1);
727 } else {
728 char *ptr;
729 ptr = strchr(buffer, '\n');
730 if (ptr)
731 *ptr = 0;
732 strcat(buffer, "/WindowMaker");
735 if (file)
736 pclose(file);
738 gdb = WMReadPropListFromFile(buffer);
740 if (gdb) {
741 if (!WMIsPLDictionary(gdb)) {
742 WMReleasePropList(gdb);
743 gdb = NULL;
744 sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), buffer);
745 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
747 } else {
748 sprintf(mbuf, _("Could not load global Window Maker domain (%s)."), buffer);
749 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
752 if (!db) {
753 db = WMCreatePLDictionary(NULL, NULL);
755 if (!gdb) {
756 gdb = WMCreatePLDictionary(NULL, NULL);
759 GlobalDB = gdb;
761 WindowMakerDB = db;
764 WMPropList *GetObjectForKey(char *defaultName)
766 WMPropList *object = NULL;
767 WMPropList *key = WMCreatePLString(defaultName);
769 object = WMGetFromPLDictionary(WindowMakerDB, key);
770 if (!object)
771 object = WMGetFromPLDictionary(GlobalDB, key);
773 WMReleasePropList(key);
775 return object;
778 void SetObjectForKey(WMPropList * object, char *defaultName)
780 WMPropList *key = WMCreatePLString(defaultName);
782 WMPutInPLDictionary(WindowMakerDB, key, object);
783 WMReleasePropList(key);
786 void RemoveObjectForKey(char *defaultName)
788 WMPropList *key = WMCreatePLString(defaultName);
790 WMRemoveFromPLDictionary(WindowMakerDB, key);
792 WMReleasePropList(key);
795 char *GetStringForKey(char *defaultName)
797 WMPropList *val;
799 val = GetObjectForKey(defaultName);
801 if (!val)
802 return NULL;
804 if (!WMIsPLString(val))
805 return NULL;
807 return WMGetFromPLString(val);
810 WMPropList *GetArrayForKey(char *defaultName)
812 WMPropList *val;
814 val = GetObjectForKey(defaultName);
816 if (!val)
817 return NULL;
819 if (!WMIsPLArray(val))
820 return NULL;
822 return val;
825 WMPropList *GetDictionaryForKey(char *defaultName)
827 WMPropList *val;
829 val = GetObjectForKey(defaultName);
831 if (!val)
832 return NULL;
834 if (!WMIsPLDictionary(val))
835 return NULL;
837 return val;
840 int GetIntegerForKey(char *defaultName)
842 WMPropList *val;
843 char *str;
844 int value;
846 val = GetObjectForKey(defaultName);
848 if (!val)
849 return 0;
851 if (!WMIsPLString(val))
852 return 0;
854 str = WMGetFromPLString(val);
855 if (!str)
856 return 0;
858 if (sscanf(str, "%i", &value) != 1)
859 return 0;
861 return value;
864 Bool GetBoolForKey(char *defaultName)
866 int value;
867 char *str;
869 str = GetStringForKey(defaultName);
871 if (!str)
872 return False;
874 if (sscanf(str, "%i", &value) == 1 && value != 0)
875 return True;
877 if (strcasecmp(str, "YES") == 0)
878 return True;
880 if (strcasecmp(str, "Y") == 0)
881 return True;
883 return False;
886 void SetIntegerForKey(int value, char *defaultName)
888 WMPropList *object;
889 char buffer[128];
891 sprintf(buffer, "%i", value);
892 object = WMCreatePLString(buffer);
894 SetObjectForKey(object, defaultName);
895 WMReleasePropList(object);
898 void SetStringForKey(char *value, char *defaultName)
900 WMPropList *object;
902 object = WMCreatePLString(value);
904 SetObjectForKey(object, defaultName);
905 WMReleasePropList(object);
908 void SetBoolForKey(Bool value, char *defaultName)
910 static WMPropList *yes = NULL, *no = NULL;
912 if (!yes) {
913 yes = WMCreatePLString("YES");
914 no = WMCreatePLString("NO");
917 SetObjectForKey(value ? yes : no, defaultName);
920 void SetSpeedForKey(int speed, char *defaultName)
922 char *str;
924 switch (speed) {
925 case 0:
926 str = "ultraslow";
927 break;
928 case 1:
929 str = "slow";
930 break;
931 case 2:
932 str = "medium";
933 break;
934 case 3:
935 str = "fast";
936 break;
937 case 4:
938 str = "ultrafast";
939 break;
940 default:
941 str = NULL;
944 if (str)
945 SetStringForKey(str, defaultName);
948 int GetSpeedForKey(char *defaultName)
950 char *str;
951 int i;
953 str = GetStringForKey(defaultName);
954 if (!str)
955 return 2;
957 if (strcasecmp(str, "ultraslow") == 0)
958 i = 0;
959 else if (strcasecmp(str, "slow") == 0)
960 i = 1;
961 else if (strcasecmp(str, "medium") == 0)
962 i = 2;
963 else if (strcasecmp(str, "fast") == 0)
964 i = 3;
965 else if (strcasecmp(str, "ultrafast") == 0)
966 i = 4;
967 else {
968 wwarning(_("bad speed value for option %s\n. Using default Medium"), defaultName);
969 i = 2;
971 return i;