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.
26 #define ICON_TITLE_FONT "sans serif:pixelsize=9"
27 #define ICON_TITLE_VFONT "sans serif:pixelsize=9:weight=100"
29 #define MAX_SECTIONS 16
31 typedef struct _WPrefs
{
34 WMScrollView
*scrollV
;
36 WMButton
*sectionB
[MAX_SECTIONS
];
55 static _WPrefs WPrefs
;
57 /* system wide defaults dictionary. Read-only */
58 static WMPropList
*GlobalDB
= NULL
;
59 /* user defaults dictionary */
60 static WMPropList
*WindowMakerDB
= NULL
;
61 static char *WindowMakerDBPath
= NULL
;
63 static Bool TIFFOK
= False
;
65 #define INITIALIZED_PANEL (1<<0)
67 static void loadConfigurations(WMScreen
* scr
, WMWindow
* mainw
);
69 static void savePanelData(Panel
* panel
);
71 static void prepareForClose(void);
73 static void quit(WMWidget
*w
, void *data
)
75 /* Parameter not used, but tell the compiler that it is ok */
84 static void save(WMWidget
* w
, void *data
)
92 /* Parameter not used, but tell the compiler that it is ok */
95 /* puts("gathering data"); */
96 for (i
= 0; i
< WPrefs
.sectionCount
; i
++) {
97 PanelRec
*rec
= WMGetHangedData(WPrefs
.sectionB
[i
]);
98 if ((rec
->callbacks
.flags
& INITIALIZED_PANEL
))
99 savePanelData((Panel
*) rec
);
101 /* puts("compressing data"); */
102 /* compare the user dictionary with the global and remove redundant data */
103 keyList
= WMGetPLDictionaryKeys(GlobalDB
);
104 /* puts(WMGetPropListDescription(WindowMakerDB, False)); */
105 for (i
= 0; i
< WMGetPropListItemCount(keyList
); i
++) {
106 key
= WMGetFromPLArray(keyList
, i
);
108 /* We don't have this value anyway, so no problem.
109 * Probably a new option */
110 p1
= WMGetFromPLDictionary(WindowMakerDB
, key
);
113 /* The global doesn't have it, so no problem either. */
114 p2
= WMGetFromPLDictionary(GlobalDB
, key
);
117 /* If both values are the same, don't save. */
118 if (WMIsPropListEqualTo(p1
, p2
))
119 WMRemoveFromPLDictionary(WindowMakerDB
, key
);
121 /* puts(WMGetPropListDescription(WindowMakerDB, False)); */
122 WMReleasePropList(keyList
);
123 /* puts("storing data"); */
125 WMWritePropListToFile(WindowMakerDB
, WindowMakerDBPath
);
127 memset(&ev
, 0, sizeof(XEvent
));
129 ev
.xclient
.type
= ClientMessage
;
130 ev
.xclient
.message_type
= XInternAtom(WMScreenDisplay(WMWidgetScreen(w
)), "_WINDOWMAKER_COMMAND", False
);
131 ev
.xclient
.window
= DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w
)));
132 ev
.xclient
.format
= 8;
133 strncpy(ev
.xclient
.data
.b
, "Reconfigure", sizeof(ev
.xclient
.data
.b
));
135 XSendEvent(WMScreenDisplay(WMWidgetScreen(w
)),
136 DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w
))), False
, SubstructureRedirectMask
, &ev
);
137 XFlush(WMScreenDisplay(WMWidgetScreen(w
)));
140 static void undo(WMWidget
* w
, void *data
)
142 PanelRec
*rec
= (PanelRec
*) WPrefs
.currentPanel
;
144 /* Parameter not used, but tell the compiler that it is ok */
151 if (rec
->callbacks
.undoChanges
&& (rec
->callbacks
.flags
& INITIALIZED_PANEL
)) {
152 (*rec
->callbacks
.undoChanges
) (WPrefs
.currentPanel
);
156 static void undoAll(WMWidget
* w
, void *data
)
160 /* Parameter not used, but tell the compiler that it is ok */
164 for (i
= 0; i
< WPrefs
.sectionCount
; i
++) {
165 PanelRec
*rec
= WMGetHangedData(WPrefs
.sectionB
[i
]);
167 if (rec
->callbacks
.undoChanges
&& (rec
->callbacks
.flags
& INITIALIZED_PANEL
))
168 (*rec
->callbacks
.undoChanges
) ((Panel
*) rec
);
172 static void prepareForClose(void)
176 for (i
= 0; i
< WPrefs
.sectionCount
; i
++) {
177 PanelRec
*rec
= WMGetHangedData(WPrefs
.sectionB
[i
]);
179 if (rec
->callbacks
.prepareForClose
&& (rec
->callbacks
.flags
& INITIALIZED_PANEL
))
180 (*rec
->callbacks
.prepareForClose
) ((Panel
*) rec
);
184 static void toggleBalloons(WMWidget
*w
, void *data
)
186 WMUserDefaults
*udb
= WMGetStandardUserDefaults();
189 /* Parameter not used, but tell the compiler that it is ok */
193 flag
= WMGetButtonSelected(WPrefs
.balloonBtn
);
195 WMSetBalloonEnabled(WMWidgetScreen(WPrefs
.win
), flag
);
197 WMSetUDBoolForKey(udb
, flag
, "BalloonHelp");
200 static void createMainWindow(WMScreen
* scr
)
202 WMScroller
*scroller
;
206 WPrefs
.win
= WMCreateWindow(scr
, "wprefs");
207 WMResizeWidget(WPrefs
.win
, 520, 390);
208 WMSetWindowTitle(WPrefs
.win
, _("Window Maker Preferences"));
209 WMSetWindowCloseAction(WPrefs
.win
, quit
, NULL
);
210 WMSetWindowMaxSize(WPrefs
.win
, 520, 390);
211 WMSetWindowMinSize(WPrefs
.win
, 520, 390);
212 WMSetWindowMiniwindowTitle(WPrefs
.win
, "Preferences");
214 WPrefs
.scrollV
= WMCreateScrollView(WPrefs
.win
);
215 WMResizeWidget(WPrefs
.scrollV
, 500, 87);
216 WMMoveWidget(WPrefs
.scrollV
, 10, 10);
217 WMSetScrollViewRelief(WPrefs
.scrollV
, WRSunken
);
218 WMSetScrollViewHasHorizontalScroller(WPrefs
.scrollV
, True
);
219 WMSetScrollViewHasVerticalScroller(WPrefs
.scrollV
, False
);
220 scroller
= WMGetScrollViewHorizontalScroller(WPrefs
.scrollV
);
221 WMSetScrollerArrowsPosition(scroller
, WSANone
);
223 WPrefs
.buttonF
= WMCreateFrame(WPrefs
.win
);
224 WMSetFrameRelief(WPrefs
.buttonF
, WRFlat
);
226 WMSetScrollViewContentView(WPrefs
.scrollV
, WMWidgetView(WPrefs
.buttonF
));
228 WPrefs
.undosBtn
= WMCreateCommandButton(WPrefs
.win
);
229 WMResizeWidget(WPrefs
.undosBtn
, 90, 28);
230 WMMoveWidget(WPrefs
.undosBtn
, 135, 350);
231 WMSetButtonText(WPrefs
.undosBtn
, _("Revert Page"));
232 WMSetButtonAction(WPrefs
.undosBtn
, undo
, NULL
);
234 WPrefs
.undoBtn
= WMCreateCommandButton(WPrefs
.win
);
235 WMResizeWidget(WPrefs
.undoBtn
, 90, 28);
236 WMMoveWidget(WPrefs
.undoBtn
, 235, 350);
237 WMSetButtonText(WPrefs
.undoBtn
, _("Revert All"));
238 WMSetButtonAction(WPrefs
.undoBtn
, undoAll
, NULL
);
240 WPrefs
.saveBtn
= WMCreateCommandButton(WPrefs
.win
);
241 WMResizeWidget(WPrefs
.saveBtn
, 80, 28);
242 WMMoveWidget(WPrefs
.saveBtn
, 335, 350);
243 WMSetButtonText(WPrefs
.saveBtn
, _("Save"));
244 WMSetButtonAction(WPrefs
.saveBtn
, save
, NULL
);
246 WPrefs
.closeBtn
= WMCreateCommandButton(WPrefs
.win
);
247 WMResizeWidget(WPrefs
.closeBtn
, 80, 28);
248 WMMoveWidget(WPrefs
.closeBtn
, 425, 350);
249 WMSetButtonText(WPrefs
.closeBtn
, _("Close"));
250 WMSetButtonAction(WPrefs
.closeBtn
, quit
, NULL
);
252 WPrefs
.balloonBtn
= WMCreateSwitchButton(WPrefs
.win
);
253 WMResizeWidget(WPrefs
.balloonBtn
, 200, 28);
254 WMMoveWidget(WPrefs
.balloonBtn
, 15, 350);
255 WMSetButtonText(WPrefs
.balloonBtn
, _("Balloon Help"));
256 WMSetButtonAction(WPrefs
.balloonBtn
, toggleBalloons
, NULL
);
258 WMUserDefaults
*udb
= WMGetStandardUserDefaults();
259 Bool flag
= WMGetUDBoolForKey(udb
, "BalloonHelp");
261 WMSetButtonSelected(WPrefs
.balloonBtn
, flag
);
262 WMSetBalloonEnabled(scr
, flag
);
266 WPrefs
.banner
= WMCreateFrame(WPrefs
.win
);
267 WMResizeWidget(WPrefs
.banner
, FRAME_WIDTH
, FRAME_HEIGHT
);
268 WMMoveWidget(WPrefs
.banner
, FRAME_LEFT
, FRAME_TOP
);
269 WMSetFrameRelief(WPrefs
.banner
, WRFlat
);
271 font
= WMCreateFont(scr
, "Lucida Sans,URW Gothic L,Times New Roman,serif"
272 ":bold:pixelsize=26:antialias=true");
273 WPrefs
.nameL
= WMCreateLabel(WPrefs
.banner
);
274 WMSetLabelTextAlignment(WPrefs
.nameL
, WACenter
);
275 WMResizeWidget(WPrefs
.nameL
, FRAME_WIDTH
- 20, 60);
276 WMMoveWidget(WPrefs
.nameL
, 10, 50);
277 WMSetLabelFont(WPrefs
.nameL
, font
);
278 WMSetLabelText(WPrefs
.nameL
, _("Window Maker Preferences"));
281 WPrefs
.versionL
= WMCreateLabel(WPrefs
.banner
);
282 WMResizeWidget(WPrefs
.versionL
, FRAME_WIDTH
- 20, 20);
283 WMMoveWidget(WPrefs
.versionL
, 10, 120);
284 WMSetLabelTextAlignment(WPrefs
.versionL
, WACenter
);
285 sprintf(buffer
, _("Version %s"), VERSION
);
286 WMSetLabelText(WPrefs
.versionL
, buffer
);
288 WPrefs
.statusL
= WMCreateLabel(WPrefs
.banner
);
289 WMResizeWidget(WPrefs
.statusL
, FRAME_WIDTH
- 20, 60);
290 WMMoveWidget(WPrefs
.statusL
, 10, 150);
291 WMSetLabelTextAlignment(WPrefs
.statusL
, WACenter
);
292 WMSetLabelText(WPrefs
.statusL
, _("Starting..."));
294 WMMapSubwidgets(WPrefs
.win
);
296 WMUnmapWidget(WPrefs
.undosBtn
);
297 WMUnmapWidget(WPrefs
.undoBtn
);
298 WMUnmapWidget(WPrefs
.saveBtn
);
301 static void showPanel(Panel
* panel
)
303 PanelRec
*rec
= (PanelRec
*) panel
;
305 if (!(rec
->callbacks
.flags
& INITIALIZED_PANEL
)) {
306 (*rec
->callbacks
.createWidgets
) (panel
);
307 rec
->callbacks
.flags
|= INITIALIZED_PANEL
;
310 WMSetWindowTitle(WPrefs
.win
, rec
->sectionName
);
312 if (rec
->callbacks
.showPanel
)
313 (*rec
->callbacks
.showPanel
) (panel
);
315 WMMapWidget(rec
->box
);
318 static void hidePanel(Panel
* panel
)
320 PanelRec
*rec
= (PanelRec
*) panel
;
322 WMUnmapWidget(rec
->box
);
324 if (rec
->callbacks
.hidePanel
)
325 (*rec
->callbacks
.hidePanel
) (panel
);
328 static void savePanelData(Panel
* panel
)
330 PanelRec
*rec
= (PanelRec
*) panel
;
332 if (rec
->callbacks
.updateDomain
) {
333 (*rec
->callbacks
.updateDomain
) (panel
);
337 static void changeSection(WMWidget
* self
, void *data
)
339 /* Parameter not used, but tell the compiler that it is ok */
342 if (WPrefs
.currentPanel
== data
)
345 if (WPrefs
.currentPanel
== NULL
) {
346 WMDestroyWidget(WPrefs
.nameL
);
347 WMDestroyWidget(WPrefs
.versionL
);
348 WMDestroyWidget(WPrefs
.statusL
);
350 WMSetFrameRelief(WPrefs
.banner
, WRGroove
);
352 /* WMMapWidget(WPrefs.undosBtn);
353 WMMapWidget(WPrefs.undoBtn);
355 WMMapWidget(WPrefs
.saveBtn
);
360 if (WPrefs
.currentPanel
)
361 hidePanel(WPrefs
.currentPanel
);
362 WPrefs
.currentPanel
= data
;
365 char *LocateImage(const char *name
)
368 char *tmp
= wmalloc(strlen(name
) + 8);
371 sprintf(tmp
, "%s.tiff", name
);
372 path
= WMPathForResourceOfType(tmp
, "tiff");
374 sprintf(tmp
, "%s.xpm", name
);
375 path
= WMPathForResourceOfType(tmp
, "xpm");
379 wwarning(_("could not locate image file %s"), name
);
385 void CreateImages(WMScreen
*scr
, RContext
*rc
, RImage
*xis
, const char *file
,
386 WMPixmap
**icon_normal
, WMPixmap
**icon_greyed
)
390 RColor gray
= { 0xae, 0xaa, 0xae, 0 };
392 path
= LocateImage(file
);
401 *icon_normal
= WMCreatePixmapFromFile(scr
, path
);
404 wwarning(_("could not load icon %s"), path
);
411 if (!icon_greyed
) // Greyed-out version not requested, we are done
417 icon
= RLoadImage(rc
, path
, 0);
420 wwarning(_("could not load icon %s"), path
);
425 RCombineImageWithColor(icon
, &gray
);
428 RCombineImagesWithOpaqueness(icon
, xis
, 180);
430 *icon_greyed
= WMCreatePixmapFromRImage(scr
, icon
, 127);
433 wwarning(_("could not process icon %s: %s"), path
, RMessageForError(RErrorCode
));
440 static WMPixmap
*makeTitledIcon(WMScreen
* scr
, WMPixmap
* icon
, const char *title1
, const char *title2
)
442 return WMRetainPixmap(icon
);
446 static XFontStruct
*hfont
= NULL
;
447 static XFontStruct
*vfont
= NULL
;
450 Display
*dpy
= WMScreenDisplay(scr
);
451 WMColor
*black
= WMBlackColor(scr
);
453 WMSize size
= WMGetPixmapSize(icon
);
455 tmp
= WMCreatePixmap(scr
, 60, 60, WMScreenDepth(scr
), True
);
457 pix
= WMGetPixmapXID(tmp
);
458 mask
= WMGetPixmapMaskXID(tmp
);
461 gc
= XCreateGC(dpy
, mask
, 0, NULL
);
463 hfont
= XLoadQueryFont(dpy
, ICON_TITLE_FONT
);
464 vfont
= XLoadQueryFont(dpy
, ICON_TITLE_VFONT
);
468 return WMRetainPixmap(icon
);
471 XSetForeground(dpy
, gc
, 0);
472 XFillRectangle(dpy
, mask
, gc
, 0, 0, 60, 60);
474 fgc
= WMColorGC(black
);
476 XSetForeground(dpy
, gc
, 1);
478 XCopyArea(dpy
, WMGetPixmapXID(icon
), pix
, fgc
, 0, 0, size
.width
, size
.height
, 12, 12);
480 if (WMGetPixmapMaskXID(icon
) != None
)
481 XCopyPlane(dpy
, WMGetPixmapMaskXID(icon
), mask
, gc
, 0, 0, size
.width
, size
.height
, 12, 12, 1);
483 XFillRectangle(dpy
, mask
, gc
, 12, 12, 48, 48);
486 XSetFont(dpy
, fgc
, vfont
->fid
);
487 XSetFont(dpy
, gc
, vfont
->fid
);
489 XDrawString(dpy
, pix
, fgc
, 0, vfont
->ascent
, title1
, strlen(title1
));
491 XDrawString(dpy
, mask
, gc
, 0, vfont
->ascent
, title1
, strlen(title1
));
495 XSetFont(dpy
, fgc
, hfont
->fid
);
496 XSetFont(dpy
, gc
, hfont
->fid
);
498 XDrawString(dpy
, pix
, fgc
, (title1
? 12 : 0), hfont
->ascent
, title2
, strlen(title2
));
500 XDrawString(dpy
, mask
, gc
, (title1
? 12 : 0), hfont
->ascent
, title2
, strlen(title2
));
507 void SetButtonAlphaImage(WMScreen
* scr
, WMButton
* bPtr
, const char *file
, const char *title1
, const char *title2
)
514 iconPath
= LocateImage(file
);
521 icon
= WMCreateBlendedPixmapFromFile(scr
, iconPath
, &color
);
523 wwarning(_("could not load icon file %s"), iconPath
);
529 icon2
= makeTitledIcon(scr
, icon
, title1
, title2
);
531 WMReleasePixmap(icon
);
536 WMSetButtonImage(bPtr
, icon2
);
539 WMReleasePixmap(icon2
);
546 icon
= WMCreateBlendedPixmapFromFile(scr
, iconPath
, &color
);
548 wwarning(_("could not load icon file %s"), iconPath
);
553 WMSetButtonAltImage(bPtr
, icon
);
556 WMReleasePixmap(icon
);
562 void AddSection(Panel
* panel
, const char *iconFile
)
566 assert(WPrefs
.sectionCount
< MAX_SECTIONS
);
568 bPtr
= WMCreateCustomButton(WPrefs
.buttonF
, WBBStateLightMask
| WBBStateChangeMask
);
569 WMResizeWidget(bPtr
, 64, 64);
570 WMMoveWidget(bPtr
, WPrefs
.sectionCount
* 64, 0);
571 WMSetButtonImagePosition(bPtr
, WIPImageOnly
);
572 WMSetButtonAction(bPtr
, changeSection
, panel
);
573 WMHangData(bPtr
, panel
);
575 WMSetBalloonTextForView(((PanelRec
*) panel
)->description
, WMWidgetView(bPtr
));
580 t1
= wstrdup(((PanelRec
*) panel
)->sectionName
);
581 t2
= strchr(t1
, ' ');
586 SetButtonAlphaImage(WMWidgetScreen(bPtr
), bPtr
, iconFile
, t1
, t2
);
591 WPrefs
.sectionB
[WPrefs
.sectionCount
] = bPtr
;
593 if (WPrefs
.sectionCount
> 0) {
594 WMGroupButtons(WPrefs
.sectionB
[0], bPtr
);
597 WPrefs
.sectionCount
++;
599 WMResizeWidget(WPrefs
.buttonF
, WPrefs
.sectionCount
* 64, 64);
602 void Initialize(WMScreen
* scr
)
608 list
= RSupportedFileFormats();
609 for (i
= 0; list
[i
] != NULL
; i
++) {
610 if (strcmp(list
[i
], "TIFF") == 0) {
617 path
= WMPathForResourceOfType("WPrefs.tiff", NULL
);
619 path
= WMPathForResourceOfType("WPrefs.xpm", NULL
);
623 tmp
= RLoadImage(WMScreenRContext(scr
), path
, 0);
625 wwarning(_("could not load image file %s:%s"), path
, RMessageForError(RErrorCode
));
627 WMSetApplicationIconImage(scr
, tmp
);
633 memset(&WPrefs
, 0, sizeof(_WPrefs
));
634 createMainWindow(scr
);
636 WMRealizeWidget(WPrefs
.win
);
638 WMSetWindowMiniwindowImage(WPrefs
.win
, WMGetApplicationIconImage(scr
));
640 WMMapWidget(WPrefs
.win
);
641 XFlush(WMScreenDisplay(scr
));
642 WMSetLabelText(WPrefs
.statusL
, _("Loading Window Maker configuration files..."));
643 XFlush(WMScreenDisplay(scr
));
644 loadConfigurations(scr
, WPrefs
.win
);
646 WMSetLabelText(WPrefs
.statusL
, _("Initializing configuration panels..."));
648 InitFocus(WPrefs
.banner
);
649 InitWindowHandling(WPrefs
.banner
);
651 InitMenuPreferences(WPrefs
.banner
);
652 InitIcons(WPrefs
.banner
);
653 InitPreferences(WPrefs
.banner
);
655 InitPaths(WPrefs
.banner
);
656 InitDocks(WPrefs
.banner
);
657 InitWorkspace(WPrefs
.banner
);
658 InitConfigurations(WPrefs
.banner
);
660 InitMenu(WPrefs
.banner
);
662 #ifdef not_yet_fully_implemented
663 InitKeyboardSettings(WPrefs
.banner
);
665 InitKeyboardShortcuts(WPrefs
.banner
);
666 InitMouseSettings(WPrefs
.banner
);
668 InitAppearance(WPrefs
.banner
);
670 InitFontSimple(WPrefs
.banner
);
672 #ifdef not_yet_fully_implemented
673 InitThemes(WPrefs
.banner
);
675 InitExpert(WPrefs
.banner
);
677 WMRealizeWidget(WPrefs
.scrollV
);
679 WMSetLabelText(WPrefs
.statusL
, "");
682 WMWindow
*GetWindow(Panel
* panel
)
687 static void loadConfigurations(WMScreen
* scr
, WMWindow
* mainw
)
689 WMPropList
*db
, *gdb
;
696 path
= wdefaultspathfordomain("WindowMaker");
697 WindowMakerDBPath
= path
;
699 db
= WMReadPropListFromFile(path
);
701 if (!WMIsPLDictionary(db
)) {
702 WMReleasePropList(db
);
704 sprintf(mbuf
, _("Window Maker domain (%s) is corrupted!"), path
);
705 WMRunAlertPanel(scr
, mainw
, _("Error"), mbuf
, _("OK"), NULL
, NULL
);
708 sprintf(mbuf
, _("Could not load Window Maker domain (%s) from defaults database."), path
);
709 WMRunAlertPanel(scr
, mainw
, _("Error"), mbuf
, _("OK"), NULL
, NULL
);
712 path
= getenv("WMAKER_BIN_NAME");
718 command
= wstrconcat(path
, " --version");
719 file
= popen(command
, "r");
722 if (!file
|| !fgets(buffer
, 1023, file
)) {
723 werror(_("could not extract version information from Window Maker"));
724 wfatal(_("Make sure wmaker is in your search path."));
726 WMRunAlertPanel(scr
, mainw
, _("Error"),
728 ("Could not extract version from Window Maker. Make sure it is correctly installed and is in your PATH environment variable."),
729 _("OK"), NULL
, NULL
);
735 if (sscanf(buffer
, "Window Maker %i.%i.%i", &v1
, &v2
, &v3
) != 3
736 && sscanf(buffer
, "WindowMaker %i.%i.%i", &v1
, &v2
, &v3
) != 3) {
737 WMRunAlertPanel(scr
, mainw
, _("Error"),
738 _("Could not extract version from Window Maker. "
739 "Make sure it is correctly installed and the path "
740 "where it installed is in the PATH environment "
741 "variable."), _("OK"), NULL
, NULL
);
744 if (v1
== 0 && (v2
< 18 || v3
< 0)) {
745 sprintf(mbuf
, _("WPrefs only supports Window Maker 0.18.0 or newer.\n"
746 "The version installed is %i.%i.%i\n"), v1
, v2
, v3
);
747 WMRunAlertPanel(scr
, mainw
, _("Error"), mbuf
, _("OK"), NULL
, NULL
);
751 if (v1
> 1 || (v1
== 1 && (v2
> 0))) {
754 ("Window Maker %i.%i.%i, which is installed in your system, is not fully supported by this version of WPrefs."),
756 WMRunAlertPanel(scr
, mainw
, _("Warning"), mbuf
, _("OK"), NULL
, NULL
);
762 command
= wstrconcat(path
, " --global_defaults_path");
763 file
= popen(command
, "r");
766 if (!file
|| !fgets(buffer
, 1023, file
)) {
767 werror(_("could not run \"%s --global_defaults_path\"."), path
);
771 ptr
= strchr(buffer
, '\n');
774 strcat(buffer
, "/WindowMaker");
780 gdb
= WMReadPropListFromFile(buffer
);
783 if (!WMIsPLDictionary(gdb
)) {
784 WMReleasePropList(gdb
);
786 sprintf(mbuf
, _("Window Maker domain (%s) is corrupted!"), buffer
);
787 WMRunAlertPanel(scr
, mainw
, _("Error"), mbuf
, _("OK"), NULL
, NULL
);
790 sprintf(mbuf
, _("Could not load global Window Maker domain (%s)."), buffer
);
791 WMRunAlertPanel(scr
, mainw
, _("Error"), mbuf
, _("OK"), NULL
, NULL
);
795 db
= WMCreatePLDictionary(NULL
, NULL
);
798 gdb
= WMCreatePLDictionary(NULL
, NULL
);
806 WMPropList
*GetObjectForKey(const char *defaultName
)
808 WMPropList
*object
= NULL
;
809 WMPropList
*key
= WMCreatePLString(defaultName
);
811 object
= WMGetFromPLDictionary(WindowMakerDB
, key
);
813 object
= WMGetFromPLDictionary(GlobalDB
, key
);
815 WMReleasePropList(key
);
820 void SetObjectForKey(WMPropList
* object
, const char *defaultName
)
822 WMPropList
*key
= WMCreatePLString(defaultName
);
824 WMPutInPLDictionary(WindowMakerDB
, key
, object
);
825 WMReleasePropList(key
);
828 void RemoveObjectForKey(const char *defaultName
)
830 WMPropList
*key
= WMCreatePLString(defaultName
);
832 WMRemoveFromPLDictionary(WindowMakerDB
, key
);
834 WMReleasePropList(key
);
837 char *GetStringForKey(const char *defaultName
)
841 val
= GetObjectForKey(defaultName
);
846 if (!WMIsPLString(val
))
849 return WMGetFromPLString(val
);
852 WMPropList
*GetArrayForKey(const char *defaultName
)
856 val
= GetObjectForKey(defaultName
);
861 if (!WMIsPLArray(val
))
867 WMPropList
*GetDictionaryForKey(const char *defaultName
)
871 val
= GetObjectForKey(defaultName
);
876 if (!WMIsPLDictionary(val
))
882 int GetIntegerForKey(const char *defaultName
)
888 val
= GetObjectForKey(defaultName
);
893 if (!WMIsPLString(val
))
896 str
= WMGetFromPLString(val
);
900 if (sscanf(str
, "%i", &value
) != 1)
906 Bool
GetBoolForKey(const char *defaultName
)
911 str
= GetStringForKey(defaultName
);
916 if (sscanf(str
, "%i", &value
) == 1 && value
!= 0)
919 if (strcasecmp(str
, "YES") == 0)
922 if (strcasecmp(str
, "Y") == 0)
928 void SetIntegerForKey(int value
, const char *defaultName
)
933 sprintf(buffer
, "%i", value
);
934 object
= WMCreatePLString(buffer
);
936 SetObjectForKey(object
, defaultName
);
937 WMReleasePropList(object
);
940 void SetStringForKey(const char *value
, const char *defaultName
)
944 object
= WMCreatePLString(value
);
946 SetObjectForKey(object
, defaultName
);
947 WMReleasePropList(object
);
950 void SetBoolForKey(Bool value
, const char *defaultName
)
952 static WMPropList
*yes
= NULL
, *no
= NULL
;
955 yes
= WMCreatePLString("YES");
956 no
= WMCreatePLString("NO");
959 SetObjectForKey(value
? yes
: no
, defaultName
);
962 void SetSpeedForKey(int speed
, const char *defaultName
)
987 SetStringForKey(str
, defaultName
);
990 int GetSpeedForKey(const char *defaultName
)
995 str
= GetStringForKey(defaultName
);
999 if (strcasecmp(str
, "ultraslow") == 0)
1001 else if (strcasecmp(str
, "slow") == 0)
1003 else if (strcasecmp(str
, "medium") == 0)
1005 else if (strcasecmp(str
, "fast") == 0)
1007 else if (strcasecmp(str
, "ultrafast") == 0)
1010 wwarning(_("bad speed value for option %s; using default Medium"), defaultName
);