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.
27 #ifdef HAVE_STDNORETURN
28 #include <stdnoreturn.h>
32 #define MAX_SECTIONS 16
34 typedef struct _WPrefs
{
37 WMScrollView
*scrollV
;
39 WMButton
*sectionB
[MAX_SECTIONS
];
58 static _WPrefs WPrefs
;
60 /* system wide defaults dictionary. Read-only */
61 static WMPropList
*GlobalDB
= NULL
;
62 /* user defaults dictionary */
63 static WMPropList
*WindowMakerDB
= NULL
;
64 static char *WindowMakerDBPath
= NULL
;
66 static Bool TIFFOK
= False
;
68 #define INITIALIZED_PANEL (1<<0)
70 static void loadConfigurations(WMScreen
* scr
, WMWindow
* mainw
);
72 static void savePanelData(Panel
* panel
);
74 static void prepareForClose(void);
76 static noreturn
void quit(WMWidget
*w
, void *data
)
78 /* Parameter not used, but tell the compiler that it is ok */
84 WMReleaseApplication();
88 static void save(WMWidget
* w
, void *data
)
96 /* Parameter not used, but tell the compiler that it is ok */
99 /* puts("gathering data"); */
100 for (i
= 0; i
< WPrefs
.sectionCount
; i
++) {
101 PanelRec
*rec
= WMGetHangedData(WPrefs
.sectionB
[i
]);
102 if ((rec
->callbacks
.flags
& INITIALIZED_PANEL
))
103 savePanelData((Panel
*) rec
);
105 /* puts("compressing data"); */
106 /* compare the user dictionary with the global and remove redundant data */
107 keyList
= WMGetPLDictionaryKeys(GlobalDB
);
108 /* puts(WMGetPropListDescription(WindowMakerDB, False)); */
109 for (i
= 0; i
< WMGetPropListItemCount(keyList
); i
++) {
110 key
= WMGetFromPLArray(keyList
, i
);
112 /* We don't have this value anyway, so no problem.
113 * Probably a new option */
114 p1
= WMGetFromPLDictionary(WindowMakerDB
, key
);
117 /* The global doesn't have it, so no problem either. */
118 p2
= WMGetFromPLDictionary(GlobalDB
, key
);
121 /* If both values are the same, don't save. */
122 if (WMIsPropListEqualTo(p1
, p2
))
123 WMRemoveFromPLDictionary(WindowMakerDB
, key
);
125 /* puts(WMGetPropListDescription(WindowMakerDB, False)); */
126 WMReleasePropList(keyList
);
127 /* puts("storing data"); */
129 WMWritePropListToFile(WindowMakerDB
, WindowMakerDBPath
);
131 memset(&ev
, 0, sizeof(XEvent
));
133 ev
.xclient
.type
= ClientMessage
;
134 ev
.xclient
.message_type
= XInternAtom(WMScreenDisplay(WMWidgetScreen(w
)), "_WINDOWMAKER_COMMAND", False
);
135 ev
.xclient
.window
= DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w
)));
136 ev
.xclient
.format
= 8;
137 strncpy(ev
.xclient
.data
.b
, "Reconfigure", sizeof(ev
.xclient
.data
.b
));
139 XSendEvent(WMScreenDisplay(WMWidgetScreen(w
)),
140 DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w
))), False
, SubstructureRedirectMask
, &ev
);
141 XFlush(WMScreenDisplay(WMWidgetScreen(w
)));
144 static void undo(WMWidget
* w
, void *data
)
146 PanelRec
*rec
= (PanelRec
*) WPrefs
.currentPanel
;
148 /* Parameter not used, but tell the compiler that it is ok */
155 if (rec
->callbacks
.undoChanges
&& (rec
->callbacks
.flags
& INITIALIZED_PANEL
)) {
156 (*rec
->callbacks
.undoChanges
) (WPrefs
.currentPanel
);
160 static void undoAll(WMWidget
* w
, void *data
)
164 /* Parameter not used, but tell the compiler that it is ok */
168 for (i
= 0; i
< WPrefs
.sectionCount
; i
++) {
169 PanelRec
*rec
= WMGetHangedData(WPrefs
.sectionB
[i
]);
171 if (rec
->callbacks
.undoChanges
&& (rec
->callbacks
.flags
& INITIALIZED_PANEL
))
172 (*rec
->callbacks
.undoChanges
) ((Panel
*) rec
);
176 static void prepareForClose(void)
180 for (i
= 0; i
< WPrefs
.sectionCount
; i
++) {
181 PanelRec
*rec
= WMGetHangedData(WPrefs
.sectionB
[i
]);
183 if (rec
->callbacks
.prepareForClose
&& (rec
->callbacks
.flags
& INITIALIZED_PANEL
))
184 (*rec
->callbacks
.prepareForClose
) ((Panel
*) rec
);
188 static void toggleBalloons(WMWidget
*w
, void *data
)
190 WMUserDefaults
*udb
= WMGetStandardUserDefaults();
193 /* Parameter not used, but tell the compiler that it is ok */
197 flag
= WMGetButtonSelected(WPrefs
.balloonBtn
);
199 WMSetBalloonEnabled(WMWidgetScreen(WPrefs
.win
), flag
);
201 WMSetUDBoolForKey(udb
, flag
, "BalloonHelp");
204 static void createMainWindow(WMScreen
* scr
)
206 WMScroller
*scroller
;
210 WPrefs
.win
= WMCreateWindow(scr
, "wprefs");
211 WMResizeWidget(WPrefs
.win
, 520, 390);
212 WMSetWindowTitle(WPrefs
.win
, _("Window Maker Preferences"));
213 WMSetWindowCloseAction(WPrefs
.win
, quit
, NULL
);
214 WMSetWindowMaxSize(WPrefs
.win
, 520, 390);
215 WMSetWindowMinSize(WPrefs
.win
, 520, 390);
216 WMSetWindowMiniwindowTitle(WPrefs
.win
, _("Preferences"));
218 WPrefs
.scrollV
= WMCreateScrollView(WPrefs
.win
);
219 WMResizeWidget(WPrefs
.scrollV
, 500, 87);
220 WMMoveWidget(WPrefs
.scrollV
, 10, 10);
221 WMSetScrollViewRelief(WPrefs
.scrollV
, WRSunken
);
222 WMSetScrollViewHasHorizontalScroller(WPrefs
.scrollV
, True
);
223 WMSetScrollViewHasVerticalScroller(WPrefs
.scrollV
, False
);
224 scroller
= WMGetScrollViewHorizontalScroller(WPrefs
.scrollV
);
225 WMSetScrollerArrowsPosition(scroller
, WSANone
);
227 WPrefs
.buttonF
= WMCreateFrame(WPrefs
.win
);
228 WMSetFrameRelief(WPrefs
.buttonF
, WRFlat
);
230 WMSetScrollViewContentView(WPrefs
.scrollV
, WMWidgetView(WPrefs
.buttonF
));
232 WPrefs
.undosBtn
= WMCreateCommandButton(WPrefs
.win
);
233 WMResizeWidget(WPrefs
.undosBtn
, 90, 28);
234 WMMoveWidget(WPrefs
.undosBtn
, 135, 350);
235 WMSetButtonText(WPrefs
.undosBtn
, _("Revert Page"));
236 WMSetButtonAction(WPrefs
.undosBtn
, undo
, NULL
);
238 WPrefs
.undoBtn
= WMCreateCommandButton(WPrefs
.win
);
239 WMResizeWidget(WPrefs
.undoBtn
, 90, 28);
240 WMMoveWidget(WPrefs
.undoBtn
, 235, 350);
241 WMSetButtonText(WPrefs
.undoBtn
, _("Revert All"));
242 WMSetButtonAction(WPrefs
.undoBtn
, undoAll
, NULL
);
244 WPrefs
.saveBtn
= WMCreateCommandButton(WPrefs
.win
);
245 WMResizeWidget(WPrefs
.saveBtn
, 80, 28);
246 WMMoveWidget(WPrefs
.saveBtn
, 335, 350);
247 WMSetButtonText(WPrefs
.saveBtn
, _("Save"));
248 WMSetButtonAction(WPrefs
.saveBtn
, save
, NULL
);
250 WPrefs
.closeBtn
= WMCreateCommandButton(WPrefs
.win
);
251 WMResizeWidget(WPrefs
.closeBtn
, 80, 28);
252 WMMoveWidget(WPrefs
.closeBtn
, 425, 350);
253 WMSetButtonText(WPrefs
.closeBtn
, _("Close"));
254 WMSetButtonAction(WPrefs
.closeBtn
, quit
, NULL
);
256 WPrefs
.balloonBtn
= WMCreateSwitchButton(WPrefs
.win
);
257 WMResizeWidget(WPrefs
.balloonBtn
, 200, 28);
258 WMMoveWidget(WPrefs
.balloonBtn
, 15, 350);
259 WMSetButtonText(WPrefs
.balloonBtn
, _("Balloon Help"));
260 WMSetButtonAction(WPrefs
.balloonBtn
, toggleBalloons
, NULL
);
262 WMUserDefaults
*udb
= WMGetStandardUserDefaults();
263 Bool flag
= WMGetUDBoolForKey(udb
, "BalloonHelp");
265 WMSetButtonSelected(WPrefs
.balloonBtn
, flag
);
266 WMSetBalloonEnabled(scr
, flag
);
270 WPrefs
.banner
= WMCreateFrame(WPrefs
.win
);
271 WMResizeWidget(WPrefs
.banner
, FRAME_WIDTH
, FRAME_HEIGHT
);
272 WMMoveWidget(WPrefs
.banner
, FRAME_LEFT
, FRAME_TOP
);
273 WMSetFrameRelief(WPrefs
.banner
, WRFlat
);
275 font
= WMCreateFont(scr
, "Lucida Sans,URW Gothic L,Times New Roman,serif"
276 ":bold:pixelsize=26:antialias=true");
277 WPrefs
.nameL
= WMCreateLabel(WPrefs
.banner
);
278 WMSetLabelTextAlignment(WPrefs
.nameL
, WACenter
);
279 WMResizeWidget(WPrefs
.nameL
, FRAME_WIDTH
- 20, 60);
280 WMMoveWidget(WPrefs
.nameL
, 10, 50);
281 WMSetLabelFont(WPrefs
.nameL
, font
);
282 WMSetLabelText(WPrefs
.nameL
, _("Window Maker Preferences"));
285 WPrefs
.versionL
= WMCreateLabel(WPrefs
.banner
);
286 WMResizeWidget(WPrefs
.versionL
, FRAME_WIDTH
- 20, 20);
287 WMMoveWidget(WPrefs
.versionL
, 10, 120);
288 WMSetLabelTextAlignment(WPrefs
.versionL
, WACenter
);
289 sprintf(buffer
, _("Version %s"), VERSION
);
290 WMSetLabelText(WPrefs
.versionL
, buffer
);
292 WPrefs
.statusL
= WMCreateLabel(WPrefs
.banner
);
293 WMResizeWidget(WPrefs
.statusL
, FRAME_WIDTH
- 20, 60);
294 WMMoveWidget(WPrefs
.statusL
, 10, 150);
295 WMSetLabelTextAlignment(WPrefs
.statusL
, WACenter
);
296 WMSetLabelText(WPrefs
.statusL
, _("Starting..."));
298 WMMapSubwidgets(WPrefs
.win
);
300 WMUnmapWidget(WPrefs
.undosBtn
);
301 WMUnmapWidget(WPrefs
.undoBtn
);
302 WMUnmapWidget(WPrefs
.saveBtn
);
305 static void showPanel(Panel
* panel
)
307 PanelRec
*rec
= (PanelRec
*) panel
;
309 if (!(rec
->callbacks
.flags
& INITIALIZED_PANEL
)) {
310 (*rec
->callbacks
.createWidgets
) (panel
);
311 rec
->callbacks
.flags
|= INITIALIZED_PANEL
;
314 WMSetWindowTitle(WPrefs
.win
, rec
->sectionName
);
316 if (rec
->callbacks
.showPanel
)
317 (*rec
->callbacks
.showPanel
) (panel
);
319 WMMapWidget(rec
->box
);
322 static void hidePanel(Panel
* panel
)
324 PanelRec
*rec
= (PanelRec
*) panel
;
326 WMUnmapWidget(rec
->box
);
328 if (rec
->callbacks
.hidePanel
)
329 (*rec
->callbacks
.hidePanel
) (panel
);
332 static void savePanelData(Panel
* panel
)
334 PanelRec
*rec
= (PanelRec
*) panel
;
336 if (rec
->callbacks
.updateDomain
) {
337 (*rec
->callbacks
.updateDomain
) (panel
);
341 static void changeSection(WMWidget
* self
, void *data
)
343 /* Parameter not used, but tell the compiler that it is ok */
346 if (WPrefs
.currentPanel
== data
)
349 if (WPrefs
.currentPanel
== NULL
) {
350 WMDestroyWidget(WPrefs
.nameL
);
351 WMDestroyWidget(WPrefs
.versionL
);
352 WMDestroyWidget(WPrefs
.statusL
);
354 WMSetFrameRelief(WPrefs
.banner
, WRGroove
);
356 /* WMMapWidget(WPrefs.undosBtn);
357 WMMapWidget(WPrefs.undoBtn);
359 WMMapWidget(WPrefs
.saveBtn
);
364 if (WPrefs
.currentPanel
)
365 hidePanel(WPrefs
.currentPanel
);
366 WPrefs
.currentPanel
= data
;
369 char *LocateImage(const char *name
)
372 char *tmp
= wmalloc(strlen(name
) + 8);
375 sprintf(tmp
, "%s.tiff", name
);
376 path
= WMPathForResourceOfType(tmp
, "tiff");
378 sprintf(tmp
, "%s.xpm", name
);
379 path
= WMPathForResourceOfType(tmp
, "xpm");
383 wwarning(_("could not locate image file %s"), name
);
389 void CreateImages(WMScreen
*scr
, RContext
*rc
, RImage
*xis
, const char *file
,
390 WMPixmap
**icon_normal
, WMPixmap
**icon_greyed
)
394 RColor gray
= { 0xae, 0xaa, 0xae, 0 };
396 path
= LocateImage(file
);
405 *icon_normal
= WMCreatePixmapFromFile(scr
, path
);
408 wwarning(_("could not load icon %s"), path
);
415 if (!icon_greyed
) // Greyed-out version not requested, we are done
421 icon
= RLoadImage(rc
, path
, 0);
424 wwarning(_("could not load icon %s"), path
);
429 RCombineImageWithColor(icon
, &gray
);
432 RCombineImagesWithOpaqueness(icon
, xis
, 180);
434 *icon_greyed
= WMCreatePixmapFromRImage(scr
, icon
, 127);
437 wwarning(_("could not process icon %s: %s"), path
, RMessageForError(RErrorCode
));
444 void SetButtonAlphaImage(WMScreen
*scr
, WMButton
*bPtr
, const char *file
)
450 iconPath
= LocateImage(file
);
457 icon
= WMCreateBlendedPixmapFromFile(scr
, iconPath
, &color
);
459 wwarning(_("could not load icon file %s"), iconPath
);
464 WMSetButtonImage(bPtr
, icon
);
471 icon
= WMCreateBlendedPixmapFromFile(scr
, iconPath
, &color
);
473 wwarning(_("could not load icon file %s"), iconPath
);
478 WMSetButtonAltImage(bPtr
, icon
);
481 WMReleasePixmap(icon
);
487 void AddSection(Panel
* panel
, const char *iconFile
)
491 assert(WPrefs
.sectionCount
< MAX_SECTIONS
);
493 bPtr
= WMCreateCustomButton(WPrefs
.buttonF
, WBBStateLightMask
| WBBStateChangeMask
);
494 WMResizeWidget(bPtr
, 64, 64);
495 WMMoveWidget(bPtr
, WPrefs
.sectionCount
* 64, 0);
496 WMSetButtonImagePosition(bPtr
, WIPImageOnly
);
497 WMSetButtonAction(bPtr
, changeSection
, panel
);
498 WMHangData(bPtr
, panel
);
500 WMSetBalloonTextForView(((PanelRec
*) panel
)->description
, WMWidgetView(bPtr
));
501 SetButtonAlphaImage(WMWidgetScreen(bPtr
), bPtr
, iconFile
);
504 WPrefs
.sectionB
[WPrefs
.sectionCount
] = bPtr
;
506 if (WPrefs
.sectionCount
> 0)
507 WMGroupButtons(WPrefs
.sectionB
[0], bPtr
);
509 WPrefs
.sectionCount
++;
511 WMResizeWidget(WPrefs
.buttonF
, WPrefs
.sectionCount
* 64, 64);
514 void Initialize(WMScreen
* scr
)
520 list
= RSupportedFileFormats();
521 for (i
= 0; list
[i
] != NULL
; i
++) {
522 if (strcmp(list
[i
], "TIFF") == 0) {
529 path
= WMPathForResourceOfType("WPrefs.tiff", NULL
);
531 path
= WMPathForResourceOfType("WPrefs.xpm", NULL
);
535 tmp
= RLoadImage(WMScreenRContext(scr
), path
, 0);
537 wwarning(_("could not load image file %s:%s"), path
, RMessageForError(RErrorCode
));
539 WMSetApplicationIconImage(scr
, tmp
);
545 memset(&WPrefs
, 0, sizeof(_WPrefs
));
546 createMainWindow(scr
);
548 WMRealizeWidget(WPrefs
.win
);
550 WMSetWindowMiniwindowImage(WPrefs
.win
, WMGetApplicationIconImage(scr
));
552 WMMapWidget(WPrefs
.win
);
553 XFlush(WMScreenDisplay(scr
));
554 WMSetLabelText(WPrefs
.statusL
, _("Loading Window Maker configuration files..."));
555 XFlush(WMScreenDisplay(scr
));
556 loadConfigurations(scr
, WPrefs
.win
);
558 WMSetLabelText(WPrefs
.statusL
, _("Initializing configuration panels..."));
560 InitFocus(WPrefs
.banner
);
561 InitWindowHandling(WPrefs
.banner
);
563 InitMenuPreferences(WPrefs
.banner
);
564 InitIcons(WPrefs
.banner
);
565 InitPreferences(WPrefs
.banner
);
567 InitPaths(WPrefs
.banner
);
568 InitDocks(WPrefs
.banner
);
569 InitWorkspace(WPrefs
.banner
);
570 InitConfigurations(WPrefs
.banner
);
572 InitMenu(WPrefs
.banner
);
574 #ifdef not_yet_fully_implemented
575 InitKeyboardSettings(WPrefs
.banner
);
577 InitKeyboardShortcuts(WPrefs
.banner
);
578 InitHotCornerShortcuts(WPrefs
.banner
);
579 InitMouseSettings(WPrefs
.banner
);
581 InitAppearance(WPrefs
.banner
);
583 InitFontSimple(WPrefs
.banner
);
585 #ifdef not_yet_fully_implemented
586 InitThemes(WPrefs
.banner
);
588 InitExpert(WPrefs
.banner
);
590 WMRealizeWidget(WPrefs
.scrollV
);
592 WMSetLabelText(WPrefs
.statusL
, "");
595 WMWindow
*GetWindow(void)
600 static void loadConfigurations(WMScreen
* scr
, WMWindow
* mainw
)
602 WMPropList
*db
, *gdb
;
606 char mbuf
[1069]; /* Size of buffer and extra characters for the sprintfs */
609 path
= wdefaultspathfordomain("WindowMaker");
610 WindowMakerDBPath
= path
;
612 db
= WMReadPropListFromFile(path
);
614 if (!WMIsPLDictionary(db
)) {
615 WMReleasePropList(db
);
617 sprintf(mbuf
, _("Window Maker domain (%s) is corrupted!"), path
);
618 WMRunAlertPanel(scr
, mainw
, _("Error"), mbuf
, _("OK"), NULL
, NULL
);
621 sprintf(mbuf
, _("Could not load Window Maker domain (%s) from defaults database."), path
);
622 WMRunAlertPanel(scr
, mainw
, _("Error"), mbuf
, _("OK"), NULL
, NULL
);
625 path
= getenv("WMAKER_BIN_NAME");
631 command
= wstrconcat(path
, " --version");
632 file
= popen(command
, "r");
635 if (!file
|| !fgets(buffer
, 1023, file
)) {
636 werror(_("could not extract version information from Window Maker"));
637 wfatal(_("Make sure wmaker is in your search path."));
639 WMRunAlertPanel(scr
, mainw
, _("Error"),
641 ("Could not extract version from Window Maker. Make sure it is correctly installed and is in your PATH environment variable."),
642 _("OK"), NULL
, NULL
);
648 if (sscanf(buffer
, "Window Maker %i.%i.%i", &v1
, &v2
, &v3
) != 3
649 && sscanf(buffer
, "WindowMaker %i.%i.%i", &v1
, &v2
, &v3
) != 3) {
650 WMRunAlertPanel(scr
, mainw
, _("Error"),
651 _("Could not extract version from Window Maker. "
652 "Make sure it is correctly installed and the path "
653 "where it installed is in the PATH environment "
654 "variable."), _("OK"), NULL
, NULL
);
657 if (v1
== 0 && (v2
< 18 || v3
< 0)) {
658 sprintf(mbuf
, _("WPrefs only supports Window Maker 0.18.0 or newer.\n"
659 "The version installed is %i.%i.%i\n"), v1
, v2
, v3
);
660 WMRunAlertPanel(scr
, mainw
, _("Error"), mbuf
, _("OK"), NULL
, NULL
);
664 if (v1
> 1 || (v1
== 1 && (v2
> 0))) {
667 ("Window Maker %i.%i.%i, which is installed in your system, is not fully supported by this version of WPrefs."),
669 WMRunAlertPanel(scr
, mainw
, _("Warning"), mbuf
, _("OK"), NULL
, NULL
);
675 command
= wstrconcat(path
, " --global_defaults_path");
676 file
= popen(command
, "r");
679 if (!file
|| !fgets(buffer
, 1023, file
)) {
680 werror(_("could not run \"%s --global_defaults_path\"."), path
);
684 ptr
= strchr(buffer
, '\n');
687 strcat(buffer
, "/WindowMaker");
693 gdb
= WMReadPropListFromFile(buffer
);
696 if (!WMIsPLDictionary(gdb
)) {
697 WMReleasePropList(gdb
);
699 sprintf(mbuf
, _("Window Maker domain (%s) is corrupted!"), buffer
);
700 WMRunAlertPanel(scr
, mainw
, _("Error"), mbuf
, _("OK"), NULL
, NULL
);
703 sprintf(mbuf
, _("Could not load global Window Maker domain (%s)."), buffer
);
704 WMRunAlertPanel(scr
, mainw
, _("Error"), mbuf
, _("OK"), NULL
, NULL
);
708 db
= WMCreatePLDictionary(NULL
, NULL
);
711 gdb
= WMCreatePLDictionary(NULL
, NULL
);
719 WMPropList
*GetObjectForKey(const char *defaultName
)
721 WMPropList
*object
= NULL
;
722 WMPropList
*key
= WMCreatePLString(defaultName
);
724 object
= WMGetFromPLDictionary(WindowMakerDB
, key
);
726 object
= WMGetFromPLDictionary(GlobalDB
, key
);
728 WMReleasePropList(key
);
733 void SetObjectForKey(WMPropList
* object
, const char *defaultName
)
735 WMPropList
*key
= WMCreatePLString(defaultName
);
737 WMPutInPLDictionary(WindowMakerDB
, key
, object
);
738 WMReleasePropList(key
);
741 void RemoveObjectForKey(const char *defaultName
)
743 WMPropList
*key
= WMCreatePLString(defaultName
);
745 WMRemoveFromPLDictionary(WindowMakerDB
, key
);
747 WMReleasePropList(key
);
750 char *GetStringForKey(const char *defaultName
)
754 val
= GetObjectForKey(defaultName
);
759 if (!WMIsPLString(val
))
762 return WMGetFromPLString(val
);
765 WMPropList
*GetArrayForKey(const char *defaultName
)
769 val
= GetObjectForKey(defaultName
);
774 if (!WMIsPLArray(val
))
780 WMPropList
*GetDictionaryForKey(const char *defaultName
)
784 val
= GetObjectForKey(defaultName
);
789 if (!WMIsPLDictionary(val
))
795 int GetIntegerForKey(const char *defaultName
)
801 val
= GetObjectForKey(defaultName
);
806 if (!WMIsPLString(val
))
809 str
= WMGetFromPLString(val
);
813 if (sscanf(str
, "%i", &value
) != 1)
819 Bool
GetBoolForKey(const char *defaultName
)
824 str
= GetStringForKey(defaultName
);
829 if (sscanf(str
, "%i", &value
) == 1 && value
!= 0)
832 if (strcasecmp(str
, "YES") == 0)
835 if (strcasecmp(str
, "Y") == 0)
841 void SetIntegerForKey(int value
, const char *defaultName
)
846 sprintf(buffer
, "%i", value
);
847 object
= WMCreatePLString(buffer
);
849 SetObjectForKey(object
, defaultName
);
850 WMReleasePropList(object
);
853 void SetStringForKey(const char *value
, const char *defaultName
)
857 object
= WMCreatePLString(value
);
859 SetObjectForKey(object
, defaultName
);
860 WMReleasePropList(object
);
863 void SetBoolForKey(Bool value
, const char *defaultName
)
865 static WMPropList
*yes
= NULL
, *no
= NULL
;
868 yes
= WMCreatePLString("YES");
869 no
= WMCreatePLString("NO");
872 SetObjectForKey(value
? yes
: no
, defaultName
);
875 void SetSpeedForKey(int speed
, const char *defaultName
)
900 SetStringForKey(str
, defaultName
);
903 int GetSpeedForKey(const char *defaultName
)
908 str
= GetStringForKey(defaultName
);
912 if (strcasecmp(str
, "ultraslow") == 0)
914 else if (strcasecmp(str
, "slow") == 0)
916 else if (strcasecmp(str
, "medium") == 0)
918 else if (strcasecmp(str
, "fast") == 0)
920 else if (strcasecmp(str
, "ultrafast") == 0)
923 wwarning(_("bad speed value for option %s; using default Medium"), defaultName
);