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.
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
{
68 WMScrollView
*scrollV
;
70 WMButton
*sectionB
[MAX_SECTIONS
];
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();
107 void quit(WMWidget
* w
, void *data
)
114 static void save(WMWidget
* w
, void *data
)
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
);
140 /* The global doesn't have it, so no problem either. */
141 p2
= WMGetFromPLDictionary(GlobalDB
, key
);
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
;
174 if (rec
->callbacks
.undoChanges
&& (rec
->callbacks
.flags
& INITIALIZED_PANEL
)) {
175 (*rec
->callbacks
.undoChanges
) (WPrefs
.currentPanel
);
179 static void undoAll(WMWidget
* w
, void *data
)
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()
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();
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
;
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
);
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"));
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
)
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
);
372 if (WPrefs
.currentPanel
)
373 hidePanel(WPrefs
.currentPanel
);
374 WPrefs
.currentPanel
= data
;
377 char *LocateImage(char *name
)
380 char *tmp
= wmalloc(strlen(name
) + 8);
383 sprintf(tmp
, "%s.tiff", name
);
384 path
= WMPathForResourceOfType(tmp
, "tiff");
386 sprintf(tmp
, "%s.xpm", name
);
387 path
= WMPathForResourceOfType(tmp
, "xpm");
391 wwarning(_("could not locate image file %s"), name
);
397 void CreateImages(WMScreen
*scr
, RContext
*rc
, RImage
*xis
, char *file
,
398 WMPixmap
**icon_normal
, WMPixmap
**icon_greyed
)
402 RColor gray
= { 0xae, 0xaa, 0xae, 0 };
404 path
= LocateImage(file
);
413 *icon_normal
= WMCreatePixmapFromFile(scr
, path
);
416 wwarning(_("could not load icon %s"), path
);
423 if (!icon_greyed
) // Greyed-out version not requested, we are done
429 icon
= RLoadImage(rc
, path
, 0);
432 wwarning(_("could not load icon %s"), path
);
437 RCombineImageWithColor(icon
, &gray
);
440 RCombineImagesWithOpaqueness(icon
, xis
, 180);
442 *icon_greyed
= WMCreatePixmapFromRImage(scr
, icon
, 127);
445 wwarning(_("could not process icon %s: %s"), path
, RMessageForError(RErrorCode
));
452 static WMPixmap
*makeTitledIcon(WMScreen
* scr
, WMPixmap
* icon
, char *title1
, char *title2
)
454 return WMRetainPixmap(icon
);
458 static XFontStruct
*hfont
= NULL
;
459 static XFontStruct
*vfont
= NULL
;
462 Display
*dpy
= WMScreenDisplay(scr
);
463 WMColor
*black
= WMBlackColor(scr
);
465 WMSize size
= WMGetPixmapSize(icon
);
467 tmp
= WMCreatePixmap(scr
, 60, 60, WMScreenDepth(scr
), True
);
469 pix
= WMGetPixmapXID(tmp
);
470 mask
= WMGetPixmapMaskXID(tmp
);
473 gc
= XCreateGC(dpy
, mask
, 0, NULL
);
475 hfont
= XLoadQueryFont(dpy
, ICON_TITLE_FONT
);
476 vfont
= XLoadQueryFont(dpy
, ICON_TITLE_VFONT
);
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);
495 XFillRectangle(dpy
, mask
, gc
, 12, 12, 48, 48);
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
));
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
));
519 void SetButtonAlphaImage(WMScreen
* scr
, WMButton
* bPtr
, char *file
, char *title1
, char *title2
)
526 iconPath
= LocateImage(file
);
533 icon
= WMCreateBlendedPixmapFromFile(scr
, iconPath
, &color
);
535 wwarning(_("could not load icon file %s"), iconPath
);
541 icon2
= makeTitledIcon(scr
, icon
, title1
, title2
);
543 WMReleasePixmap(icon
);
548 WMSetButtonImage(bPtr
, icon2
);
551 WMReleasePixmap(icon2
);
558 icon
= WMCreateBlendedPixmapFromFile(scr
, iconPath
, &color
);
560 wwarning(_("could not load icon file %s"), iconPath
);
565 WMSetButtonAltImage(bPtr
, icon
);
568 WMReleasePixmap(icon
);
574 void AddSection(Panel
* panel
, char *iconFile
)
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
));
592 t1
= wstrdup(((PanelRec
*) panel
)->sectionName
);
593 t2
= strchr(t1
, ' ');
598 SetButtonAlphaImage(WMWidgetScreen(bPtr
), bPtr
, iconFile
, t1
, t2
);
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
)
620 list
= RSupportedFileFormats();
621 for (i
= 0; list
[i
] != NULL
; i
++) {
622 if (strcmp(list
[i
], "TIFF") == 0) {
629 path
= WMPathForResourceOfType("WPrefs.tiff", NULL
);
631 path
= WMPathForResourceOfType("WPrefs.xpm", NULL
);
635 tmp
= RLoadImage(WMScreenRContext(scr
), path
, 0);
637 wwarning(_("could not load image file %s:%s"), path
, RMessageForError(RErrorCode
));
639 WMSetApplicationIconImage(scr
, tmp
);
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
);
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
);
687 InitExpert(scr
, WPrefs
.banner
);
689 WMRealizeWidget(WPrefs
.scrollV
);
691 WMSetLabelText(WPrefs
.statusL
, "");
694 WMWindow
*GetWindow(Panel
* panel
)
699 static void loadConfigurations(WMScreen
* scr
, WMWindow
* mainw
)
701 WMPropList
*db
, *gdb
;
708 path
= wdefaultspathfordomain("WindowMaker");
709 WindowMakerDBPath
= path
;
711 db
= WMReadPropListFromFile(path
);
713 if (!WMIsPLDictionary(db
)) {
714 WMReleasePropList(db
);
716 sprintf(mbuf
, _("Window Maker domain (%s) is corrupted!"), path
);
717 WMRunAlertPanel(scr
, mainw
, _("Error"), mbuf
, _("OK"), NULL
, NULL
);
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");
730 command
= wstrconcat(path
, " --version");
731 file
= popen(command
, "r");
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
);
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
);
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
);
763 if (v1
> 1 || (v1
== 1 && (v2
> 0))) {
766 ("Window Maker %i.%i.%i, which is installed in your system, is not fully supported by this version of WPrefs."),
768 WMRunAlertPanel(scr
, mainw
, _("Warning"), mbuf
, _("OK"), NULL
, NULL
);
774 command
= wstrconcat(path
, " --global_defaults_path");
775 file
= popen(command
, "r");
778 if (!file
|| !fgets(buffer
, 1023, file
)) {
779 werror(_("could not run \"%s --global_defaults_path\"."), path
);
783 ptr
= strchr(buffer
, '\n');
786 strcat(buffer
, "/WindowMaker");
792 gdb
= WMReadPropListFromFile(buffer
);
795 if (!WMIsPLDictionary(gdb
)) {
796 WMReleasePropList(gdb
);
798 sprintf(mbuf
, _("Window Maker domain (%s) is corrupted!"), buffer
);
799 WMRunAlertPanel(scr
, mainw
, _("Error"), mbuf
, _("OK"), NULL
, NULL
);
802 sprintf(mbuf
, _("Could not load global Window Maker domain (%s)."), buffer
);
803 WMRunAlertPanel(scr
, mainw
, _("Error"), mbuf
, _("OK"), NULL
, NULL
);
807 db
= WMCreatePLDictionary(NULL
, NULL
);
810 gdb
= WMCreatePLDictionary(NULL
, NULL
);
818 WMPropList
*GetObjectForKey(char *defaultName
)
820 WMPropList
*object
= NULL
;
821 WMPropList
*key
= WMCreatePLString(defaultName
);
823 object
= WMGetFromPLDictionary(WindowMakerDB
, key
);
825 object
= WMGetFromPLDictionary(GlobalDB
, key
);
827 WMReleasePropList(key
);
832 void SetObjectForKey(WMPropList
* object
, char *defaultName
)
834 WMPropList
*key
= WMCreatePLString(defaultName
);
836 WMPutInPLDictionary(WindowMakerDB
, key
, object
);
837 WMReleasePropList(key
);
840 void RemoveObjectForKey(char *defaultName
)
842 WMPropList
*key
= WMCreatePLString(defaultName
);
844 WMRemoveFromPLDictionary(WindowMakerDB
, key
);
846 WMReleasePropList(key
);
849 char *GetStringForKey(char *defaultName
)
853 val
= GetObjectForKey(defaultName
);
858 if (!WMIsPLString(val
))
861 return WMGetFromPLString(val
);
864 WMPropList
*GetArrayForKey(char *defaultName
)
868 val
= GetObjectForKey(defaultName
);
873 if (!WMIsPLArray(val
))
879 WMPropList
*GetDictionaryForKey(char *defaultName
)
883 val
= GetObjectForKey(defaultName
);
888 if (!WMIsPLDictionary(val
))
894 int GetIntegerForKey(char *defaultName
)
900 val
= GetObjectForKey(defaultName
);
905 if (!WMIsPLString(val
))
908 str
= WMGetFromPLString(val
);
912 if (sscanf(str
, "%i", &value
) != 1)
918 Bool
GetBoolForKey(char *defaultName
)
923 str
= GetStringForKey(defaultName
);
928 if (sscanf(str
, "%i", &value
) == 1 && value
!= 0)
931 if (strcasecmp(str
, "YES") == 0)
934 if (strcasecmp(str
, "Y") == 0)
940 void SetIntegerForKey(int value
, char *defaultName
)
945 sprintf(buffer
, "%i", value
);
946 object
= WMCreatePLString(buffer
);
948 SetObjectForKey(object
, defaultName
);
949 WMReleasePropList(object
);
952 void SetStringForKey(char *value
, char *defaultName
)
956 object
= WMCreatePLString(value
);
958 SetObjectForKey(object
, defaultName
);
959 WMReleasePropList(object
);
962 void SetBoolForKey(Bool value
, char *defaultName
)
964 static WMPropList
*yes
= NULL
, *no
= NULL
;
967 yes
= WMCreatePLString("YES");
968 no
= WMCreatePLString("NO");
971 SetObjectForKey(value
? yes
: no
, defaultName
);
974 void SetSpeedForKey(int speed
, char *defaultName
)
999 SetStringForKey(str
, defaultName
);
1002 int GetSpeedForKey(char *defaultName
)
1007 str
= GetStringForKey(defaultName
);
1011 if (strcasecmp(str
, "ultraslow") == 0)
1013 else if (strcasecmp(str
, "slow") == 0)
1015 else if (strcasecmp(str
, "medium") == 0)
1017 else if (strcasecmp(str
, "fast") == 0)
1019 else if (strcasecmp(str
, "ultrafast") == 0)
1022 wwarning(_("bad speed value for option %s; using default Medium"), defaultName
);