Improve dockapp recognition
[wmaker-crm.git] / WPrefs.app / WPrefs.c
blob231a3ef97cbf8d00ef6727e7184d9deb44e8be9f
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 XEvent ev;
121 /* puts("gathering data"); */
122 for (i = 0; i < WPrefs.sectionCount; i++) {
123 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
124 if ((rec->callbacks.flags & INITIALIZED_PANEL))
125 savePanelData((Panel *) rec);
127 /* puts("compressing data"); */
128 /* compare the user dictionary with the global and remove redundant data */
129 keyList = WMGetPLDictionaryKeys(GlobalDB);
130 /* puts(WMGetPropListDescription(WindowMakerDB, False)); */
131 for (i = 0; i < WMGetPropListItemCount(keyList); i++) {
132 key = WMGetFromPLArray(keyList, i);
134 /* We don't have this value anyway, so no problem.
135 * Probably a new option */
136 p1 = WMGetFromPLDictionary(WindowMakerDB, key);
137 if (!p1)
138 continue;
139 /* The global doesn't have it, so no problem either. */
140 p2 = WMGetFromPLDictionary(GlobalDB, key);
141 if (!p2)
142 continue;
143 /* If both values are the same, don't save. */
144 if (WMIsPropListEqualTo(p1, p2))
145 WMRemoveFromPLDictionary(WindowMakerDB, key);
147 /* puts(WMGetPropListDescription(WindowMakerDB, False)); */
148 WMReleasePropList(keyList);
149 /* puts("storing data"); */
151 WMWritePropListToFile(WindowMakerDB, WindowMakerDBPath);
153 memset(&ev, 0, sizeof(XEvent));
155 ev.xclient.type = ClientMessage;
156 ev.xclient.message_type = XInternAtom(WMScreenDisplay(WMWidgetScreen(w)), "_WINDOWMAKER_COMMAND", False);
157 ev.xclient.window = DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w)));
158 ev.xclient.format = 8;
159 strncpy(ev.xclient.data.b, "Reconfigure", sizeof(ev.xclient.data.b));
161 XSendEvent(WMScreenDisplay(WMWidgetScreen(w)),
162 DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w))), False, SubstructureRedirectMask, &ev);
163 XFlush(WMScreenDisplay(WMWidgetScreen(w)));
166 static void undo(WMWidget * w, void *data)
168 PanelRec *rec = (PanelRec *) WPrefs.currentPanel;
170 if (!rec)
171 return;
173 if (rec->callbacks.undoChanges && (rec->callbacks.flags & INITIALIZED_PANEL)) {
174 (*rec->callbacks.undoChanges) (WPrefs.currentPanel);
178 static void undoAll(WMWidget * w, void *data)
180 int i;
182 for (i = 0; i < WPrefs.sectionCount; i++) {
183 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
185 if (rec->callbacks.undoChanges && (rec->callbacks.flags & INITIALIZED_PANEL))
186 (*rec->callbacks.undoChanges) ((Panel *) rec);
190 static void prepareForClose()
192 int i;
194 for (i = 0; i < WPrefs.sectionCount; i++) {
195 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
197 if (rec->callbacks.prepareForClose && (rec->callbacks.flags & INITIALIZED_PANEL))
198 (*rec->callbacks.prepareForClose) ((Panel *) rec);
202 void toggleBalloons(WMWidget * w, void *data)
204 WMUserDefaults *udb = WMGetStandardUserDefaults();
205 Bool flag;
207 flag = WMGetButtonSelected(WPrefs.balloonBtn);
209 WMSetBalloonEnabled(WMWidgetScreen(WPrefs.win), flag);
211 WMSetUDBoolForKey(udb, flag, "BalloonHelp");
214 static void createMainWindow(WMScreen * scr)
216 WMScroller *scroller;
217 WMFont *font;
218 char buffer[128];
220 WPrefs.win = WMCreateWindow(scr, "wprefs");
221 WMResizeWidget(WPrefs.win, 520, 390);
222 WMSetWindowTitle(WPrefs.win, _("Window Maker Preferences"));
223 WMSetWindowCloseAction(WPrefs.win, quit, NULL);
224 WMSetWindowMaxSize(WPrefs.win, 520, 390);
225 WMSetWindowMinSize(WPrefs.win, 520, 390);
226 WMSetWindowMiniwindowTitle(WPrefs.win, "Preferences");
228 WPrefs.scrollV = WMCreateScrollView(WPrefs.win);
229 WMResizeWidget(WPrefs.scrollV, 500, 87);
230 WMMoveWidget(WPrefs.scrollV, 10, 10);
231 WMSetScrollViewRelief(WPrefs.scrollV, WRSunken);
232 WMSetScrollViewHasHorizontalScroller(WPrefs.scrollV, True);
233 WMSetScrollViewHasVerticalScroller(WPrefs.scrollV, False);
234 scroller = WMGetScrollViewHorizontalScroller(WPrefs.scrollV);
235 WMSetScrollerArrowsPosition(scroller, WSANone);
237 WPrefs.buttonF = WMCreateFrame(WPrefs.win);
238 WMSetFrameRelief(WPrefs.buttonF, WRFlat);
240 WMSetScrollViewContentView(WPrefs.scrollV, WMWidgetView(WPrefs.buttonF));
242 WPrefs.undosBtn = WMCreateCommandButton(WPrefs.win);
243 WMResizeWidget(WPrefs.undosBtn, 90, 28);
244 WMMoveWidget(WPrefs.undosBtn, 135, 350);
245 WMSetButtonText(WPrefs.undosBtn, _("Revert Page"));
246 WMSetButtonAction(WPrefs.undosBtn, undo, NULL);
248 WPrefs.undoBtn = WMCreateCommandButton(WPrefs.win);
249 WMResizeWidget(WPrefs.undoBtn, 90, 28);
250 WMMoveWidget(WPrefs.undoBtn, 235, 350);
251 WMSetButtonText(WPrefs.undoBtn, _("Revert All"));
252 WMSetButtonAction(WPrefs.undoBtn, undoAll, NULL);
254 WPrefs.saveBtn = WMCreateCommandButton(WPrefs.win);
255 WMResizeWidget(WPrefs.saveBtn, 80, 28);
256 WMMoveWidget(WPrefs.saveBtn, 335, 350);
257 WMSetButtonText(WPrefs.saveBtn, _("Save"));
258 WMSetButtonAction(WPrefs.saveBtn, save, NULL);
260 WPrefs.closeBtn = WMCreateCommandButton(WPrefs.win);
261 WMResizeWidget(WPrefs.closeBtn, 80, 28);
262 WMMoveWidget(WPrefs.closeBtn, 425, 350);
263 WMSetButtonText(WPrefs.closeBtn, _("Close"));
264 WMSetButtonAction(WPrefs.closeBtn, quit, NULL);
266 WPrefs.balloonBtn = WMCreateSwitchButton(WPrefs.win);
267 WMResizeWidget(WPrefs.balloonBtn, 200, 28);
268 WMMoveWidget(WPrefs.balloonBtn, 15, 350);
269 WMSetButtonText(WPrefs.balloonBtn, _("Balloon Help"));
270 WMSetButtonAction(WPrefs.balloonBtn, toggleBalloons, NULL);
272 WMUserDefaults *udb = WMGetStandardUserDefaults();
273 Bool flag = WMGetUDBoolForKey(udb, "BalloonHelp");
275 WMSetButtonSelected(WPrefs.balloonBtn, flag);
276 WMSetBalloonEnabled(scr, flag);
279 /* banner */
280 WPrefs.banner = WMCreateFrame(WPrefs.win);
281 WMResizeWidget(WPrefs.banner, FRAME_WIDTH, FRAME_HEIGHT);
282 WMMoveWidget(WPrefs.banner, FRAME_LEFT, FRAME_TOP);
283 WMSetFrameRelief(WPrefs.banner, WRFlat);
285 font = WMCreateFont(scr, "Lucida Sans,URW Gothic L,Times New Roman,serif"
286 ":bold:pixelsize=26:antialias=true");
287 WPrefs.nameL = WMCreateLabel(WPrefs.banner);
288 WMSetLabelTextAlignment(WPrefs.nameL, WACenter);
289 WMResizeWidget(WPrefs.nameL, FRAME_WIDTH - 20, 60);
290 WMMoveWidget(WPrefs.nameL, 10, 50);
291 WMSetLabelFont(WPrefs.nameL, font);
292 WMSetLabelText(WPrefs.nameL, _("Window Maker Preferences"));
293 WMReleaseFont(font);
295 WPrefs.versionL = WMCreateLabel(WPrefs.banner);
296 WMResizeWidget(WPrefs.versionL, FRAME_WIDTH - 20, 20);
297 WMMoveWidget(WPrefs.versionL, 10, 120);
298 WMSetLabelTextAlignment(WPrefs.versionL, WACenter);
299 sprintf(buffer, _("Version %s"), VERSION);
300 WMSetLabelText(WPrefs.versionL, buffer);
302 WPrefs.statusL = WMCreateLabel(WPrefs.banner);
303 WMResizeWidget(WPrefs.statusL, FRAME_WIDTH - 20, 60);
304 WMMoveWidget(WPrefs.statusL, 10, 150);
305 WMSetLabelTextAlignment(WPrefs.statusL, WACenter);
306 WMSetLabelText(WPrefs.statusL, _("Starting..."));
308 WMMapSubwidgets(WPrefs.win);
310 WMUnmapWidget(WPrefs.undosBtn);
311 WMUnmapWidget(WPrefs.undoBtn);
312 WMUnmapWidget(WPrefs.saveBtn);
315 static void showPanel(Panel * panel)
317 PanelRec *rec = (PanelRec *) panel;
319 if (!(rec->callbacks.flags & INITIALIZED_PANEL)) {
320 (*rec->callbacks.createWidgets) (panel);
321 rec->callbacks.flags |= INITIALIZED_PANEL;
324 WMSetWindowTitle(WPrefs.win, rec->sectionName);
326 if (rec->callbacks.showPanel)
327 (*rec->callbacks.showPanel) (panel);
329 WMMapWidget(rec->box);
332 static void hidePanel(Panel * panel)
334 PanelRec *rec = (PanelRec *) panel;
336 WMUnmapWidget(rec->box);
338 if (rec->callbacks.hidePanel)
339 (*rec->callbacks.hidePanel) (panel);
342 static void savePanelData(Panel * panel)
344 PanelRec *rec = (PanelRec *) panel;
346 if (rec->callbacks.updateDomain) {
347 (*rec->callbacks.updateDomain) (panel);
351 static void changeSection(WMWidget * self, void *data)
353 if (WPrefs.currentPanel == data)
354 return;
356 if (WPrefs.currentPanel == NULL) {
357 WMDestroyWidget(WPrefs.nameL);
358 WMDestroyWidget(WPrefs.versionL);
359 WMDestroyWidget(WPrefs.statusL);
361 WMSetFrameRelief(WPrefs.banner, WRGroove);
363 /* WMMapWidget(WPrefs.undosBtn);
364 WMMapWidget(WPrefs.undoBtn);
366 WMMapWidget(WPrefs.saveBtn);
369 showPanel(data);
371 if (WPrefs.currentPanel)
372 hidePanel(WPrefs.currentPanel);
373 WPrefs.currentPanel = data;
376 char *LocateImage(char *name)
378 char *path;
379 char *tmp = wmalloc(strlen(name) + 8);
381 if (TIFFOK) {
382 sprintf(tmp, "%s.tiff", name);
383 path = WMPathForResourceOfType(tmp, "tiff");
384 } else {
385 sprintf(tmp, "%s.xpm", name);
386 path = WMPathForResourceOfType(tmp, "xpm");
388 wfree(tmp);
389 if (!path) {
390 wwarning(_("could not locate image file %s\n"), name);
393 return path;
396 static WMPixmap *makeTitledIcon(WMScreen * scr, WMPixmap * icon, char *title1, char *title2)
398 return WMRetainPixmap(icon);
400 #if 0
401 static GC gc = NULL;
402 static XFontStruct *hfont = NULL;
403 static XFontStruct *vfont = NULL;
404 WMPixmap *tmp;
405 Pixmap pix, mask;
406 Display *dpy = WMScreenDisplay(scr);
407 WMColor *black = WMBlackColor(scr);
408 GC fgc;
409 WMSize size = WMGetPixmapSize(icon);
411 tmp = WMCreatePixmap(scr, 60, 60, WMScreenDepth(scr), True);
413 pix = WMGetPixmapXID(tmp);
414 mask = WMGetPixmapMaskXID(tmp);
416 if (gc == NULL) {
417 gc = XCreateGC(dpy, mask, 0, NULL);
419 hfont = XLoadQueryFont(dpy, ICON_TITLE_FONT);
420 vfont = XLoadQueryFont(dpy, ICON_TITLE_VFONT);
423 if (hfont == NULL) {
424 return WMRetainPixmap(icon);
427 XSetForeground(dpy, gc, 0);
428 XFillRectangle(dpy, mask, gc, 0, 0, 60, 60);
430 fgc = WMColorGC(black);
432 XSetForeground(dpy, gc, 1);
434 XCopyArea(dpy, WMGetPixmapXID(icon), pix, fgc, 0, 0, size.width, size.height, 12, 12);
436 if (WMGetPixmapMaskXID(icon) != None)
437 XCopyPlane(dpy, WMGetPixmapMaskXID(icon), mask, gc, 0, 0, size.width, size.height, 12, 12, 1);
438 else
439 XFillRectangle(dpy, mask, gc, 12, 12, 48, 48);
441 if (title1) {
442 XSetFont(dpy, fgc, vfont->fid);
443 XSetFont(dpy, gc, vfont->fid);
445 XDrawString(dpy, pix, fgc, 0, vfont->ascent, title1, strlen(title1));
447 XDrawString(dpy, mask, gc, 0, vfont->ascent, title1, strlen(title1));
450 if (title2) {
451 XSetFont(dpy, fgc, hfont->fid);
452 XSetFont(dpy, gc, hfont->fid);
454 XDrawString(dpy, pix, fgc, (title1 ? 12 : 0), hfont->ascent, title2, strlen(title2));
456 XDrawString(dpy, mask, gc, (title1 ? 12 : 0), hfont->ascent, title2, strlen(title2));
459 return tmp;
460 #endif
463 void SetButtonAlphaImage(WMScreen * scr, WMButton * bPtr, char *file, char *title1, char *title2)
465 WMPixmap *icon;
466 WMPixmap *icon2;
467 RColor color;
468 char *iconPath;
470 iconPath = LocateImage(file);
472 color.red = 0xae;
473 color.green = 0xaa;
474 color.blue = 0xae;
475 color.alpha = 0;
476 if (iconPath) {
477 icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
478 if (!icon)
479 wwarning(_("could not load icon file %s"), iconPath);
480 } else {
481 icon = NULL;
484 if (icon) {
485 icon2 = makeTitledIcon(scr, icon, title1, title2);
486 if (icon)
487 WMReleasePixmap(icon);
488 } else {
489 icon2 = NULL;
492 WMSetButtonImage(bPtr, icon2);
494 if (icon2)
495 WMReleasePixmap(icon2);
497 color.red = 0xff;
498 color.green = 0xff;
499 color.blue = 0xff;
500 color.alpha = 0;
501 if (iconPath) {
502 icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
503 if (!icon)
504 wwarning(_("could not load icon file %s"), iconPath);
505 } else {
506 icon = NULL;
509 WMSetButtonAltImage(bPtr, icon);
511 if (icon)
512 WMReleasePixmap(icon);
514 if (iconPath)
515 wfree(iconPath);
518 void AddSection(Panel * panel, char *iconFile)
520 WMButton *bPtr;
522 assert(WPrefs.sectionCount < MAX_SECTIONS);
524 bPtr = WMCreateCustomButton(WPrefs.buttonF, WBBStateLightMask | WBBStateChangeMask);
525 WMResizeWidget(bPtr, 64, 64);
526 WMMoveWidget(bPtr, WPrefs.sectionCount * 64, 0);
527 WMSetButtonImagePosition(bPtr, WIPImageOnly);
528 WMSetButtonAction(bPtr, changeSection, panel);
529 WMHangData(bPtr, panel);
531 WMSetBalloonTextForView(((PanelRec *) panel)->description, WMWidgetView(bPtr));
534 char *t1, *t2;
536 t1 = wstrdup(((PanelRec *) panel)->sectionName);
537 t2 = strchr(t1, ' ');
538 if (t2) {
539 *t2 = 0;
540 t2++;
542 SetButtonAlphaImage(WMWidgetScreen(bPtr), bPtr, iconFile, t1, t2);
543 wfree(t1);
545 WMMapWidget(bPtr);
547 WPrefs.sectionB[WPrefs.sectionCount] = bPtr;
549 if (WPrefs.sectionCount > 0) {
550 WMGroupButtons(WPrefs.sectionB[0], bPtr);
553 WPrefs.sectionCount++;
555 WMResizeWidget(WPrefs.buttonF, WPrefs.sectionCount * 64, 64);
558 void Initialize(WMScreen * scr)
560 char **list;
561 int i;
562 char *path;
564 list = RSupportedFileFormats();
565 for (i = 0; list[i] != NULL; i++) {
566 if (strcmp(list[i], "TIFF") == 0) {
567 TIFFOK = True;
568 break;
572 if (TIFFOK)
573 path = WMPathForResourceOfType("WPrefs.tiff", NULL);
574 else
575 path = WMPathForResourceOfType("WPrefs.xpm", NULL);
576 if (path) {
577 RImage *tmp;
579 tmp = RLoadImage(WMScreenRContext(scr), path, 0);
580 if (!tmp) {
581 wwarning(_("could not load image file %s:%s"), path, RMessageForError(RErrorCode));
582 } else {
583 WMSetApplicationIconImage(scr, tmp);
584 RReleaseImage(tmp);
586 wfree(path);
589 memset(&WPrefs, 0, sizeof(_WPrefs));
590 createMainWindow(scr);
592 WMRealizeWidget(WPrefs.win);
594 WMSetWindowMiniwindowImage(WPrefs.win, WMGetApplicationIconImage(scr));
596 WMMapWidget(WPrefs.win);
597 XFlush(WMScreenDisplay(scr));
598 WMSetLabelText(WPrefs.statusL, _("Loading Window Maker configuration files..."));
599 XFlush(WMScreenDisplay(scr));
600 loadConfigurations(scr, WPrefs.win);
602 WMSetLabelText(WPrefs.statusL, _("Initializing configuration panels..."));
604 InitFocus(scr, WPrefs.banner);
605 InitWindowHandling(scr, WPrefs.banner);
607 InitMenuPreferences(scr, WPrefs.banner);
608 InitIcons(scr, WPrefs.banner);
609 InitPreferences(scr, WPrefs.banner);
611 InitPaths(scr, WPrefs.banner);
612 InitWorkspace(scr, WPrefs.banner);
613 InitConfigurations(scr, WPrefs.banner);
615 InitMenu(scr, WPrefs.banner);
617 #ifdef not_yet_fully_implemented
618 InitKeyboardSettings(scr, WPrefs.banner);
619 #endif
620 InitKeyboardShortcuts(scr, WPrefs.banner);
621 InitMouseSettings(scr, WPrefs.banner);
623 InitAppearance(scr, WPrefs.banner);
625 InitFontSimple(scr, WPrefs.banner);
627 #ifdef not_yet_fully_implemented
628 InitThemes(scr, WPrefs.banner);
629 #endif
630 InitExpert(scr, WPrefs.banner);
632 WMRealizeWidget(WPrefs.scrollV);
634 WMSetLabelText(WPrefs.statusL, "");
637 WMWindow *GetWindow(Panel * panel)
639 return WPrefs.win;
642 static void loadConfigurations(WMScreen * scr, WMWindow * mainw)
644 WMPropList *db, *gdb;
645 char *path;
646 FILE *file;
647 char buffer[1024];
648 char mbuf[1024];
649 int v1, v2, v3;
651 path = wdefaultspathfordomain("WindowMaker");
652 WindowMakerDBPath = path;
654 db = WMReadPropListFromFile(path);
655 if (db) {
656 if (!WMIsPLDictionary(db)) {
657 WMReleasePropList(db);
658 db = NULL;
659 sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), path);
660 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
662 } else {
663 sprintf(mbuf, _("Could not load Window Maker domain (%s) from defaults database."), path);
664 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
667 path = getenv("WMAKER_BIN_NAME");
668 if (!path)
669 path = "wmaker";
671 char *command;
673 command = wstrconcat(path, " --version");
674 file = popen(command, "r");
675 wfree(command);
677 if (!file || !fgets(buffer, 1023, file)) {
678 wsyserror(_("could not extract version information from Window Maker"));
679 wfatal(_("Make sure wmaker is in your search path."));
681 WMRunAlertPanel(scr, mainw, _("Error"),
683 ("Could not extract version from Window Maker. Make sure it is correctly installed and is in your PATH environment variable."),
684 _("OK"), NULL, NULL);
685 exit(1);
687 if (file)
688 pclose(file);
690 if (sscanf(buffer, "Window Maker %i.%i.%i", &v1, &v2, &v3) != 3
691 && sscanf(buffer, "WindowMaker %i.%i.%i", &v1, &v2, &v3) != 3) {
692 WMRunAlertPanel(scr, mainw, _("Error"),
693 _("Could not extract version from Window Maker. "
694 "Make sure it is correctly installed and the path "
695 "where it installed is in the PATH environment "
696 "variable."), _("OK"), NULL, NULL);
697 exit(1);
699 if (v1 == 0 && (v2 < 18 || v3 < 0)) {
700 sprintf(mbuf, _("WPrefs only supports Window Maker 0.18.0 or newer.\n"
701 "The version installed is %i.%i.%i\n"), v1, v2, v3);
702 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
703 exit(1);
706 if (v1 > 1 || (v1 == 1 && (v2 > 0))) {
707 sprintf(mbuf,
709 ("Window Maker %i.%i.%i, which is installed in your system, is not fully supported by this version of WPrefs."),
710 v1, v2, v3);
711 WMRunAlertPanel(scr, mainw, _("Warning"), mbuf, _("OK"), NULL, NULL);
715 char *command;
717 command = wstrconcat(path, " --global_defaults_path");
718 file = popen(command, "r");
719 wfree(command);
721 if (!file || !fgets(buffer, 1023, file)) {
722 wsyserror(_("could not run \"%s --global_defaults_path\"."), path);
723 exit(1);
724 } else {
725 char *ptr;
726 ptr = strchr(buffer, '\n');
727 if (ptr)
728 *ptr = 0;
729 strcat(buffer, "/WindowMaker");
732 if (file)
733 pclose(file);
735 gdb = WMReadPropListFromFile(buffer);
737 if (gdb) {
738 if (!WMIsPLDictionary(gdb)) {
739 WMReleasePropList(gdb);
740 gdb = NULL;
741 sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), buffer);
742 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
744 } else {
745 sprintf(mbuf, _("Could not load global Window Maker domain (%s)."), buffer);
746 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
749 if (!db) {
750 db = WMCreatePLDictionary(NULL, NULL);
752 if (!gdb) {
753 gdb = WMCreatePLDictionary(NULL, NULL);
756 GlobalDB = gdb;
758 WindowMakerDB = db;
761 WMPropList *GetObjectForKey(char *defaultName)
763 WMPropList *object = NULL;
764 WMPropList *key = WMCreatePLString(defaultName);
766 object = WMGetFromPLDictionary(WindowMakerDB, key);
767 if (!object)
768 object = WMGetFromPLDictionary(GlobalDB, key);
770 WMReleasePropList(key);
772 return object;
775 void SetObjectForKey(WMPropList * object, char *defaultName)
777 WMPropList *key = WMCreatePLString(defaultName);
779 WMPutInPLDictionary(WindowMakerDB, key, object);
780 WMReleasePropList(key);
783 void RemoveObjectForKey(char *defaultName)
785 WMPropList *key = WMCreatePLString(defaultName);
787 WMRemoveFromPLDictionary(WindowMakerDB, key);
789 WMReleasePropList(key);
792 char *GetStringForKey(char *defaultName)
794 WMPropList *val;
796 val = GetObjectForKey(defaultName);
798 if (!val)
799 return NULL;
801 if (!WMIsPLString(val))
802 return NULL;
804 return WMGetFromPLString(val);
807 WMPropList *GetArrayForKey(char *defaultName)
809 WMPropList *val;
811 val = GetObjectForKey(defaultName);
813 if (!val)
814 return NULL;
816 if (!WMIsPLArray(val))
817 return NULL;
819 return val;
822 WMPropList *GetDictionaryForKey(char *defaultName)
824 WMPropList *val;
826 val = GetObjectForKey(defaultName);
828 if (!val)
829 return NULL;
831 if (!WMIsPLDictionary(val))
832 return NULL;
834 return val;
837 int GetIntegerForKey(char *defaultName)
839 WMPropList *val;
840 char *str;
841 int value;
843 val = GetObjectForKey(defaultName);
845 if (!val)
846 return 0;
848 if (!WMIsPLString(val))
849 return 0;
851 str = WMGetFromPLString(val);
852 if (!str)
853 return 0;
855 if (sscanf(str, "%i", &value) != 1)
856 return 0;
858 return value;
861 Bool GetBoolForKey(char *defaultName)
863 int value;
864 char *str;
866 str = GetStringForKey(defaultName);
868 if (!str)
869 return False;
871 if (sscanf(str, "%i", &value) == 1 && value != 0)
872 return True;
874 if (strcasecmp(str, "YES") == 0)
875 return True;
877 if (strcasecmp(str, "Y") == 0)
878 return True;
880 return False;
883 void SetIntegerForKey(int value, char *defaultName)
885 WMPropList *object;
886 char buffer[128];
888 sprintf(buffer, "%i", value);
889 object = WMCreatePLString(buffer);
891 SetObjectForKey(object, defaultName);
892 WMReleasePropList(object);
895 void SetStringForKey(char *value, char *defaultName)
897 WMPropList *object;
899 object = WMCreatePLString(value);
901 SetObjectForKey(object, defaultName);
902 WMReleasePropList(object);
905 void SetBoolForKey(Bool value, char *defaultName)
907 static WMPropList *yes = NULL, *no = NULL;
909 if (!yes) {
910 yes = WMCreatePLString("YES");
911 no = WMCreatePLString("NO");
914 SetObjectForKey(value ? yes : no, defaultName);
917 void SetSpeedForKey(int speed, char *defaultName)
919 char *str;
921 switch (speed) {
922 case 0:
923 str = "ultraslow";
924 break;
925 case 1:
926 str = "slow";
927 break;
928 case 2:
929 str = "medium";
930 break;
931 case 3:
932 str = "fast";
933 break;
934 case 4:
935 str = "ultrafast";
936 break;
937 default:
938 str = NULL;
941 if (str)
942 SetStringForKey(str, defaultName);
945 int GetSpeedForKey(char *defaultName)
947 char *str;
948 int i;
950 str = GetStringForKey(defaultName);
951 if (!str)
952 return 2;
954 if (strcasecmp(str, "ultraslow") == 0)
955 i = 0;
956 else if (strcasecmp(str, "slow") == 0)
957 i = 1;
958 else if (strcasecmp(str, "medium") == 0)
959 i = 2;
960 else if (strcasecmp(str, "fast") == 0)
961 i = 3;
962 else if (strcasecmp(str, "ultrafast") == 0)
963 i = 4;
964 else {
965 wwarning(_("bad speed value for option %s\n. Using default Medium"), defaultName);
966 i = 2;
968 return i;