fixed bug with zombies after wmaker crashed
[wmaker-crm.git] / WPrefs.app / WPrefs.c
bloba20e35891ab78f33ca4ab68b9f869f23698658a9
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 "-adobe-helvetica-bold-r-*-*-10-*"
65 #define ICON_TITLE_VFONT "-adobe-helvetica-bold-r-*-*-10-[]-*"
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 *creditsL;
91 WMLabel *statusL;
93 Panel *currentPanel;
94 } _WPrefs;
97 static _WPrefs WPrefs;
99 /* system wide defaults dictionary. Read-only */
100 static WMPropList *GlobalDB = NULL;
101 /* user defaults dictionary */
102 static WMPropList *WindowMakerDB = NULL;
103 static char *WindowMakerDBPath = NULL;
106 static Bool TIFFOK = False;
109 #define INITIALIZED_PANEL (1<<0)
114 static void loadConfigurations(WMScreen *scr, WMWindow *mainw);
116 static void savePanelData(Panel *panel);
118 static void prepareForClose();
120 void
121 quit(WMWidget *w, void *data)
123 prepareForClose();
125 exit(0);
129 static void
130 save(WMWidget *w, void *data)
132 int i;
133 WMPropList *p1, *p2;
134 WMPropList *keyList;
135 WMPropList *key;
136 char *msg = "Reconfigure";
137 XEvent ev;
140 /* puts("gathering data");*/
141 for (i=0; i<WPrefs.sectionCount; i++) {
142 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
143 if ((rec->callbacks.flags & INITIALIZED_PANEL))
144 savePanelData((Panel*)rec);
146 /* puts("compressing data");*/
147 /* compare the user dictionary with the global and remove redundant data */
148 keyList = WMGetPLDictionaryKeys(GlobalDB);
149 /* puts(WMGetPropListDescription(WindowMakerDB, False));*/
150 for (i=0; i<WMGetPropListItemCount(keyList); i++) {
151 key = WMGetFromPLArray(keyList, i);
153 /* We don't have this value anyway, so no problem.
154 * Probably a new option */
155 p1 = WMGetFromPLDictionary(WindowMakerDB, key);
156 if (!p1)
157 continue;
158 /* The global doesn't have it, so no problem either. */
159 p2 = WMGetFromPLDictionary(GlobalDB, key);
160 if (!p2)
161 continue;
162 /* If both values are the same, don't save. */
163 if (WMIsPropListEqualTo(p1, p2))
164 WMRemoveFromPLDictionary(WindowMakerDB, key);
166 /* puts(WMGetPropListDescription(WindowMakerDB, False));*/
167 WMReleasePropList(keyList);
168 /* puts("storing data");*/
170 WMWritePropListToFile(WindowMakerDB, WindowMakerDBPath, True);
173 memset(&ev, 0, sizeof(XEvent));
175 ev.xclient.type = ClientMessage;
176 ev.xclient.message_type = XInternAtom(WMScreenDisplay(WMWidgetScreen(w)),
177 "_WINDOWMAKER_COMMAND", False);
178 ev.xclient.window = DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w)));
179 ev.xclient.format = 8;
181 for (i = 0; i <= strlen(msg); i++) {
182 ev.xclient.data.b[i] = msg[i];
184 XSendEvent(WMScreenDisplay(WMWidgetScreen(w)),
185 DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w))),
186 False, SubstructureRedirectMask, &ev);
187 XFlush(WMScreenDisplay(WMWidgetScreen(w)));
192 static void
193 undo(WMWidget *w, void *data)
195 PanelRec *rec = (PanelRec*)WPrefs.currentPanel;
197 if (!rec)
198 return;
200 if (rec->callbacks.undoChanges
201 && (rec->callbacks.flags & INITIALIZED_PANEL)) {
202 (*rec->callbacks.undoChanges)(WPrefs.currentPanel);
207 static void
208 undoAll(WMWidget *w, void *data)
210 int i;
212 for (i=0; i<WPrefs.sectionCount; i++) {
213 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
215 if (rec->callbacks.undoChanges
216 && (rec->callbacks.flags & INITIALIZED_PANEL))
217 (*rec->callbacks.undoChanges)((Panel*)rec);
223 static void
224 prepareForClose()
226 int i;
228 for (i=0; i<WPrefs.sectionCount; i++) {
229 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
231 if (rec->callbacks.prepareForClose
232 && (rec->callbacks.flags & INITIALIZED_PANEL))
233 (*rec->callbacks.prepareForClose)((Panel*)rec);
238 void
239 toggleBalloons(WMWidget *w, void *data)
241 WMUserDefaults *udb = WMGetStandardUserDefaults();
242 Bool flag;
244 flag = WMGetButtonSelected(WPrefs.balloonBtn);
246 WMSetBalloonEnabled(WMWidgetScreen(WPrefs.win), flag);
248 WMSetUDBoolForKey(udb, flag, "BalloonHelp");
252 static void
253 createMainWindow(WMScreen *scr)
255 WMScroller *scroller;
256 WMFont *font;
257 char buffer[128];
259 WPrefs.win = WMCreateWindow(scr, "wprefs");
260 WMResizeWidget(WPrefs.win, 520, 390);
261 WMSetWindowTitle(WPrefs.win, _("Window Maker Preferences"));
262 WMSetWindowCloseAction(WPrefs.win, quit, NULL);
263 WMSetWindowMaxSize(WPrefs.win, 520, 390);
264 WMSetWindowMinSize(WPrefs.win, 520, 390);
265 WMSetWindowMiniwindowTitle(WPrefs.win, "Preferences");
266 WMSetWindowMiniwindowPixmap(WPrefs.win, WMGetApplicationIconPixmap(scr));
268 WPrefs.scrollV = WMCreateScrollView(WPrefs.win);
269 WMResizeWidget(WPrefs.scrollV, 500, 87);
270 WMMoveWidget(WPrefs.scrollV, 10, 10);
271 WMSetScrollViewRelief(WPrefs.scrollV, WRSunken);
272 WMSetScrollViewHasHorizontalScroller(WPrefs.scrollV, True);
273 WMSetScrollViewHasVerticalScroller(WPrefs.scrollV, False);
274 scroller = WMGetScrollViewHorizontalScroller(WPrefs.scrollV);
275 WMSetScrollerArrowsPosition(scroller, WSANone);
277 WPrefs.buttonF = WMCreateFrame(WPrefs.win);
278 WMSetFrameRelief(WPrefs.buttonF, WRFlat);
280 WMSetScrollViewContentView(WPrefs.scrollV, WMWidgetView(WPrefs.buttonF));
282 WPrefs.undosBtn = WMCreateCommandButton(WPrefs.win);
283 WMResizeWidget(WPrefs.undosBtn, 90, 28);
284 WMMoveWidget(WPrefs.undosBtn, 135, 350);
285 WMSetButtonText(WPrefs.undosBtn, _("Revert Page"));
286 WMSetButtonAction(WPrefs.undosBtn, undo, NULL);
288 WPrefs.undoBtn = WMCreateCommandButton(WPrefs.win);
289 WMResizeWidget(WPrefs.undoBtn, 90, 28);
290 WMMoveWidget(WPrefs.undoBtn, 235, 350);
291 WMSetButtonText(WPrefs.undoBtn, _("Revert All"));
292 WMSetButtonAction(WPrefs.undoBtn, undoAll, NULL);
294 WPrefs.saveBtn = WMCreateCommandButton(WPrefs.win);
295 WMResizeWidget(WPrefs.saveBtn, 80, 28);
296 WMMoveWidget(WPrefs.saveBtn, 335, 350);
297 WMSetButtonText(WPrefs.saveBtn, _("Save"));
298 WMSetButtonAction(WPrefs.saveBtn, save, NULL);
300 WPrefs.closeBtn = WMCreateCommandButton(WPrefs.win);
301 WMResizeWidget(WPrefs.closeBtn, 80, 28);
302 WMMoveWidget(WPrefs.closeBtn, 425, 350);
303 WMSetButtonText(WPrefs.closeBtn, _("Close"));
304 WMSetButtonAction(WPrefs.closeBtn, quit, NULL);
307 WPrefs.balloonBtn = WMCreateSwitchButton(WPrefs.win);
308 WMResizeWidget(WPrefs.balloonBtn, 200, 28);
309 WMMoveWidget(WPrefs.balloonBtn, 15, 350);
310 WMSetButtonText(WPrefs.balloonBtn, _("Balloon Help"));
311 WMSetButtonAction(WPrefs.balloonBtn, toggleBalloons, NULL);
313 WMUserDefaults *udb = WMGetStandardUserDefaults();
314 Bool flag = WMGetUDBoolForKey(udb, "BalloonHelp");
316 WMSetButtonSelected(WPrefs.balloonBtn, flag);
317 WMSetBalloonEnabled(scr, flag);
320 /* banner */
321 WPrefs.banner = WMCreateFrame(WPrefs.win);
322 WMResizeWidget(WPrefs.banner, FRAME_WIDTH, FRAME_HEIGHT);
323 WMMoveWidget(WPrefs.banner, FRAME_LEFT, FRAME_TOP);
324 WMSetFrameRelief(WPrefs.banner, WRFlat);
326 font = WMCreateFont(scr, "-*-times-bold-r-*-*-24-*-*-*-*-*-*-*,"
327 "-*-fixed-medium-r-normal-*-24-*");
328 if (!font)
329 font = WMBoldSystemFontOfSize(scr, 24);
330 WPrefs.nameL = WMCreateLabel(WPrefs.banner);
331 WMSetLabelTextAlignment(WPrefs.nameL, WACenter);
332 WMResizeWidget(WPrefs.nameL, FRAME_WIDTH-20, 30);
333 WMMoveWidget(WPrefs.nameL, 10, 25);
334 WMSetLabelFont(WPrefs.nameL, font);
335 WMSetLabelText(WPrefs.nameL, _("Window Maker Preferences Utility"));
336 WMReleaseFont(font);
338 WPrefs.versionL = WMCreateLabel(WPrefs.banner);
339 WMResizeWidget(WPrefs.versionL, FRAME_WIDTH-20, 20);
340 WMMoveWidget(WPrefs.versionL, 10, 65);
341 WMSetLabelTextAlignment(WPrefs.versionL, WACenter);
342 sprintf(buffer, _("Version %s for Window Maker %s or newer"), WVERSION,
343 WMVERSION);
344 WMSetLabelText(WPrefs.versionL, buffer);
346 WPrefs.statusL = WMCreateLabel(WPrefs.banner);
347 WMResizeWidget(WPrefs.statusL, FRAME_WIDTH-20, 60);
348 WMMoveWidget(WPrefs.statusL, 10, 100);
349 WMSetLabelTextAlignment(WPrefs.statusL, WACenter);
350 WMSetLabelText(WPrefs.statusL, _("Starting..."));
352 WPrefs.creditsL = WMCreateLabel(WPrefs.banner);
353 WMResizeWidget(WPrefs.creditsL, FRAME_WIDTH-20, 60);
354 WMMoveWidget(WPrefs.creditsL, 10, FRAME_HEIGHT-60);
355 WMSetLabelTextAlignment(WPrefs.creditsL, WACenter);
356 WMSetLabelText(WPrefs.creditsL, _("Programming/Design: Alfredo K. Kojima\n"
357 "Artwork: Marco van Hylckama Vlieg, Largo et al\n"
358 "More Programming: James Thompson et al"));
361 WMMapSubwidgets(WPrefs.win);
363 WMUnmapWidget(WPrefs.undosBtn);
364 WMUnmapWidget(WPrefs.undoBtn);
365 WMUnmapWidget(WPrefs.saveBtn);
369 static void
370 showPanel(Panel *panel)
372 PanelRec *rec = (PanelRec*)panel;
374 if (!(rec->callbacks.flags & INITIALIZED_PANEL)) {
375 (*rec->callbacks.createWidgets)(panel);
376 rec->callbacks.flags |= INITIALIZED_PANEL;
379 WMSetWindowTitle(WPrefs.win, rec->sectionName);
381 if (rec->callbacks.showPanel)
382 (*rec->callbacks.showPanel)(panel);
384 WMMapWidget(rec->box);
389 static void
390 hidePanel(Panel *panel)
392 PanelRec *rec = (PanelRec*)panel;
394 WMUnmapWidget(rec->box);
396 if (rec->callbacks.hidePanel)
397 (*rec->callbacks.hidePanel)(panel);
401 static void
402 savePanelData(Panel *panel)
404 PanelRec *rec = (PanelRec*)panel;
406 if (rec->callbacks.updateDomain) {
407 (*rec->callbacks.updateDomain)(panel);
412 static void
413 changeSection(WMWidget *self, void *data)
415 if (WPrefs.currentPanel == data)
416 return;
418 if (WPrefs.currentPanel == NULL) {
419 WMDestroyWidget(WPrefs.nameL);
420 WMDestroyWidget(WPrefs.creditsL);
421 WMDestroyWidget(WPrefs.versionL);
422 WMDestroyWidget(WPrefs.statusL);
424 WMSetFrameRelief(WPrefs.banner, WRGroove);
426 /* WMMapWidget(WPrefs.undosBtn);
427 WMMapWidget(WPrefs.undoBtn);
429 WMMapWidget(WPrefs.saveBtn);
432 showPanel(data);
434 if (WPrefs.currentPanel)
435 hidePanel(WPrefs.currentPanel);
436 WPrefs.currentPanel = data;
441 char*
442 LocateImage(char *name)
444 char *path;
445 char *tmp = wmalloc(strlen(name)+8);
447 if (TIFFOK) {
448 sprintf(tmp, "%s.tiff", name);
449 path = WMPathForResourceOfType(tmp, "tiff");
450 } else {
451 sprintf(tmp, "%s.xpm", name);
452 path = WMPathForResourceOfType(tmp, "xpm");
454 wfree(tmp);
455 if (!path) {
456 wwarning(_("could not locate image file %s\n"), name);
459 return path;
464 static WMPixmap*
465 makeTitledIcon(WMScreen *scr, WMPixmap *icon, char *title1, char *title2)
467 return WMRetainPixmap(icon);
469 #if 0
470 static GC gc = NULL;
471 static XFontStruct *hfont = NULL;
472 static XFontStruct *vfont = NULL;
473 WMPixmap *tmp;
474 Pixmap pix, mask;
475 Display *dpy = WMScreenDisplay(scr);
476 WMColor *black = WMBlackColor(scr);
477 GC fgc;
478 WMSize size = WMGetPixmapSize(icon);
481 tmp = WMCreatePixmap(scr, 60, 60, WMScreenDepth(scr), True);
483 pix = WMGetPixmapXID(tmp);
484 mask = WMGetPixmapMaskXID(tmp);
486 if (gc == NULL) {
487 gc = XCreateGC(dpy, mask, 0, NULL);
489 hfont = XLoadQueryFont(dpy, ICON_TITLE_FONT);
490 vfont = XLoadQueryFont(dpy, ICON_TITLE_VFONT);
493 if (hfont == NULL) {
494 return WMRetainPixmap(icon);
497 XSetForeground(dpy, gc, 0);
498 XFillRectangle(dpy, mask, gc, 0, 0, 60, 60);
500 fgc = WMColorGC(black);
502 XSetForeground(dpy, gc, 1);
504 XCopyArea(dpy, WMGetPixmapXID(icon), pix, fgc, 0, 0,
505 size.width, size.height, 12, 12);
507 if (WMGetPixmapMaskXID(icon) != None)
508 XCopyPlane(dpy, WMGetPixmapMaskXID(icon), mask, gc, 0, 0,
509 size.width, size.height, 12, 12, 1);
510 else
511 XFillRectangle(dpy, mask, gc, 12, 12, 48, 48);
514 if (title1) {
515 XSetFont(dpy, fgc, vfont->fid);
516 XSetFont(dpy, gc, vfont->fid);
518 XDrawString(dpy, pix, fgc, 0, vfont->ascent,
519 title1, strlen(title1));
521 XDrawString(dpy, mask, gc, 0, vfont->ascent,
522 title1, strlen(title1));
525 if (title2) {
526 XSetFont(dpy, fgc, hfont->fid);
527 XSetFont(dpy, gc, hfont->fid);
529 XDrawString(dpy, pix, fgc, (title1 ? 12 : 0), hfont->ascent,
530 title2, strlen(title2));
532 XDrawString(dpy, mask, gc, (title1 ? 12 : 0), hfont->ascent,
533 title2, strlen(title2));
536 return tmp;
537 #endif
541 void
542 SetButtonAlphaImage(WMScreen *scr, WMButton *bPtr, char *file,
543 char *title1, char *title2)
545 WMPixmap *icon;
546 WMPixmap *icon2;
547 RColor color;
548 char *iconPath;
550 iconPath = LocateImage(file);
552 color.red = 0xae;
553 color.green = 0xaa;
554 color.blue = 0xae;
555 color.alpha = 0;
556 if (iconPath) {
557 icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
558 if (!icon)
559 wwarning(_("could not load icon file %s"), iconPath);
560 } else {
561 icon = NULL;
564 if (icon) {
565 icon2 = makeTitledIcon(scr, icon, title1, title2);
566 if (icon)
567 WMReleasePixmap(icon);
568 } else {
569 icon2 = NULL;
572 WMSetButtonImage(bPtr, icon2);
574 if (icon2)
575 WMReleasePixmap(icon2);
577 color.red = 0xff;
578 color.green = 0xff;
579 color.blue = 0xff;
580 color.alpha = 0;
581 if (iconPath) {
582 icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
583 if (!icon)
584 wwarning(_("could not load icon file %s"), iconPath);
585 } else {
586 icon = NULL;
589 WMSetButtonAltImage(bPtr, icon);
591 if (icon)
592 WMReleasePixmap(icon);
594 if (iconPath)
595 wfree(iconPath);
599 void
600 AddSection(Panel *panel, char *iconFile)
602 WMButton *bPtr;
604 assert(WPrefs.sectionCount < MAX_SECTIONS);
607 bPtr = WMCreateCustomButton(WPrefs.buttonF, WBBStateLightMask
608 |WBBStateChangeMask);
609 WMResizeWidget(bPtr, 64, 64);
610 WMMoveWidget(bPtr, WPrefs.sectionCount*64, 0);
611 WMSetButtonImagePosition(bPtr, WIPImageOnly);
612 WMSetButtonAction(bPtr, changeSection, panel);
613 WMHangData(bPtr, panel);
615 WMSetBalloonTextForView(((PanelRec*)panel)->description,
616 WMWidgetView(bPtr));
619 char *t1, *t2;
621 t1 = wstrdup(((PanelRec*)panel)->sectionName);
622 t2 = strchr(t1, ' ');
623 if (t2) {
624 *t2 = 0;
625 t2++;
627 SetButtonAlphaImage(WMWidgetScreen(bPtr), bPtr, iconFile,
628 t1, t2);
629 wfree(t1);
631 WMMapWidget(bPtr);
633 WPrefs.sectionB[WPrefs.sectionCount] = bPtr;
635 if (WPrefs.sectionCount > 0) {
636 WMGroupButtons(WPrefs.sectionB[0], bPtr);
639 WPrefs.sectionCount++;
641 WMResizeWidget(WPrefs.buttonF, WPrefs.sectionCount*64, 64);
645 void
646 Initialize(WMScreen *scr)
648 char **list;
649 int i;
650 char *path;
651 WMPixmap *icon;
654 list = RSupportedFileFormats();
655 for (i=0; list[i]!=NULL; i++) {
656 if (strcmp(list[i], "TIFF")==0) {
657 TIFFOK = True;
658 break;
662 if (TIFFOK)
663 path = WMPathForResourceOfType("WPrefs.tiff", NULL);
664 else
665 path = WMPathForResourceOfType("WPrefs.xpm", NULL);
666 if (path) {
667 RImage *tmp;
669 tmp = RLoadImage(WMScreenRContext(scr), path, 0);
670 if (!tmp) {
671 wwarning(_("could not load image file %s:%s"), path,
672 RMessageForError(RErrorCode));
673 } else {
674 icon = WMCreatePixmapFromRImage(scr, tmp, 0);
675 RReleaseImage(tmp);
676 if (icon) {
677 WMSetApplicationIconPixmap(scr, icon);
678 WMReleasePixmap(icon);
681 wfree(path);
684 memset(&WPrefs, 0, sizeof(_WPrefs));
685 createMainWindow(scr);
687 WMRealizeWidget(WPrefs.win);
688 WMMapWidget(WPrefs.win);
689 XFlush(WMScreenDisplay(scr));
690 WMSetLabelText(WPrefs.statusL, _("Loading Window Maker configuration files..."));
691 XFlush(WMScreenDisplay(scr));
692 loadConfigurations(scr, WPrefs.win);
694 WMSetLabelText(WPrefs.statusL, _("Initializing configuration panels..."));
696 InitFocus(scr, WPrefs.banner);
697 InitWindowHandling(scr, WPrefs.banner);
699 InitMenuPreferences(scr, WPrefs.banner);
700 InitIcons(scr, WPrefs.banner);
701 InitPreferences(scr, WPrefs.banner);
703 InitPaths(scr, WPrefs.banner);
704 InitWorkspace(scr, WPrefs.banner);
705 InitConfigurations(scr, WPrefs.banner);
707 InitMenu(scr, WPrefs.banner);
709 #ifdef not_yet_fully_implemented
710 InitKeyboardSettings(scr, WPrefs.banner);
711 #endif
712 InitKeyboardShortcuts(scr, WPrefs.banner);
713 InitMouseSettings(scr, WPrefs.banner);
715 InitAppearance(scr, WPrefs.banner);
717 InitFontSimple(scr, WPrefs.banner);
719 #ifdef not_yet_fully_implemented
720 InitThemes(scr, WPrefs.banner);
721 #endif
722 InitExpert(scr, WPrefs.banner);
724 WMRealizeWidget(WPrefs.scrollV);
726 WMSetLabelText(WPrefs.statusL,
727 _("WPrefs is free software and is distributed WITHOUT ANY\n"
728 "WARRANTY under the terms of the GNU General Public License."));
732 WMWindow*
733 GetWindow(Panel *panel)
735 return WPrefs.win;
739 static void
740 loadConfigurations(WMScreen *scr, WMWindow *mainw)
742 WMPropList *db, *gdb;
743 char *path;
744 FILE *file;
745 char buffer[1024];
746 char mbuf[1024];
747 int v1, v2, v3;
749 path = wdefaultspathfordomain("WindowMaker");
750 WindowMakerDBPath = path;
752 db = WMReadPropListFromFile(path);
753 if (db) {
754 if (!WMIsPLDictionary(db)) {
755 WMReleasePropList(db);
756 db = NULL;
757 sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), path);
758 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
760 } else {
761 sprintf(mbuf, _("Could not load Window Maker domain (%s) from defaults database."),
762 path);
763 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
766 path = getenv("WMAKER_BIN_NAME");
767 if (!path)
768 path = "wmaker";
770 char *command;
772 command = wstrconcat(path, " --version");
773 file = popen(command, "r");
774 wfree(command);
776 if (!file || !fgets(buffer, 1023, file)) {
777 wsyserror(_("could not extract version information from Window Maker"));
778 wfatal(_("Make sure wmaker is in your search path."));
780 WMRunAlertPanel(scr, mainw, _("Error"),
781 _("Could not extract version from Window Maker. Make sure it is correctly installed and is in your PATH environment variable."),
782 _("OK"), NULL, NULL);
783 exit(1);
785 if (file)
786 pclose(file);
788 if (sscanf(buffer, "Window Maker %i.%i.%i",&v1,&v2,&v3)!=3
789 && sscanf(buffer, "WindowMaker %i.%i.%i",&v1,&v2,&v3)!=3) {
790 WMRunAlertPanel(scr, mainw, _("Error"),
791 _("Could not extract version from Window Maker. "
792 "Make sure it is correctly installed and the path "
793 "where it installed is in the PATH environment "
794 "variable."), _("OK"), NULL, NULL);
795 exit(1);
797 if (v1 == 0 && (v2 < 18 || v3 < 0)) {
798 sprintf(mbuf, _("WPrefs only supports Window Maker 0.18.0 or newer.\n"
799 "The version installed is %i.%i.%i\n"), v1, v2, v3);
800 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
801 exit(1);
804 if (v1 > 1 || (v1 == 1 && (v2 > 0))) {
805 sprintf(mbuf, _("Window Maker %i.%i.%i, which is installed in your system, is not fully supported by this version of WPrefs."),
806 v1, v2, v3);
807 WMRunAlertPanel(scr, mainw, _("Warning"), mbuf, _("OK"), NULL, NULL);
811 char *command;
813 command = wstrconcat(path, " --global_defaults_path");
814 file = popen(command, "r");
815 wfree(command);
817 if (!file || !fgets(buffer, 1023, file)) {
818 wsyserror(_("could not run \"%s --global_defaults_path\"."), path);
819 exit(1);
820 } else {
821 char *ptr;
822 ptr = strchr(buffer, '\n');
823 if (ptr)
824 *ptr = 0;
825 strcat(buffer, "/WindowMaker");
828 if (file)
829 pclose(file);
831 gdb = WMReadPropListFromFile(buffer);
833 if (gdb) {
834 if (!WMIsPLDictionary(gdb)) {
835 WMReleasePropList(gdb);
836 gdb = NULL;
837 sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), buffer);
838 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
840 } else {
841 sprintf(mbuf, _("Could not load global Window Maker domain (%s)."),
842 buffer);
843 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
846 if (!db) {
847 db = WMCreatePLDictionary(NULL, NULL);
849 if (!gdb) {
850 gdb = WMCreatePLDictionary(NULL, NULL);
853 GlobalDB = gdb;
855 WindowMakerDB = db;
859 WMPropList*
860 GetObjectForKey(char *defaultName)
862 WMPropList *object = NULL;
863 WMPropList *key = WMCreatePLString(defaultName);
865 object = WMGetFromPLDictionary(WindowMakerDB, key);
866 if (!object)
867 object = WMGetFromPLDictionary(GlobalDB, key);
869 WMReleasePropList(key);
871 return object;
875 void
876 SetObjectForKey(WMPropList *object, char *defaultName)
878 WMPropList *key = WMCreatePLString(defaultName);
880 WMPutInPLDictionary(WindowMakerDB, key, object);
881 WMReleasePropList(key);
885 void
886 RemoveObjectForKey(char *defaultName)
888 WMPropList *key = WMCreatePLString(defaultName);
890 WMRemoveFromPLDictionary(WindowMakerDB, key);
892 WMReleasePropList(key);
896 char*
897 GetStringForKey(char *defaultName)
899 WMPropList *val;
901 val = GetObjectForKey(defaultName);
903 if (!val)
904 return NULL;
906 if (!WMIsPLString(val))
907 return NULL;
909 return WMGetFromPLString(val);
914 WMPropList*
915 GetArrayForKey(char *defaultName)
917 WMPropList *val;
919 val = GetObjectForKey(defaultName);
921 if (!val)
922 return NULL;
924 if (!WMIsPLArray(val))
925 return NULL;
927 return val;
931 WMPropList*
932 GetDictionaryForKey(char *defaultName)
934 WMPropList *val;
936 val = GetObjectForKey(defaultName);
938 if (!val)
939 return NULL;
941 if (!WMIsPLDictionary(val))
942 return NULL;
944 return val;
949 GetIntegerForKey(char *defaultName)
951 WMPropList *val;
952 char *str;
953 int value;
955 val = GetObjectForKey(defaultName);
957 if (!val)
958 return 0;
960 if (!WMIsPLString(val))
961 return 0;
963 str = WMGetFromPLString(val);
964 if (!str)
965 return 0;
967 if (sscanf(str, "%i", &value)!=1)
968 return 0;
970 return value;
974 Bool
975 GetBoolForKey(char *defaultName)
977 int value;
978 char *str;
980 str = GetStringForKey(defaultName);
982 if (!str)
983 return False;
985 if (sscanf(str, "%i", &value)==1 && value!=0)
986 return True;
988 if (strcasecmp(str, "YES")==0)
989 return True;
991 if (strcasecmp(str, "Y")==0)
992 return True;
994 return False;
998 void
999 SetIntegerForKey(int value, char *defaultName)
1001 WMPropList *object;
1002 char buffer[128];
1004 sprintf(buffer, "%i", value);
1005 object = WMCreatePLString(buffer);
1007 SetObjectForKey(object, defaultName);
1008 WMReleasePropList(object);
1013 void
1014 SetStringForKey(char *value, char *defaultName)
1016 WMPropList *object;
1018 object = WMCreatePLString(value);
1020 SetObjectForKey(object, defaultName);
1021 WMReleasePropList(object);
1025 void
1026 SetBoolForKey(Bool value, char *defaultName)
1028 static WMPropList *yes = NULL, *no = NULL;
1030 if (!yes) {
1031 yes = WMCreatePLString("YES");
1032 no = WMCreatePLString("NO");
1035 SetObjectForKey(value ? yes : no, defaultName);
1039 void
1040 SetSpeedForKey(int speed, char *defaultName)
1042 char *str;
1044 switch (speed) {
1045 case 0:
1046 str = "ultraslow";
1047 break;
1048 case 1:
1049 str = "slow";
1050 break;
1051 case 2:
1052 str = "medium";
1053 break;
1054 case 3:
1055 str = "fast";
1056 break;
1057 case 4:
1058 str = "ultrafast";
1059 break;
1060 default:
1061 str = NULL;
1064 if (str)
1065 SetStringForKey(str, defaultName);
1070 GetSpeedForKey(char *defaultName)
1072 char *str;
1073 int i;
1075 str = GetStringForKey(defaultName);
1076 if (!str)
1077 return 2;
1079 if (strcasecmp(str, "ultraslow")==0)
1080 i = 0;
1081 else if (strcasecmp(str, "slow")==0)
1082 i = 1;
1083 else if (strcasecmp(str, "medium")==0)
1084 i = 2;
1085 else if (strcasecmp(str, "fast")==0)
1086 i = 3;
1087 else if (strcasecmp(str, "ultrafast")==0)
1088 i = 4;
1089 else {
1090 wwarning(_("bad speed value for option %s\n. Using default Medium"),
1091 defaultName);
1092 i = 2;
1094 return i;