- rewrote the font conversion routines to avoid the need to allocate memory
[wmaker-crm.git] / WPrefs.app / WPrefs.c
blobf25853ebb537a464a28fa09f47e7628b770459b3
1 /* WPrefs.c- main window and other basic stuff
2 *
3 * WPrefs - Window Maker Preferences Program
4 *
5 * Copyright (c) 1998-2003 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, 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);
44 extern Panel *InitConfigurations(WMScreen *scr, WMWidget *parent);
46 extern Panel *InitPaths(WMScreen *scr, WMWidget *parent);
48 extern Panel *InitMenu(WMScreen *scr, WMWidget *parent);
50 extern Panel *InitExpert(WMScreen *scr, WMWidget *parent);
52 extern Panel *InitMenuPreferences(WMScreen *scr, WMWidget *parent);
54 extern Panel *InitIcons(WMScreen *scr, WMWidget *parent);
56 extern Panel *InitThemes(WMScreen *scr, WMWidget *parent);
58 extern Panel *InitAppearance(WMScreen *scr, WMWidget *parent);
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 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");
265 WMSetWindowMiniwindowPixmap(WPrefs.win, WMGetApplicationIconPixmap(scr));
267 WPrefs.scrollV = WMCreateScrollView(WPrefs.win);
268 WMResizeWidget(WPrefs.scrollV, 500, 87);
269 WMMoveWidget(WPrefs.scrollV, 10, 10);
270 WMSetScrollViewRelief(WPrefs.scrollV, WRSunken);
271 WMSetScrollViewHasHorizontalScroller(WPrefs.scrollV, True);
272 WMSetScrollViewHasVerticalScroller(WPrefs.scrollV, False);
273 scroller = WMGetScrollViewHorizontalScroller(WPrefs.scrollV);
274 WMSetScrollerArrowsPosition(scroller, WSANone);
276 WPrefs.buttonF = WMCreateFrame(WPrefs.win);
277 WMSetFrameRelief(WPrefs.buttonF, WRFlat);
279 WMSetScrollViewContentView(WPrefs.scrollV, WMWidgetView(WPrefs.buttonF));
281 WPrefs.undosBtn = WMCreateCommandButton(WPrefs.win);
282 WMResizeWidget(WPrefs.undosBtn, 90, 28);
283 WMMoveWidget(WPrefs.undosBtn, 135, 350);
284 WMSetButtonText(WPrefs.undosBtn, _("Revert Page"));
285 WMSetButtonAction(WPrefs.undosBtn, undo, NULL);
287 WPrefs.undoBtn = WMCreateCommandButton(WPrefs.win);
288 WMResizeWidget(WPrefs.undoBtn, 90, 28);
289 WMMoveWidget(WPrefs.undoBtn, 235, 350);
290 WMSetButtonText(WPrefs.undoBtn, _("Revert All"));
291 WMSetButtonAction(WPrefs.undoBtn, undoAll, NULL);
293 WPrefs.saveBtn = WMCreateCommandButton(WPrefs.win);
294 WMResizeWidget(WPrefs.saveBtn, 80, 28);
295 WMMoveWidget(WPrefs.saveBtn, 335, 350);
296 WMSetButtonText(WPrefs.saveBtn, _("Save"));
297 WMSetButtonAction(WPrefs.saveBtn, save, NULL);
299 WPrefs.closeBtn = WMCreateCommandButton(WPrefs.win);
300 WMResizeWidget(WPrefs.closeBtn, 80, 28);
301 WMMoveWidget(WPrefs.closeBtn, 425, 350);
302 WMSetButtonText(WPrefs.closeBtn, _("Close"));
303 WMSetButtonAction(WPrefs.closeBtn, quit, NULL);
306 WPrefs.balloonBtn = WMCreateSwitchButton(WPrefs.win);
307 WMResizeWidget(WPrefs.balloonBtn, 200, 28);
308 WMMoveWidget(WPrefs.balloonBtn, 15, 350);
309 WMSetButtonText(WPrefs.balloonBtn, _("Balloon Help"));
310 WMSetButtonAction(WPrefs.balloonBtn, toggleBalloons, NULL);
312 WMUserDefaults *udb = WMGetStandardUserDefaults();
313 Bool flag = WMGetUDBoolForKey(udb, "BalloonHelp");
315 WMSetButtonSelected(WPrefs.balloonBtn, flag);
316 WMSetBalloonEnabled(scr, flag);
319 /* banner */
320 WPrefs.banner = WMCreateFrame(WPrefs.win);
321 WMResizeWidget(WPrefs.banner, FRAME_WIDTH, FRAME_HEIGHT);
322 WMMoveWidget(WPrefs.banner, FRAME_LEFT, FRAME_TOP);
323 WMSetFrameRelief(WPrefs.banner, WRFlat);
325 font = WMCreateFont(scr, "-*-times-bold-r-*-*-24-*-*-*-*-*-*-*,"
326 "-*-fixed-medium-r-normal-*-24-*");
327 if (!font)
328 font = WMBoldSystemFontOfSize(scr, 24);
329 WPrefs.nameL = WMCreateLabel(WPrefs.banner);
330 WMSetLabelTextAlignment(WPrefs.nameL, WACenter);
331 WMResizeWidget(WPrefs.nameL, FRAME_WIDTH-20, 30);
332 WMMoveWidget(WPrefs.nameL, 10, 25);
333 WMSetLabelFont(WPrefs.nameL, font);
334 WMSetLabelText(WPrefs.nameL, _("Window Maker Preferences Utility"));
335 WMReleaseFont(font);
337 WPrefs.versionL = WMCreateLabel(WPrefs.banner);
338 WMResizeWidget(WPrefs.versionL, FRAME_WIDTH-20, 20);
339 WMMoveWidget(WPrefs.versionL, 10, 65);
340 WMSetLabelTextAlignment(WPrefs.versionL, WACenter);
341 sprintf(buffer, _("Version %s for Window Maker %s or newer"), WVERSION,
342 WMVERSION);
343 WMSetLabelText(WPrefs.versionL, buffer);
345 WPrefs.statusL = WMCreateLabel(WPrefs.banner);
346 WMResizeWidget(WPrefs.statusL, FRAME_WIDTH-20, 60);
347 WMMoveWidget(WPrefs.statusL, 10, 100);
348 WMSetLabelTextAlignment(WPrefs.statusL, WACenter);
349 WMSetLabelText(WPrefs.statusL, _("Starting..."));
351 WPrefs.creditsL = WMCreateLabel(WPrefs.banner);
352 WMResizeWidget(WPrefs.creditsL, FRAME_WIDTH-20, 60);
353 WMMoveWidget(WPrefs.creditsL, 10, FRAME_HEIGHT-60);
354 WMSetLabelTextAlignment(WPrefs.creditsL, WACenter);
355 WMSetLabelText(WPrefs.creditsL, _("Programming/Design: Alfredo K. Kojima\n"
356 "Artwork: Marco van Hylckama Vlieg, Largo et al\n"
357 "More Programming: James Thompson et al"));
360 WMMapSubwidgets(WPrefs.win);
362 WMUnmapWidget(WPrefs.undosBtn);
363 WMUnmapWidget(WPrefs.undoBtn);
364 WMUnmapWidget(WPrefs.saveBtn);
368 static void
369 showPanel(Panel *panel)
371 PanelRec *rec = (PanelRec*)panel;
373 if (!(rec->callbacks.flags & INITIALIZED_PANEL)) {
374 (*rec->callbacks.createWidgets)(panel);
375 rec->callbacks.flags |= INITIALIZED_PANEL;
378 WMSetWindowTitle(WPrefs.win, rec->sectionName);
380 if (rec->callbacks.showPanel)
381 (*rec->callbacks.showPanel)(panel);
383 WMMapWidget(rec->box);
388 static void
389 hidePanel(Panel *panel)
391 PanelRec *rec = (PanelRec*)panel;
393 WMUnmapWidget(rec->box);
395 if (rec->callbacks.hidePanel)
396 (*rec->callbacks.hidePanel)(panel);
400 static void
401 savePanelData(Panel *panel)
403 PanelRec *rec = (PanelRec*)panel;
405 if (rec->callbacks.updateDomain) {
406 (*rec->callbacks.updateDomain)(panel);
411 static void
412 changeSection(WMWidget *self, void *data)
414 if (WPrefs.currentPanel == data)
415 return;
417 if (WPrefs.currentPanel == NULL) {
418 WMDestroyWidget(WPrefs.nameL);
419 WMDestroyWidget(WPrefs.creditsL);
420 WMDestroyWidget(WPrefs.versionL);
421 WMDestroyWidget(WPrefs.statusL);
423 WMSetFrameRelief(WPrefs.banner, WRGroove);
425 /* WMMapWidget(WPrefs.undosBtn);
426 WMMapWidget(WPrefs.undoBtn);
428 WMMapWidget(WPrefs.saveBtn);
431 showPanel(data);
433 if (WPrefs.currentPanel)
434 hidePanel(WPrefs.currentPanel);
435 WPrefs.currentPanel = data;
440 char*
441 LocateImage(char *name)
443 char *path;
444 char *tmp = wmalloc(strlen(name)+8);
446 if (TIFFOK) {
447 sprintf(tmp, "%s.tiff", name);
448 path = WMPathForResourceOfType(tmp, "tiff");
449 } else {
450 sprintf(tmp, "%s.xpm", name);
451 path = WMPathForResourceOfType(tmp, "xpm");
453 wfree(tmp);
454 if (!path) {
455 wwarning(_("could not locate image file %s\n"), name);
458 return path;
463 static WMPixmap*
464 makeTitledIcon(WMScreen *scr, WMPixmap *icon, char *title1, char *title2)
466 return WMRetainPixmap(icon);
468 #if 0
469 static GC gc = NULL;
470 static XFontStruct *hfont = NULL;
471 static XFontStruct *vfont = NULL;
472 WMPixmap *tmp;
473 Pixmap pix, mask;
474 Display *dpy = WMScreenDisplay(scr);
475 WMColor *black = WMBlackColor(scr);
476 GC fgc;
477 WMSize size = WMGetPixmapSize(icon);
480 tmp = WMCreatePixmap(scr, 60, 60, WMScreenDepth(scr), True);
482 pix = WMGetPixmapXID(tmp);
483 mask = WMGetPixmapMaskXID(tmp);
485 if (gc == NULL) {
486 gc = XCreateGC(dpy, mask, 0, NULL);
488 hfont = XLoadQueryFont(dpy, ICON_TITLE_FONT);
489 vfont = XLoadQueryFont(dpy, ICON_TITLE_VFONT);
492 if (hfont == NULL) {
493 return WMRetainPixmap(icon);
496 XSetForeground(dpy, gc, 0);
497 XFillRectangle(dpy, mask, gc, 0, 0, 60, 60);
499 fgc = WMColorGC(black);
501 XSetForeground(dpy, gc, 1);
503 XCopyArea(dpy, WMGetPixmapXID(icon), pix, fgc, 0, 0,
504 size.width, size.height, 12, 12);
506 if (WMGetPixmapMaskXID(icon) != None)
507 XCopyPlane(dpy, WMGetPixmapMaskXID(icon), mask, gc, 0, 0,
508 size.width, size.height, 12, 12, 1);
509 else
510 XFillRectangle(dpy, mask, gc, 12, 12, 48, 48);
513 if (title1) {
514 XSetFont(dpy, fgc, vfont->fid);
515 XSetFont(dpy, gc, vfont->fid);
517 XDrawString(dpy, pix, fgc, 0, vfont->ascent,
518 title1, strlen(title1));
520 XDrawString(dpy, mask, gc, 0, vfont->ascent,
521 title1, strlen(title1));
524 if (title2) {
525 XSetFont(dpy, fgc, hfont->fid);
526 XSetFont(dpy, gc, hfont->fid);
528 XDrawString(dpy, pix, fgc, (title1 ? 12 : 0), hfont->ascent,
529 title2, strlen(title2));
531 XDrawString(dpy, mask, gc, (title1 ? 12 : 0), hfont->ascent,
532 title2, strlen(title2));
535 return tmp;
536 #endif
540 void
541 SetButtonAlphaImage(WMScreen *scr, WMButton *bPtr, char *file,
542 char *title1, char *title2)
544 WMPixmap *icon;
545 WMPixmap *icon2;
546 RColor color;
547 char *iconPath;
549 iconPath = LocateImage(file);
551 color.red = 0xae;
552 color.green = 0xaa;
553 color.blue = 0xae;
554 color.alpha = 0;
555 if (iconPath) {
556 icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
557 if (!icon)
558 wwarning(_("could not load icon file %s"), iconPath);
559 } else {
560 icon = NULL;
563 if (icon) {
564 icon2 = makeTitledIcon(scr, icon, title1, title2);
565 if (icon)
566 WMReleasePixmap(icon);
567 } else {
568 icon2 = NULL;
571 WMSetButtonImage(bPtr, icon2);
573 if (icon2)
574 WMReleasePixmap(icon2);
576 color.red = 0xff;
577 color.green = 0xff;
578 color.blue = 0xff;
579 color.alpha = 0;
580 if (iconPath) {
581 icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
582 if (!icon)
583 wwarning(_("could not load icon file %s"), iconPath);
584 } else {
585 icon = NULL;
588 WMSetButtonAltImage(bPtr, icon);
590 if (icon)
591 WMReleasePixmap(icon);
593 if (iconPath)
594 wfree(iconPath);
598 void
599 AddSection(Panel *panel, char *iconFile)
601 WMButton *bPtr;
603 assert(WPrefs.sectionCount < MAX_SECTIONS);
606 bPtr = WMCreateCustomButton(WPrefs.buttonF, WBBStateLightMask
607 |WBBStateChangeMask);
608 WMResizeWidget(bPtr, 64, 64);
609 WMMoveWidget(bPtr, WPrefs.sectionCount*64, 0);
610 WMSetButtonImagePosition(bPtr, WIPImageOnly);
611 WMSetButtonAction(bPtr, changeSection, panel);
612 WMHangData(bPtr, panel);
614 WMSetBalloonTextForView(((PanelRec*)panel)->description,
615 WMWidgetView(bPtr));
618 char *t1, *t2;
620 t1 = wstrdup(((PanelRec*)panel)->sectionName);
621 t2 = strchr(t1, ' ');
622 if (t2) {
623 *t2 = 0;
624 t2++;
626 SetButtonAlphaImage(WMWidgetScreen(bPtr), bPtr, iconFile,
627 t1, t2);
628 wfree(t1);
630 WMMapWidget(bPtr);
632 WPrefs.sectionB[WPrefs.sectionCount] = bPtr;
634 if (WPrefs.sectionCount > 0) {
635 WMGroupButtons(WPrefs.sectionB[0], bPtr);
638 WPrefs.sectionCount++;
640 WMResizeWidget(WPrefs.buttonF, WPrefs.sectionCount*64, 64);
644 void
645 Initialize(WMScreen *scr)
647 char **list;
648 int i;
649 char *path;
650 WMPixmap *icon;
653 list = RSupportedFileFormats();
654 for (i=0; list[i]!=NULL; i++) {
655 if (strcmp(list[i], "TIFF")==0) {
656 TIFFOK = True;
657 break;
661 if (TIFFOK)
662 path = WMPathForResourceOfType("WPrefs.tiff", NULL);
663 else
664 path = WMPathForResourceOfType("WPrefs.xpm", NULL);
665 if (path) {
666 RImage *tmp;
668 tmp = RLoadImage(WMScreenRContext(scr), path, 0);
669 if (!tmp) {
670 wwarning(_("could not load image file %s:%s"), path,
671 RMessageForError(RErrorCode));
672 } else {
673 icon = WMCreatePixmapFromRImage(scr, tmp, 0);
674 RReleaseImage(tmp);
675 if (icon) {
676 WMSetApplicationIconPixmap(scr, icon);
677 WMReleasePixmap(icon);
680 wfree(path);
683 memset(&WPrefs, 0, sizeof(_WPrefs));
684 createMainWindow(scr);
686 WMRealizeWidget(WPrefs.win);
687 WMMapWidget(WPrefs.win);
688 XFlush(WMScreenDisplay(scr));
689 WMSetLabelText(WPrefs.statusL, _("Loading Window Maker configuration files..."));
690 XFlush(WMScreenDisplay(scr));
691 loadConfigurations(scr, WPrefs.win);
693 WMSetLabelText(WPrefs.statusL, _("Initializing configuration panels..."));
695 InitFocus(scr, WPrefs.banner);
696 InitWindowHandling(scr, WPrefs.banner);
698 InitMenuPreferences(scr, WPrefs.banner);
699 InitIcons(scr, WPrefs.banner);
700 InitPreferences(scr, WPrefs.banner);
702 InitPaths(scr, WPrefs.banner);
703 InitWorkspace(scr, WPrefs.banner);
704 InitConfigurations(scr, WPrefs.banner);
706 InitMenu(scr, WPrefs.banner);
708 #ifdef not_yet_fully_implemented
709 InitKeyboardSettings(scr, WPrefs.banner);
710 #endif
711 InitKeyboardShortcuts(scr, WPrefs.banner);
712 InitMouseSettings(scr, WPrefs.banner);
714 InitAppearance(scr, WPrefs.banner);
716 #ifdef finished_checking
717 InitFont(scr, WPrefs.banner);
718 #endif
720 #ifdef not_yet_fully_implemented
721 InitThemes(scr, WPrefs.banner);
722 #endif
723 InitExpert(scr, WPrefs.banner);
725 WMRealizeWidget(WPrefs.scrollV);
727 WMSetLabelText(WPrefs.statusL,
728 _("WPrefs is free software and is distributed WITHOUT ANY\n"
729 "WARRANTY under the terms of the GNU General Public License."));
733 WMWindow*
734 GetWindow(Panel *panel)
736 return WPrefs.win;
740 static void
741 loadConfigurations(WMScreen *scr, WMWindow *mainw)
743 WMPropList *db, *gdb;
744 char *path;
745 FILE *file;
746 char buffer[1024];
747 char mbuf[1024];
748 int v1, v2, v3;
750 path = wdefaultspathfordomain("WindowMaker");
751 WindowMakerDBPath = path;
753 db = WMReadPropListFromFile(path);
754 if (db) {
755 if (!WMIsPLDictionary(db)) {
756 WMReleasePropList(db);
757 db = NULL;
758 sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), path);
759 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
761 } else {
762 sprintf(mbuf, _("Could not load Window Maker domain (%s) from defaults database."),
763 path);
764 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
767 path = getenv("WMAKER_BIN_NAME");
768 if (!path)
769 path = "wmaker";
771 char *command;
773 command = wstrconcat(path, " --version");
774 file = popen(command, "r");
775 wfree(command);
777 if (!file || !fgets(buffer, 1023, file)) {
778 wsyserror(_("could not extract version information from Window Maker"));
779 wfatal(_("Make sure wmaker is in your search path."));
781 WMRunAlertPanel(scr, mainw, _("Error"),
782 _("Could not extract version from Window Maker. Make sure it is correctly installed and is in your PATH environment variable."),
783 _("OK"), NULL, NULL);
784 exit(1);
786 if (file)
787 pclose(file);
789 if (sscanf(buffer, "Window Maker %i.%i.%i",&v1,&v2,&v3)!=3
790 && sscanf(buffer, "WindowMaker %i.%i.%i",&v1,&v2,&v3)!=3) {
791 WMRunAlertPanel(scr, mainw, _("Error"),
792 _("Could not extract version from Window Maker. "
793 "Make sure it is correctly installed and the path "
794 "where it installed is in the PATH environment "
795 "variable."), _("OK"), NULL, NULL);
796 exit(1);
798 if (v1 == 0 && (v2 < 18 || v3 < 0)) {
799 sprintf(mbuf, _("WPrefs only supports Window Maker 0.18.0 or newer.\n"
800 "The version installed is %i.%i.%i\n"), v1, v2, v3);
801 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
802 exit(1);
805 if (v1 > 1 || (v1 == 1 && (v2 > 0))) {
806 sprintf(mbuf, _("Window Maker %i.%i.%i, which is installed in your system, is not fully supported by this version of WPrefs."),
807 v1, v2, v3);
808 WMRunAlertPanel(scr, mainw, _("Warning"), mbuf, _("OK"), NULL, NULL);
812 char *command;
814 command = wstrconcat(path, " --global_defaults_path");
815 file = popen(command, "r");
816 wfree(command);
818 if (!file || !fgets(buffer, 1023, file)) {
819 wsyserror(_("could not run \"%s --global_defaults_path\"."), path);
820 exit(1);
821 } else {
822 char *ptr;
823 ptr = strchr(buffer, '\n');
824 if (ptr)
825 *ptr = 0;
826 strcat(buffer, "/WindowMaker");
829 if (file)
830 pclose(file);
832 gdb = WMReadPropListFromFile(buffer);
834 if (gdb) {
835 if (!WMIsPLDictionary(gdb)) {
836 WMReleasePropList(gdb);
837 gdb = NULL;
838 sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), buffer);
839 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
841 } else {
842 sprintf(mbuf, _("Could not load global Window Maker domain (%s)."),
843 buffer);
844 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
847 if (!db) {
848 db = WMCreatePLDictionary(NULL, NULL, NULL);
850 if (!gdb) {
851 gdb = WMCreatePLDictionary(NULL, NULL, NULL);
854 GlobalDB = gdb;
856 WindowMakerDB = db;
860 WMPropList*
861 GetObjectForKey(char *defaultName)
863 WMPropList *object = NULL;
864 WMPropList *key = WMCreatePLString(defaultName);
866 object = WMGetFromPLDictionary(WindowMakerDB, key);
867 if (!object)
868 object = WMGetFromPLDictionary(GlobalDB, key);
870 WMReleasePropList(key);
872 return object;
876 void
877 SetObjectForKey(WMPropList *object, char *defaultName)
879 WMPropList *key = WMCreatePLString(defaultName);
881 WMPutInPLDictionary(WindowMakerDB, key, object);
882 WMReleasePropList(key);
886 void
887 RemoveObjectForKey(char *defaultName)
889 WMPropList *key = WMCreatePLString(defaultName);
891 WMRemoveFromPLDictionary(WindowMakerDB, key);
893 WMReleasePropList(key);
897 char*
898 GetStringForKey(char *defaultName)
900 WMPropList *val;
902 val = GetObjectForKey(defaultName);
904 if (!val)
905 return NULL;
907 if (!WMIsPLString(val))
908 return NULL;
910 return WMGetFromPLString(val);
915 WMPropList*
916 GetArrayForKey(char *defaultName)
918 WMPropList *val;
920 val = GetObjectForKey(defaultName);
922 if (!val)
923 return NULL;
925 if (!WMIsPLArray(val))
926 return NULL;
928 return val;
932 WMPropList*
933 GetDictionaryForKey(char *defaultName)
935 WMPropList *val;
937 val = GetObjectForKey(defaultName);
939 if (!val)
940 return NULL;
942 if (!WMIsPLDictionary(val))
943 return NULL;
945 return val;
950 GetIntegerForKey(char *defaultName)
952 WMPropList *val;
953 char *str;
954 int value;
956 val = GetObjectForKey(defaultName);
958 if (!val)
959 return 0;
961 if (!WMIsPLString(val))
962 return 0;
964 str = WMGetFromPLString(val);
965 if (!str)
966 return 0;
968 if (sscanf(str, "%i", &value)!=1)
969 return 0;
971 return value;
975 Bool
976 GetBoolForKey(char *defaultName)
978 int value;
979 char *str;
981 str = GetStringForKey(defaultName);
983 if (!str)
984 return False;
986 if (sscanf(str, "%i", &value)==1 && value!=0)
987 return True;
989 if (strcasecmp(str, "YES")==0)
990 return True;
992 if (strcasecmp(str, "Y")==0)
993 return True;
995 return False;
999 void
1000 SetIntegerForKey(int value, char *defaultName)
1002 WMPropList *object;
1003 char buffer[128];
1005 sprintf(buffer, "%i", value);
1006 object = WMCreatePLString(buffer);
1008 SetObjectForKey(object, defaultName);
1009 WMReleasePropList(object);
1014 void
1015 SetStringForKey(char *value, char *defaultName)
1017 WMPropList *object;
1019 object = WMCreatePLString(value);
1021 SetObjectForKey(object, defaultName);
1022 WMReleasePropList(object);
1026 void
1027 SetBoolForKey(Bool value, char *defaultName)
1029 static WMPropList *yes = NULL, *no = NULL;
1031 if (!yes) {
1032 yes = WMCreatePLString("YES");
1033 no = WMCreatePLString("NO");
1036 SetObjectForKey(value ? yes : no, defaultName);
1040 void
1041 SetSpeedForKey(int speed, char *defaultName)
1043 char *str;
1045 switch (speed) {
1046 case 0:
1047 str = "ultraslow";
1048 break;
1049 case 1:
1050 str = "slow";
1051 break;
1052 case 2:
1053 str = "medium";
1054 break;
1055 case 3:
1056 str = "fast";
1057 break;
1058 case 4:
1059 str = "ultrafast";
1060 break;
1061 default:
1062 str = NULL;
1065 if (str)
1066 SetStringForKey(str, defaultName);
1071 GetSpeedForKey(char *defaultName)
1073 char *str;
1074 int i;
1076 str = GetStringForKey(defaultName);
1077 if (!str)
1078 return 2;
1080 if (strcasecmp(str, "ultraslow")==0)
1081 i = 0;
1082 else if (strcasecmp(str, "slow")==0)
1083 i = 1;
1084 else if (strcasecmp(str, "medium")==0)
1085 i = 2;
1086 else if (strcasecmp(str, "fast")==0)
1087 i = 3;
1088 else if (strcasecmp(str, "ultrafast")==0)
1089 i = 4;
1090 else {
1091 wwarning(_("bad speed value for option %s\n. Using default Medium"),
1092 defaultName);
1093 i = 2;
1095 return i;