util: Added a few missing 'static' attributes for functions
[wmaker-crm.git] / WPrefs.app / WPrefs.c
blob3acbd395090c1d4b055dd0dd2f59bb5a36c02c83
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 along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "WPrefs.h"
23 #include <assert.h>
25 extern Panel *InitWindowHandling(WMScreen * scr, WMWidget * parent);
27 extern Panel *InitKeyboardSettings(WMScreen * scr, WMWidget * parent);
29 extern Panel *InitMouseSettings(WMScreen * scr, WMWidget * parent);
31 extern Panel *InitKeyboardShortcuts(WMScreen * scr, WMWidget * parent);
33 extern Panel *InitWorkspace(WMScreen * scr, WMWidget * parent);
35 extern Panel *InitDocks(WMScreen *scr, WMWidget *parent);
37 extern Panel *InitFocus(WMScreen * scr, WMWidget * parent);
39 extern Panel *InitPreferences(WMScreen * scr, WMWidget * parent);
41 extern Panel *InitFont(WMScreen * scr, WMWidget * parent);
42 extern Panel *InitFontSimple(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);
60 #define ICON_TITLE_FONT "sans serif:pixelsize=9"
61 #define ICON_TITLE_VFONT "sans serif:pixelsize=9:weight=100"
63 #define MAX_SECTIONS 16
65 typedef struct _WPrefs {
66 WMWindow *win;
68 WMScrollView *scrollV;
69 WMFrame *buttonF;
70 WMButton *sectionB[MAX_SECTIONS];
72 int sectionCount;
74 WMButton *saveBtn;
75 WMButton *closeBtn;
76 WMButton *undoBtn;
77 WMButton *undosBtn;
79 WMButton *balloonBtn;
81 WMFrame *banner;
82 WMLabel *nameL;
83 WMLabel *versionL;
84 WMLabel *statusL;
86 Panel *currentPanel;
87 } _WPrefs;
89 static _WPrefs WPrefs;
91 /* system wide defaults dictionary. Read-only */
92 static WMPropList *GlobalDB = NULL;
93 /* user defaults dictionary */
94 static WMPropList *WindowMakerDB = NULL;
95 static char *WindowMakerDBPath = NULL;
97 static Bool TIFFOK = False;
99 #define INITIALIZED_PANEL (1<<0)
101 static void loadConfigurations(WMScreen * scr, WMWindow * mainw);
103 static void savePanelData(Panel * panel);
105 static void prepareForClose(void);
107 void quit(WMWidget * w, void *data)
109 prepareForClose();
111 exit(0);
114 static void save(WMWidget * w, void *data)
116 int i;
117 WMPropList *p1, *p2;
118 WMPropList *keyList;
119 WMPropList *key;
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);
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;
160 strncpy(ev.xclient.data.b, "Reconfigure", sizeof(ev.xclient.data.b));
162 XSendEvent(WMScreenDisplay(WMWidgetScreen(w)),
163 DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w))), False, SubstructureRedirectMask, &ev);
164 XFlush(WMScreenDisplay(WMWidgetScreen(w)));
167 static void undo(WMWidget * w, void *data)
169 PanelRec *rec = (PanelRec *) WPrefs.currentPanel;
171 if (!rec)
172 return;
174 if (rec->callbacks.undoChanges && (rec->callbacks.flags & INITIALIZED_PANEL)) {
175 (*rec->callbacks.undoChanges) (WPrefs.currentPanel);
179 static void undoAll(WMWidget * w, void *data)
181 int i;
183 for (i = 0; i < WPrefs.sectionCount; i++) {
184 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
186 if (rec->callbacks.undoChanges && (rec->callbacks.flags & INITIALIZED_PANEL))
187 (*rec->callbacks.undoChanges) ((Panel *) rec);
191 static void prepareForClose(void)
193 int i;
195 for (i = 0; i < WPrefs.sectionCount; i++) {
196 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
198 if (rec->callbacks.prepareForClose && (rec->callbacks.flags & INITIALIZED_PANEL))
199 (*rec->callbacks.prepareForClose) ((Panel *) rec);
203 void toggleBalloons(WMWidget * w, void *data)
205 WMUserDefaults *udb = WMGetStandardUserDefaults();
206 Bool flag;
208 flag = WMGetButtonSelected(WPrefs.balloonBtn);
210 WMSetBalloonEnabled(WMWidgetScreen(WPrefs.win), flag);
212 WMSetUDBoolForKey(udb, flag, "BalloonHelp");
215 static void createMainWindow(WMScreen * scr)
217 WMScroller *scroller;
218 WMFont *font;
219 char buffer[128];
221 WPrefs.win = WMCreateWindow(scr, "wprefs");
222 WMResizeWidget(WPrefs.win, 520, 390);
223 WMSetWindowTitle(WPrefs.win, _("Window Maker Preferences"));
224 WMSetWindowCloseAction(WPrefs.win, quit, NULL);
225 WMSetWindowMaxSize(WPrefs.win, 520, 390);
226 WMSetWindowMinSize(WPrefs.win, 520, 390);
227 WMSetWindowMiniwindowTitle(WPrefs.win, "Preferences");
229 WPrefs.scrollV = WMCreateScrollView(WPrefs.win);
230 WMResizeWidget(WPrefs.scrollV, 500, 87);
231 WMMoveWidget(WPrefs.scrollV, 10, 10);
232 WMSetScrollViewRelief(WPrefs.scrollV, WRSunken);
233 WMSetScrollViewHasHorizontalScroller(WPrefs.scrollV, True);
234 WMSetScrollViewHasVerticalScroller(WPrefs.scrollV, False);
235 scroller = WMGetScrollViewHorizontalScroller(WPrefs.scrollV);
236 WMSetScrollerArrowsPosition(scroller, WSANone);
238 WPrefs.buttonF = WMCreateFrame(WPrefs.win);
239 WMSetFrameRelief(WPrefs.buttonF, WRFlat);
241 WMSetScrollViewContentView(WPrefs.scrollV, WMWidgetView(WPrefs.buttonF));
243 WPrefs.undosBtn = WMCreateCommandButton(WPrefs.win);
244 WMResizeWidget(WPrefs.undosBtn, 90, 28);
245 WMMoveWidget(WPrefs.undosBtn, 135, 350);
246 WMSetButtonText(WPrefs.undosBtn, _("Revert Page"));
247 WMSetButtonAction(WPrefs.undosBtn, undo, NULL);
249 WPrefs.undoBtn = WMCreateCommandButton(WPrefs.win);
250 WMResizeWidget(WPrefs.undoBtn, 90, 28);
251 WMMoveWidget(WPrefs.undoBtn, 235, 350);
252 WMSetButtonText(WPrefs.undoBtn, _("Revert All"));
253 WMSetButtonAction(WPrefs.undoBtn, undoAll, NULL);
255 WPrefs.saveBtn = WMCreateCommandButton(WPrefs.win);
256 WMResizeWidget(WPrefs.saveBtn, 80, 28);
257 WMMoveWidget(WPrefs.saveBtn, 335, 350);
258 WMSetButtonText(WPrefs.saveBtn, _("Save"));
259 WMSetButtonAction(WPrefs.saveBtn, save, NULL);
261 WPrefs.closeBtn = WMCreateCommandButton(WPrefs.win);
262 WMResizeWidget(WPrefs.closeBtn, 80, 28);
263 WMMoveWidget(WPrefs.closeBtn, 425, 350);
264 WMSetButtonText(WPrefs.closeBtn, _("Close"));
265 WMSetButtonAction(WPrefs.closeBtn, quit, NULL);
267 WPrefs.balloonBtn = WMCreateSwitchButton(WPrefs.win);
268 WMResizeWidget(WPrefs.balloonBtn, 200, 28);
269 WMMoveWidget(WPrefs.balloonBtn, 15, 350);
270 WMSetButtonText(WPrefs.balloonBtn, _("Balloon Help"));
271 WMSetButtonAction(WPrefs.balloonBtn, toggleBalloons, NULL);
273 WMUserDefaults *udb = WMGetStandardUserDefaults();
274 Bool flag = WMGetUDBoolForKey(udb, "BalloonHelp");
276 WMSetButtonSelected(WPrefs.balloonBtn, flag);
277 WMSetBalloonEnabled(scr, flag);
280 /* banner */
281 WPrefs.banner = WMCreateFrame(WPrefs.win);
282 WMResizeWidget(WPrefs.banner, FRAME_WIDTH, FRAME_HEIGHT);
283 WMMoveWidget(WPrefs.banner, FRAME_LEFT, FRAME_TOP);
284 WMSetFrameRelief(WPrefs.banner, WRFlat);
286 font = WMCreateFont(scr, "Lucida Sans,URW Gothic L,Times New Roman,serif"
287 ":bold:pixelsize=26:antialias=true");
288 WPrefs.nameL = WMCreateLabel(WPrefs.banner);
289 WMSetLabelTextAlignment(WPrefs.nameL, WACenter);
290 WMResizeWidget(WPrefs.nameL, FRAME_WIDTH - 20, 60);
291 WMMoveWidget(WPrefs.nameL, 10, 50);
292 WMSetLabelFont(WPrefs.nameL, font);
293 WMSetLabelText(WPrefs.nameL, _("Window Maker Preferences"));
294 WMReleaseFont(font);
296 WPrefs.versionL = WMCreateLabel(WPrefs.banner);
297 WMResizeWidget(WPrefs.versionL, FRAME_WIDTH - 20, 20);
298 WMMoveWidget(WPrefs.versionL, 10, 120);
299 WMSetLabelTextAlignment(WPrefs.versionL, WACenter);
300 sprintf(buffer, _("Version %s"), VERSION);
301 WMSetLabelText(WPrefs.versionL, buffer);
303 WPrefs.statusL = WMCreateLabel(WPrefs.banner);
304 WMResizeWidget(WPrefs.statusL, FRAME_WIDTH - 20, 60);
305 WMMoveWidget(WPrefs.statusL, 10, 150);
306 WMSetLabelTextAlignment(WPrefs.statusL, WACenter);
307 WMSetLabelText(WPrefs.statusL, _("Starting..."));
309 WMMapSubwidgets(WPrefs.win);
311 WMUnmapWidget(WPrefs.undosBtn);
312 WMUnmapWidget(WPrefs.undoBtn);
313 WMUnmapWidget(WPrefs.saveBtn);
316 static void showPanel(Panel * panel)
318 PanelRec *rec = (PanelRec *) panel;
320 if (!(rec->callbacks.flags & INITIALIZED_PANEL)) {
321 (*rec->callbacks.createWidgets) (panel);
322 rec->callbacks.flags |= INITIALIZED_PANEL;
325 WMSetWindowTitle(WPrefs.win, rec->sectionName);
327 if (rec->callbacks.showPanel)
328 (*rec->callbacks.showPanel) (panel);
330 WMMapWidget(rec->box);
333 static void hidePanel(Panel * panel)
335 PanelRec *rec = (PanelRec *) panel;
337 WMUnmapWidget(rec->box);
339 if (rec->callbacks.hidePanel)
340 (*rec->callbacks.hidePanel) (panel);
343 static void savePanelData(Panel * panel)
345 PanelRec *rec = (PanelRec *) panel;
347 if (rec->callbacks.updateDomain) {
348 (*rec->callbacks.updateDomain) (panel);
352 static void changeSection(WMWidget * self, void *data)
354 if (WPrefs.currentPanel == data)
355 return;
357 if (WPrefs.currentPanel == NULL) {
358 WMDestroyWidget(WPrefs.nameL);
359 WMDestroyWidget(WPrefs.versionL);
360 WMDestroyWidget(WPrefs.statusL);
362 WMSetFrameRelief(WPrefs.banner, WRGroove);
364 /* WMMapWidget(WPrefs.undosBtn);
365 WMMapWidget(WPrefs.undoBtn);
367 WMMapWidget(WPrefs.saveBtn);
370 showPanel(data);
372 if (WPrefs.currentPanel)
373 hidePanel(WPrefs.currentPanel);
374 WPrefs.currentPanel = data;
377 char *LocateImage(const char *name)
379 char *path;
380 char *tmp = wmalloc(strlen(name) + 8);
382 if (TIFFOK) {
383 sprintf(tmp, "%s.tiff", name);
384 path = WMPathForResourceOfType(tmp, "tiff");
385 } else {
386 sprintf(tmp, "%s.xpm", name);
387 path = WMPathForResourceOfType(tmp, "xpm");
389 wfree(tmp);
390 if (!path) {
391 wwarning(_("could not locate image file %s"), name);
394 return path;
397 void CreateImages(WMScreen *scr, RContext *rc, RImage *xis, const char *file,
398 WMPixmap **icon_normal, WMPixmap **icon_greyed)
400 RImage *icon;
401 char *path;
402 RColor gray = { 0xae, 0xaa, 0xae, 0 };
404 path = LocateImage(file);
405 if (!path)
407 *icon_normal = NULL;
408 if (icon_greyed)
409 *icon_greyed = NULL;
410 return;
413 *icon_normal = WMCreatePixmapFromFile(scr, path);
414 if (!*icon_normal)
416 wwarning(_("could not load icon %s"), path);
417 if (icon_greyed)
418 *icon_greyed = NULL;
419 wfree(path);
420 return;
423 if (!icon_greyed) // Greyed-out version not requested, we are done
425 wfree(path);
426 return;
429 icon = RLoadImage(rc, path, 0);
430 if (!icon)
432 wwarning(_("could not load icon %s"), path);
433 *icon_greyed = NULL;
434 wfree(path);
435 return;
437 RCombineImageWithColor(icon, &gray);
438 if (xis)
440 RCombineImagesWithOpaqueness(icon, xis, 180);
442 *icon_greyed = WMCreatePixmapFromRImage(scr, icon, 127);
443 if (!*icon_greyed)
445 wwarning(_("could not process icon %s: %s"), path, RMessageForError(RErrorCode));
447 RReleaseImage(icon);
448 wfree(path);
452 static WMPixmap *makeTitledIcon(WMScreen * scr, WMPixmap * icon, const char *title1, const char *title2)
454 return WMRetainPixmap(icon);
456 #if 0
457 static GC gc = NULL;
458 static XFontStruct *hfont = NULL;
459 static XFontStruct *vfont = NULL;
460 WMPixmap *tmp;
461 Pixmap pix, mask;
462 Display *dpy = WMScreenDisplay(scr);
463 WMColor *black = WMBlackColor(scr);
464 GC fgc;
465 WMSize size = WMGetPixmapSize(icon);
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, size.width, size.height, 12, 12);
492 if (WMGetPixmapMaskXID(icon) != None)
493 XCopyPlane(dpy, WMGetPixmapMaskXID(icon), mask, gc, 0, 0, size.width, size.height, 12, 12, 1);
494 else
495 XFillRectangle(dpy, mask, gc, 12, 12, 48, 48);
497 if (title1) {
498 XSetFont(dpy, fgc, vfont->fid);
499 XSetFont(dpy, gc, vfont->fid);
501 XDrawString(dpy, pix, fgc, 0, vfont->ascent, title1, strlen(title1));
503 XDrawString(dpy, mask, gc, 0, vfont->ascent, title1, strlen(title1));
506 if (title2) {
507 XSetFont(dpy, fgc, hfont->fid);
508 XSetFont(dpy, gc, hfont->fid);
510 XDrawString(dpy, pix, fgc, (title1 ? 12 : 0), hfont->ascent, title2, strlen(title2));
512 XDrawString(dpy, mask, gc, (title1 ? 12 : 0), hfont->ascent, title2, strlen(title2));
515 return tmp;
516 #endif
519 void SetButtonAlphaImage(WMScreen * scr, WMButton * bPtr, const char *file, const char *title1, const char *title2)
521 WMPixmap *icon;
522 WMPixmap *icon2;
523 RColor color;
524 char *iconPath;
526 iconPath = LocateImage(file);
528 color.red = 0xae;
529 color.green = 0xaa;
530 color.blue = 0xae;
531 color.alpha = 0;
532 if (iconPath) {
533 icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
534 if (!icon)
535 wwarning(_("could not load icon file %s"), iconPath);
536 } else {
537 icon = NULL;
540 if (icon) {
541 icon2 = makeTitledIcon(scr, icon, title1, title2);
542 if (icon)
543 WMReleasePixmap(icon);
544 } else {
545 icon2 = NULL;
548 WMSetButtonImage(bPtr, icon2);
550 if (icon2)
551 WMReleasePixmap(icon2);
553 color.red = 0xff;
554 color.green = 0xff;
555 color.blue = 0xff;
556 color.alpha = 0;
557 if (iconPath) {
558 icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
559 if (!icon)
560 wwarning(_("could not load icon file %s"), iconPath);
561 } else {
562 icon = NULL;
565 WMSetButtonAltImage(bPtr, icon);
567 if (icon)
568 WMReleasePixmap(icon);
570 if (iconPath)
571 wfree(iconPath);
574 void AddSection(Panel * panel, const char *iconFile)
576 WMButton *bPtr;
578 assert(WPrefs.sectionCount < MAX_SECTIONS);
580 bPtr = WMCreateCustomButton(WPrefs.buttonF, WBBStateLightMask | WBBStateChangeMask);
581 WMResizeWidget(bPtr, 64, 64);
582 WMMoveWidget(bPtr, WPrefs.sectionCount * 64, 0);
583 WMSetButtonImagePosition(bPtr, WIPImageOnly);
584 WMSetButtonAction(bPtr, changeSection, panel);
585 WMHangData(bPtr, panel);
587 WMSetBalloonTextForView(((PanelRec *) panel)->description, WMWidgetView(bPtr));
590 char *t1, *t2;
592 t1 = wstrdup(((PanelRec *) panel)->sectionName);
593 t2 = strchr(t1, ' ');
594 if (t2) {
595 *t2 = 0;
596 t2++;
598 SetButtonAlphaImage(WMWidgetScreen(bPtr), bPtr, iconFile, t1, t2);
599 wfree(t1);
601 WMMapWidget(bPtr);
603 WPrefs.sectionB[WPrefs.sectionCount] = bPtr;
605 if (WPrefs.sectionCount > 0) {
606 WMGroupButtons(WPrefs.sectionB[0], bPtr);
609 WPrefs.sectionCount++;
611 WMResizeWidget(WPrefs.buttonF, WPrefs.sectionCount * 64, 64);
614 void Initialize(WMScreen * scr)
616 char **list;
617 int i;
618 char *path;
620 list = RSupportedFileFormats();
621 for (i = 0; list[i] != NULL; i++) {
622 if (strcmp(list[i], "TIFF") == 0) {
623 TIFFOK = True;
624 break;
628 if (TIFFOK)
629 path = WMPathForResourceOfType("WPrefs.tiff", NULL);
630 else
631 path = WMPathForResourceOfType("WPrefs.xpm", NULL);
632 if (path) {
633 RImage *tmp;
635 tmp = RLoadImage(WMScreenRContext(scr), path, 0);
636 if (!tmp) {
637 wwarning(_("could not load image file %s:%s"), path, RMessageForError(RErrorCode));
638 } else {
639 WMSetApplicationIconImage(scr, tmp);
640 RReleaseImage(tmp);
642 wfree(path);
645 memset(&WPrefs, 0, sizeof(_WPrefs));
646 createMainWindow(scr);
648 WMRealizeWidget(WPrefs.win);
650 WMSetWindowMiniwindowImage(WPrefs.win, WMGetApplicationIconImage(scr));
652 WMMapWidget(WPrefs.win);
653 XFlush(WMScreenDisplay(scr));
654 WMSetLabelText(WPrefs.statusL, _("Loading Window Maker configuration files..."));
655 XFlush(WMScreenDisplay(scr));
656 loadConfigurations(scr, WPrefs.win);
658 WMSetLabelText(WPrefs.statusL, _("Initializing configuration panels..."));
660 InitFocus(scr, WPrefs.banner);
661 InitWindowHandling(scr, WPrefs.banner);
663 InitMenuPreferences(scr, WPrefs.banner);
664 InitIcons(scr, WPrefs.banner);
665 InitPreferences(scr, WPrefs.banner);
667 InitPaths(scr, WPrefs.banner);
668 InitDocks(scr, WPrefs.banner);
669 InitWorkspace(scr, WPrefs.banner);
670 InitConfigurations(scr, WPrefs.banner);
672 InitMenu(scr, WPrefs.banner);
674 #ifdef not_yet_fully_implemented
675 InitKeyboardSettings(scr, WPrefs.banner);
676 #endif
677 InitKeyboardShortcuts(scr, WPrefs.banner);
678 InitMouseSettings(scr, WPrefs.banner);
680 InitAppearance(scr, WPrefs.banner);
682 InitFontSimple(scr, WPrefs.banner);
684 #ifdef not_yet_fully_implemented
685 InitThemes(scr, WPrefs.banner);
686 #endif
687 InitExpert(scr, WPrefs.banner);
689 WMRealizeWidget(WPrefs.scrollV);
691 WMSetLabelText(WPrefs.statusL, "");
694 WMWindow *GetWindow(Panel * panel)
696 return WPrefs.win;
699 static void loadConfigurations(WMScreen * scr, WMWindow * mainw)
701 WMPropList *db, *gdb;
702 char *path;
703 FILE *file;
704 char buffer[1024];
705 char mbuf[1024];
706 int v1, v2, v3;
708 path = wdefaultspathfordomain("WindowMaker");
709 WindowMakerDBPath = path;
711 db = WMReadPropListFromFile(path);
712 if (db) {
713 if (!WMIsPLDictionary(db)) {
714 WMReleasePropList(db);
715 db = NULL;
716 sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), path);
717 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
719 } else {
720 sprintf(mbuf, _("Could not load Window Maker domain (%s) from defaults database."), path);
721 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
724 path = getenv("WMAKER_BIN_NAME");
725 if (!path)
726 path = "wmaker";
728 char *command;
730 command = wstrconcat(path, " --version");
731 file = popen(command, "r");
732 wfree(command);
734 if (!file || !fgets(buffer, 1023, file)) {
735 werror(_("could not extract version information from Window Maker"));
736 wfatal(_("Make sure wmaker is in your search path."));
738 WMRunAlertPanel(scr, mainw, _("Error"),
740 ("Could not extract version from Window Maker. Make sure it is correctly installed and is in your PATH environment variable."),
741 _("OK"), NULL, NULL);
742 exit(1);
744 if (file)
745 pclose(file);
747 if (sscanf(buffer, "Window Maker %i.%i.%i", &v1, &v2, &v3) != 3
748 && sscanf(buffer, "WindowMaker %i.%i.%i", &v1, &v2, &v3) != 3) {
749 WMRunAlertPanel(scr, mainw, _("Error"),
750 _("Could not extract version from Window Maker. "
751 "Make sure it is correctly installed and the path "
752 "where it installed is in the PATH environment "
753 "variable."), _("OK"), NULL, NULL);
754 exit(1);
756 if (v1 == 0 && (v2 < 18 || v3 < 0)) {
757 sprintf(mbuf, _("WPrefs only supports Window Maker 0.18.0 or newer.\n"
758 "The version installed is %i.%i.%i\n"), v1, v2, v3);
759 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
760 exit(1);
763 if (v1 > 1 || (v1 == 1 && (v2 > 0))) {
764 sprintf(mbuf,
766 ("Window Maker %i.%i.%i, which is installed in your system, is not fully supported by this version of WPrefs."),
767 v1, v2, v3);
768 WMRunAlertPanel(scr, mainw, _("Warning"), mbuf, _("OK"), NULL, NULL);
772 char *command;
774 command = wstrconcat(path, " --global_defaults_path");
775 file = popen(command, "r");
776 wfree(command);
778 if (!file || !fgets(buffer, 1023, file)) {
779 werror(_("could not run \"%s --global_defaults_path\"."), path);
780 exit(1);
781 } else {
782 char *ptr;
783 ptr = strchr(buffer, '\n');
784 if (ptr)
785 *ptr = 0;
786 strcat(buffer, "/WindowMaker");
789 if (file)
790 pclose(file);
792 gdb = WMReadPropListFromFile(buffer);
794 if (gdb) {
795 if (!WMIsPLDictionary(gdb)) {
796 WMReleasePropList(gdb);
797 gdb = NULL;
798 sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), buffer);
799 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
801 } else {
802 sprintf(mbuf, _("Could not load global Window Maker domain (%s)."), buffer);
803 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
806 if (!db) {
807 db = WMCreatePLDictionary(NULL, NULL);
809 if (!gdb) {
810 gdb = WMCreatePLDictionary(NULL, NULL);
813 GlobalDB = gdb;
815 WindowMakerDB = db;
818 WMPropList *GetObjectForKey(const char *defaultName)
820 WMPropList *object = NULL;
821 WMPropList *key = WMCreatePLString(defaultName);
823 object = WMGetFromPLDictionary(WindowMakerDB, key);
824 if (!object)
825 object = WMGetFromPLDictionary(GlobalDB, key);
827 WMReleasePropList(key);
829 return object;
832 void SetObjectForKey(WMPropList * object, const char *defaultName)
834 WMPropList *key = WMCreatePLString(defaultName);
836 WMPutInPLDictionary(WindowMakerDB, key, object);
837 WMReleasePropList(key);
840 void RemoveObjectForKey(const char *defaultName)
842 WMPropList *key = WMCreatePLString(defaultName);
844 WMRemoveFromPLDictionary(WindowMakerDB, key);
846 WMReleasePropList(key);
849 char *GetStringForKey(const char *defaultName)
851 WMPropList *val;
853 val = GetObjectForKey(defaultName);
855 if (!val)
856 return NULL;
858 if (!WMIsPLString(val))
859 return NULL;
861 return WMGetFromPLString(val);
864 WMPropList *GetArrayForKey(const char *defaultName)
866 WMPropList *val;
868 val = GetObjectForKey(defaultName);
870 if (!val)
871 return NULL;
873 if (!WMIsPLArray(val))
874 return NULL;
876 return val;
879 WMPropList *GetDictionaryForKey(const char *defaultName)
881 WMPropList *val;
883 val = GetObjectForKey(defaultName);
885 if (!val)
886 return NULL;
888 if (!WMIsPLDictionary(val))
889 return NULL;
891 return val;
894 int GetIntegerForKey(const char *defaultName)
896 WMPropList *val;
897 char *str;
898 int value;
900 val = GetObjectForKey(defaultName);
902 if (!val)
903 return 0;
905 if (!WMIsPLString(val))
906 return 0;
908 str = WMGetFromPLString(val);
909 if (!str)
910 return 0;
912 if (sscanf(str, "%i", &value) != 1)
913 return 0;
915 return value;
918 Bool GetBoolForKey(const char *defaultName)
920 int value;
921 char *str;
923 str = GetStringForKey(defaultName);
925 if (!str)
926 return False;
928 if (sscanf(str, "%i", &value) == 1 && value != 0)
929 return True;
931 if (strcasecmp(str, "YES") == 0)
932 return True;
934 if (strcasecmp(str, "Y") == 0)
935 return True;
937 return False;
940 void SetIntegerForKey(int value, const char *defaultName)
942 WMPropList *object;
943 char buffer[128];
945 sprintf(buffer, "%i", value);
946 object = WMCreatePLString(buffer);
948 SetObjectForKey(object, defaultName);
949 WMReleasePropList(object);
952 void SetStringForKey(const char *value, const const char *defaultName)
954 WMPropList *object;
956 object = WMCreatePLString(value);
958 SetObjectForKey(object, defaultName);
959 WMReleasePropList(object);
962 void SetBoolForKey(Bool value, const char *defaultName)
964 static WMPropList *yes = NULL, *no = NULL;
966 if (!yes) {
967 yes = WMCreatePLString("YES");
968 no = WMCreatePLString("NO");
971 SetObjectForKey(value ? yes : no, defaultName);
974 void SetSpeedForKey(int speed, const char *defaultName)
976 char *str;
978 switch (speed) {
979 case 0:
980 str = "ultraslow";
981 break;
982 case 1:
983 str = "slow";
984 break;
985 case 2:
986 str = "medium";
987 break;
988 case 3:
989 str = "fast";
990 break;
991 case 4:
992 str = "ultrafast";
993 break;
994 default:
995 str = NULL;
998 if (str)
999 SetStringForKey(str, defaultName);
1002 int GetSpeedForKey(const char *defaultName)
1004 char *str;
1005 int i;
1007 str = GetStringForKey(defaultName);
1008 if (!str)
1009 return 2;
1011 if (strcasecmp(str, "ultraslow") == 0)
1012 i = 0;
1013 else if (strcasecmp(str, "slow") == 0)
1014 i = 1;
1015 else if (strcasecmp(str, "medium") == 0)
1016 i = 2;
1017 else if (strcasecmp(str, "fast") == 0)
1018 i = 3;
1019 else if (strcasecmp(str, "ultrafast") == 0)
1020 i = 4;
1021 else {
1022 wwarning(_("bad speed value for option %s; using default Medium"), defaultName);
1023 i = 2;
1025 return i;