1 /* WPrefs.c- main window and other basic stuff
3 * WPrefs - Window Maker Preferences Program
5 * Copyright (c) 1998-2000 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,
28 extern Panel
*InitWindowHandling(WMScreen
*scr
, WMWindow
*win
);
30 extern Panel
*InitKeyboardSettings(WMScreen
*scr
, WMWindow
*win
);
32 extern Panel
*InitMouseSettings(WMScreen
*scr
, WMWindow
*win
);
34 extern Panel
*InitKeyboardShortcuts(WMScreen
*scr
, WMWindow
*win
);
36 extern Panel
*InitWorkspace(WMScreen
*scr
, WMWindow
*win
);
38 extern Panel
*InitFocus(WMScreen
*scr
, WMWindow
*win
);
40 extern Panel
*InitPreferences(WMScreen
*scr
, WMWindow
*win
);
42 extern Panel
*InitFont(WMScreen
*scr
, WMWindow
*win
);
44 extern Panel
*InitConfigurations(WMScreen
*scr
, WMWindow
*win
);
46 extern Panel
*InitPaths(WMScreen
*scr
, WMWindow
*win
);
48 extern Panel
*InitMenu(WMScreen
*scr
, WMWindow
*win
);
50 extern Panel
*InitExpert(WMScreen
*scr
, WMWindow
*win
);
52 extern Panel
*InitMenuPreferences(WMScreen
*scr
, WMWindow
*win
);
54 extern Panel
*InitIcons(WMScreen
*scr
, WMWindow
*win
);
56 extern Panel
*InitThemes(WMScreen
*scr
, WMWindow
*win
);
58 extern Panel
*InitAppearance(WMScreen
*scr
, WMWindow
*win
);
63 #define ICON_TITLE_FONT "-adobe-helvetica-bold-r-*-*-10-*"
64 #define ICON_TITLE_VFONT "-adobe-helvetica-bold-r-*-*-10-[]-*"
67 #define MAX_SECTIONS 16
70 typedef struct _WPrefs
{
73 WMScrollView
*scrollV
;
75 WMButton
*sectionB
[MAX_SECTIONS
];
96 static _WPrefs WPrefs
;
98 /* system wide defaults dictionary. Read-only */
99 static proplist_t GlobalDB
= NULL
;
100 /* user defaults dictionary */
101 static proplist_t WindowMakerDB
= NULL
;
104 static Bool TIFFOK
= False
;
107 #define INITIALIZED_PANEL (1<<0)
112 static void loadConfigurations(WMScreen
*scr
, WMWindow
*mainw
);
114 static void savePanelData(Panel
*panel
);
116 static void prepareForClose();
119 quit(WMWidget
*w
, void *data
)
128 save(WMWidget
*w
, void *data
)
134 char *msg
= "Reconfigure";
138 /* puts("gathering data");*/
139 for (i
=0; i
<WPrefs
.sectionCount
; i
++) {
140 PanelRec
*rec
= WMGetHangedData(WPrefs
.sectionB
[i
]);
141 if ((rec
->callbacks
.flags
& INITIALIZED_PANEL
))
142 savePanelData((Panel
*)rec
);
144 /* puts("compressing data");*/
145 /* compare the user dictionary with the global and remove redundant data */
146 keyList
= PLGetAllDictionaryKeys(GlobalDB
);
147 /* puts(PLGetDescription(WindowMakerDB));*/
148 for (i
=0; i
<PLGetNumberOfElements(keyList
); i
++) {
149 key
= PLGetArrayElement(keyList
, i
);
151 /* We don't have this value anyway, so no problem.
152 * Probably a new option */
153 p1
= PLGetDictionaryEntry(WindowMakerDB
, key
);
156 /* The global doesn't have it, so no problem either. */
157 p2
= PLGetDictionaryEntry(GlobalDB
, key
);
160 /* If both values are the same, don't save. */
161 if (PLIsEqual(p1
, p2
))
162 PLRemoveDictionaryEntry(WindowMakerDB
, key
);
164 /* puts(PLGetDescription(WindowMakerDB));*/
166 /* puts("storing data");*/
168 PLSave(WindowMakerDB
, YES
);
171 memset(&ev
, 0, sizeof(XEvent
));
173 ev
.xclient
.type
= ClientMessage
;
174 ev
.xclient
.message_type
= XInternAtom(WMScreenDisplay(WMWidgetScreen(w
)),
175 "_WINDOWMAKER_COMMAND", False
);
176 ev
.xclient
.window
= DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w
)));
177 ev
.xclient
.format
= 8;
179 for (i
= 0; i
<= strlen(msg
); i
++) {
180 ev
.xclient
.data
.b
[i
] = msg
[i
];
182 XSendEvent(WMScreenDisplay(WMWidgetScreen(w
)),
183 DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w
))),
184 False
, SubstructureRedirectMask
, &ev
);
185 XFlush(WMScreenDisplay(WMWidgetScreen(w
)));
191 undo(WMWidget
*w
, void *data
)
193 PanelRec
*rec
= (PanelRec
*)WPrefs
.currentPanel
;
198 if (rec
->callbacks
.undoChanges
199 && (rec
->callbacks
.flags
& INITIALIZED_PANEL
)) {
200 (*rec
->callbacks
.undoChanges
)(WPrefs
.currentPanel
);
206 undoAll(WMWidget
*w
, void *data
)
210 for (i
=0; i
<WPrefs
.sectionCount
; i
++) {
211 PanelRec
*rec
= WMGetHangedData(WPrefs
.sectionB
[i
]);
213 if (rec
->callbacks
.undoChanges
214 && (rec
->callbacks
.flags
& INITIALIZED_PANEL
))
215 (*rec
->callbacks
.undoChanges
)((Panel
*)rec
);
226 for (i
=0; i
<WPrefs
.sectionCount
; i
++) {
227 PanelRec
*rec
= WMGetHangedData(WPrefs
.sectionB
[i
]);
229 if (rec
->callbacks
.prepareForClose
230 && (rec
->callbacks
.flags
& INITIALIZED_PANEL
))
231 (*rec
->callbacks
.prepareForClose
)((Panel
*)rec
);
237 toggleBalloons(WMWidget
*w
, void *data
)
239 WMUserDefaults
*udb
= WMGetStandardUserDefaults();
242 flag
= WMGetButtonSelected(WPrefs
.balloonBtn
);
244 WMSetBalloonEnabled(WMWidgetScreen(WPrefs
.win
), flag
);
246 WMSetUDBoolForKey(udb
, flag
, "BalloonHelp");
251 createMainWindow(WMScreen
*scr
)
253 WMScroller
*scroller
;
257 WPrefs
.win
= WMCreateWindow(scr
, "wprefs");
258 WMResizeWidget(WPrefs
.win
, 520, 390);
259 WMSetWindowTitle(WPrefs
.win
, _("Window Maker Preferences"));
260 WMSetWindowCloseAction(WPrefs
.win
, quit
, NULL
);
261 WMSetWindowMaxSize(WPrefs
.win
, 520, 390);
262 WMSetWindowMinSize(WPrefs
.win
, 520, 390);
263 WMSetWindowMiniwindowTitle(WPrefs
.win
, "Preferences");
264 WMSetWindowMiniwindowImage(WPrefs
.win
, WMGetApplicationIconImage(scr
));
266 WPrefs
.scrollV
= WMCreateScrollView(WPrefs
.win
);
267 WMResizeWidget(WPrefs
.scrollV
, 500, 87);
268 WMMoveWidget(WPrefs
.scrollV
, 10, 10);
269 WMSetScrollViewRelief(WPrefs
.scrollV
, WRSunken
);
270 WMSetScrollViewHasHorizontalScroller(WPrefs
.scrollV
, True
);
271 WMSetScrollViewHasVerticalScroller(WPrefs
.scrollV
, False
);
272 scroller
= WMGetScrollViewHorizontalScroller(WPrefs
.scrollV
);
273 WMSetScrollerArrowsPosition(scroller
, WSANone
);
275 WPrefs
.buttonF
= WMCreateFrame(WPrefs
.win
);
276 WMSetFrameRelief(WPrefs
.buttonF
, WRFlat
);
278 WMSetScrollViewContentView(WPrefs
.scrollV
, WMWidgetView(WPrefs
.buttonF
));
280 WPrefs
.undosBtn
= WMCreateCommandButton(WPrefs
.win
);
281 WMResizeWidget(WPrefs
.undosBtn
, 90, 28);
282 WMMoveWidget(WPrefs
.undosBtn
, 135, 350);
283 WMSetButtonText(WPrefs
.undosBtn
, _("Revert Page"));
284 WMSetButtonAction(WPrefs
.undosBtn
, undo
, NULL
);
286 WPrefs
.undoBtn
= WMCreateCommandButton(WPrefs
.win
);
287 WMResizeWidget(WPrefs
.undoBtn
, 90, 28);
288 WMMoveWidget(WPrefs
.undoBtn
, 235, 350);
289 WMSetButtonText(WPrefs
.undoBtn
, _("Revert All"));
290 WMSetButtonAction(WPrefs
.undoBtn
, undoAll
, NULL
);
292 WPrefs
.saveBtn
= WMCreateCommandButton(WPrefs
.win
);
293 WMResizeWidget(WPrefs
.saveBtn
, 80, 28);
294 WMMoveWidget(WPrefs
.saveBtn
, 335, 350);
295 WMSetButtonText(WPrefs
.saveBtn
, _("Save"));
296 WMSetButtonAction(WPrefs
.saveBtn
, save
, NULL
);
298 WPrefs
.closeBtn
= WMCreateCommandButton(WPrefs
.win
);
299 WMResizeWidget(WPrefs
.closeBtn
, 80, 28);
300 WMMoveWidget(WPrefs
.closeBtn
, 425, 350);
301 WMSetButtonText(WPrefs
.closeBtn
, _("Close"));
302 WMSetButtonAction(WPrefs
.closeBtn
, quit
, NULL
);
305 WPrefs
.balloonBtn
= WMCreateSwitchButton(WPrefs
.win
);
306 WMResizeWidget(WPrefs
.balloonBtn
, 200, 28);
307 WMMoveWidget(WPrefs
.balloonBtn
, 15, 350);
308 WMSetButtonText(WPrefs
.balloonBtn
, _("Balloon Help"));
309 WMSetButtonAction(WPrefs
.balloonBtn
, toggleBalloons
, NULL
);
311 WMUserDefaults
*udb
= WMGetStandardUserDefaults();
312 Bool flag
= WMGetUDBoolForKey(udb
, "BalloonHelp");
314 WMSetButtonSelected(WPrefs
.balloonBtn
, flag
);
315 WMSetBalloonEnabled(scr
, flag
);
319 WPrefs
.banner
= WMCreateFrame(WPrefs
.win
);
320 WMResizeWidget(WPrefs
.banner
, FRAME_WIDTH
, FRAME_HEIGHT
);
321 WMMoveWidget(WPrefs
.banner
, FRAME_LEFT
, FRAME_TOP
);
322 WMSetFrameRelief(WPrefs
.banner
, WRFlat
);
324 font
= WMCreateFont(scr
, "-*-times-bold-r-*-*-24-*-*-*-*-*-*-*,"
325 "-*-fixed-medium-r-normal-*-24-*");
327 font
= WMBoldSystemFontOfSize(scr
, 24);
328 WPrefs
.nameL
= WMCreateLabel(WPrefs
.banner
);
329 WMSetLabelTextAlignment(WPrefs
.nameL
, WACenter
);
330 WMResizeWidget(WPrefs
.nameL
, FRAME_WIDTH
-20, 30);
331 WMMoveWidget(WPrefs
.nameL
, 10, 25);
332 WMSetLabelFont(WPrefs
.nameL
, font
);
333 WMSetLabelText(WPrefs
.nameL
, _("Window Maker Preferences Utility"));
336 WPrefs
.versionL
= WMCreateLabel(WPrefs
.banner
);
337 WMResizeWidget(WPrefs
.versionL
, FRAME_WIDTH
-20, 20);
338 WMMoveWidget(WPrefs
.versionL
, 10, 65);
339 WMSetLabelTextAlignment(WPrefs
.versionL
, WACenter
);
340 sprintf(buffer
, _("Version %s for Window Maker %s or newer"), WVERSION
,
342 WMSetLabelText(WPrefs
.versionL
, buffer
);
344 WPrefs
.statusL
= WMCreateLabel(WPrefs
.banner
);
345 WMResizeWidget(WPrefs
.statusL
, FRAME_WIDTH
-20, 60);
346 WMMoveWidget(WPrefs
.statusL
, 10, 100);
347 WMSetLabelTextAlignment(WPrefs
.statusL
, WACenter
);
348 WMSetLabelText(WPrefs
.statusL
, _("Starting..."));
350 WPrefs
.creditsL
= WMCreateLabel(WPrefs
.banner
);
351 WMResizeWidget(WPrefs
.creditsL
, FRAME_WIDTH
-20, 60);
352 WMMoveWidget(WPrefs
.creditsL
, 10, FRAME_HEIGHT
-60);
353 WMSetLabelTextAlignment(WPrefs
.creditsL
, WACenter
);
354 WMSetLabelText(WPrefs
.creditsL
, _("Programming/Design: Alfredo K. Kojima\n"
355 "Artwork: Marco van Hylckama Vlieg and Largo\n"
356 "More Programming: James Thompson"));
359 WMMapSubwidgets(WPrefs
.win
);
361 WMUnmapWidget(WPrefs
.undosBtn
);
362 WMUnmapWidget(WPrefs
.undoBtn
);
363 WMUnmapWidget(WPrefs
.saveBtn
);
368 showPanel(Panel
*panel
)
370 PanelRec
*rec
= (PanelRec
*)panel
;
372 if (!(rec
->callbacks
.flags
& INITIALIZED_PANEL
)) {
373 (*rec
->callbacks
.createWidgets
)(panel
);
374 rec
->callbacks
.flags
|= INITIALIZED_PANEL
;
377 WMSetWindowTitle(WPrefs
.win
, rec
->sectionName
);
379 if (rec
->callbacks
.showPanel
)
380 (*rec
->callbacks
.showPanel
)(panel
);
382 WMMapWidget(rec
->frame
);
388 hidePanel(Panel
*panel
)
390 PanelRec
*rec
= (PanelRec
*)panel
;
392 WMUnmapWidget(rec
->frame
);
394 if (rec
->callbacks
.hidePanel
)
395 (*rec
->callbacks
.hidePanel
)(panel
);
400 savePanelData(Panel
*panel
)
402 PanelRec
*rec
= (PanelRec
*)panel
;
404 if (rec
->callbacks
.updateDomain
) {
405 (*rec
->callbacks
.updateDomain
)(panel
);
411 changeSection(WMWidget
*self
, void *data
)
414 WMDestroyWidget(WPrefs
.banner
);
415 WPrefs
.banner
= NULL
;
416 /* WMMapWidget(WPrefs.undosBtn);
417 WMMapWidget(WPrefs.undoBtn);
419 WMMapWidget(WPrefs
.saveBtn
);
424 if (WPrefs
.currentPanel
)
425 hidePanel(WPrefs
.currentPanel
);
426 WPrefs
.currentPanel
= data
;
434 LocateImage(char *name
)
437 char *tmp
= wmalloc(strlen(name
)+8);
440 sprintf(tmp
, "%s.tiff", name
);
441 path
= WMPathForResourceOfType(tmp
, "tiff");
443 sprintf(tmp
, "%s.xpm", name
);
444 path
= WMPathForResourceOfType(tmp
, "xpm");
448 wwarning(_("could not locate image file %s\n"), name
);
457 makeTitledIcon(WMScreen
*scr
, WMPixmap
*icon
, char *title1
, char *title2
)
459 return WMRetainPixmap(icon
);
463 static XFontStruct
*hfont
= NULL
;
464 static XFontStruct
*vfont
= NULL
;
467 Display
*dpy
= WMScreenDisplay(scr
);
468 WMColor
*black
= WMBlackColor(scr
);
470 WMSize size
= WMGetPixmapSize(icon
);
473 tmp
= WMCreatePixmap(scr
, 60, 60, WMScreenDepth(scr
), True
);
475 pix
= WMGetPixmapXID(tmp
);
476 mask
= WMGetPixmapMaskXID(tmp
);
479 gc
= XCreateGC(dpy
, mask
, 0, NULL
);
481 hfont
= XLoadQueryFont(dpy
, ICON_TITLE_FONT
);
482 vfont
= XLoadQueryFont(dpy
, ICON_TITLE_VFONT
);
486 return WMRetainPixmap(icon
);
489 XSetForeground(dpy
, gc
, 0);
490 XFillRectangle(dpy
, mask
, gc
, 0, 0, 60, 60);
492 fgc
= WMColorGC(black
);
494 XSetForeground(dpy
, gc
, 1);
496 XCopyArea(dpy
, WMGetPixmapXID(icon
), pix
, fgc
, 0, 0,
497 size
.width
, size
.height
, 12, 12);
499 if (WMGetPixmapMaskXID(icon
) != None
)
500 XCopyPlane(dpy
, WMGetPixmapMaskXID(icon
), mask
, gc
, 0, 0,
501 size
.width
, size
.height
, 12, 12, 1);
503 XFillRectangle(dpy
, mask
, gc
, 12, 12, 48, 48);
507 XSetFont(dpy
, fgc
, vfont
->fid
);
508 XSetFont(dpy
, gc
, vfont
->fid
);
510 XDrawString(dpy
, pix
, fgc
, 0, vfont
->ascent
,
511 title1
, strlen(title1
));
513 XDrawString(dpy
, mask
, gc
, 0, vfont
->ascent
,
514 title1
, strlen(title1
));
518 XSetFont(dpy
, fgc
, hfont
->fid
);
519 XSetFont(dpy
, gc
, hfont
->fid
);
521 XDrawString(dpy
, pix
, fgc
, (title1
? 12 : 0), hfont
->ascent
,
522 title2
, strlen(title2
));
524 XDrawString(dpy
, mask
, gc
, (title1
? 12 : 0), hfont
->ascent
,
525 title2
, strlen(title2
));
534 SetButtonAlphaImage(WMScreen
*scr
, WMButton
*bPtr
, char *file
,
535 char *title1
, char *title2
)
542 iconPath
= LocateImage(file
);
549 icon
= WMCreateBlendedPixmapFromFile(scr
, iconPath
, &color
);
551 wwarning(_("could not load icon file %s"), iconPath
);
557 icon2
= makeTitledIcon(scr
, icon
, title1
, title2
);
559 WMReleasePixmap(icon
);
564 WMSetButtonImage(bPtr
, icon2
);
567 WMReleasePixmap(icon2
);
574 icon
= WMCreateBlendedPixmapFromFile(scr
, iconPath
, &color
);
576 wwarning(_("could not load icon file %s"), iconPath
);
581 WMSetButtonAltImage(bPtr
, icon
);
584 WMReleasePixmap(icon
);
592 AddSection(Panel
*panel
, char *iconFile
)
596 assert(WPrefs
.sectionCount
< MAX_SECTIONS
);
599 bPtr
= WMCreateCustomButton(WPrefs
.buttonF
, WBBStateLightMask
600 |WBBStateChangeMask
);
601 WMResizeWidget(bPtr
, 64, 64);
602 WMMoveWidget(bPtr
, WPrefs
.sectionCount
*64, 0);
603 WMSetButtonImagePosition(bPtr
, WIPImageOnly
);
604 WMSetButtonAction(bPtr
, changeSection
, panel
);
605 WMHangData(bPtr
, panel
);
607 WMSetBalloonTextForView(((PanelRec
*)panel
)->description
,
613 t1
= wstrdup(((PanelRec
*)panel
)->sectionName
);
614 t2
= strchr(t1
, ' ');
619 SetButtonAlphaImage(WMWidgetScreen(bPtr
), bPtr
, iconFile
,
625 WPrefs
.sectionB
[WPrefs
.sectionCount
] = bPtr
;
627 if (WPrefs
.sectionCount
> 0) {
628 WMGroupButtons(WPrefs
.sectionB
[0], bPtr
);
631 WPrefs
.sectionCount
++;
633 WMResizeWidget(WPrefs
.buttonF
, WPrefs
.sectionCount
*64, 64);
638 Initialize(WMScreen
*scr
)
646 list
= RSupportedFileFormats();
647 for (i
=0; list
[i
]!=NULL
; i
++) {
648 if (strcmp(list
[i
], "TIFF")==0) {
655 path
= WMPathForResourceOfType("WPrefs.tiff", NULL
);
657 path
= WMPathForResourceOfType("WPrefs.xpm", NULL
);
661 tmp
= RLoadImage(WMScreenRContext(scr
), path
, 0);
663 wwarning(_("could not load image file %s:%s"), path
,
664 RMessageForError(RErrorCode
));
666 icon
= WMCreatePixmapFromRImage(scr
, tmp
, 0);
669 WMSetApplicationIconImage(scr
, icon
);
670 WMReleasePixmap(icon
);
676 memset(&WPrefs
, 0, sizeof(_WPrefs
));
677 createMainWindow(scr
);
679 WMRealizeWidget(WPrefs
.win
);
680 WMMapWidget(WPrefs
.win
);
681 XFlush(WMScreenDisplay(scr
));
682 WMSetLabelText(WPrefs
.statusL
, _("Loading Window Maker configuration files..."));
683 XFlush(WMScreenDisplay(scr
));
684 loadConfigurations(scr
, WPrefs
.win
);
686 WMSetLabelText(WPrefs
.statusL
, _("Initializing configuration panels..."));
688 InitWindowHandling(scr
, WPrefs
.win
);
689 InitFocus(scr
, WPrefs
.win
);
690 InitMenuPreferences(scr
, WPrefs
.win
);
691 InitIcons(scr
, WPrefs
.win
);
692 InitPreferences(scr
, WPrefs
.win
);
694 InitPaths(scr
, WPrefs
.win
);
695 InitWorkspace(scr
, WPrefs
.win
);
696 InitConfigurations(scr
, WPrefs
.win
);
698 InitMenu(scr
, WPrefs
.win
);
700 #ifdef not_yet_fully_implemented
701 InitKeyboardSettings(scr
, WPrefs
.win
);
703 InitKeyboardShortcuts(scr
, WPrefs
.win
);
704 InitMouseSettings(scr
, WPrefs
.win
);
706 InitAppearance(scr
, WPrefs
.win
);
709 InitFont(scr
, WPrefs
.win
);
711 #ifdef not_yet_fully_implemented
712 InitThemes(scr
, WPrefs
.win
);
714 InitExpert(scr
, WPrefs
.win
);
716 WMRealizeWidget(WPrefs
.scrollV
);
718 WMSetLabelText(WPrefs
.statusL
,
719 _("WPrefs is free software and is distributed WITHOUT ANY\n"
720 "WARRANTY under the terms of the GNU General Public License."));
725 GetWindow(Panel
*panel
)
732 loadConfigurations(WMScreen
*scr
, WMWindow
*mainw
)
741 path
= wdefaultspathfordomain("WindowMaker");
743 db
= PLGetProplistWithPath(path
);
745 if (!PLIsDictionary(db
)) {
748 sprintf(mbuf
, _("Window Maker domain (%s) is corrupted!"), path
);
749 WMRunAlertPanel(scr
, mainw
, _("Error"), mbuf
, _("OK"), NULL
, NULL
);
752 sprintf(mbuf
, _("Could not load Window Maker domain (%s) from defaults database."),
754 WMRunAlertPanel(scr
, mainw
, _("Error"), mbuf
, _("OK"), NULL
, NULL
);
758 path
= getenv("WMAKER_BIN_NAME");
764 command
= wstrconcat(path
, " --version");
765 file
= popen(command
, "r");
768 if (!file
|| !fgets(buffer
, 1023, file
)) {
769 wsyserror(_("could not extract version information from Window Maker"));
770 wfatal(_("Make sure wmaker is in your search path."));
772 WMRunAlertPanel(scr
, mainw
, _("Error"),
773 _("Could not extract version from Window Maker. Make sure it is correctly installed and is in your PATH environment variable."),
774 _("OK"), NULL
, NULL
);
780 if (sscanf(buffer
, "Window Maker %i.%i.%i",&v1
,&v2
,&v3
)!=3
781 && sscanf(buffer
, "WindowMaker %i.%i.%i",&v1
,&v2
,&v3
)!=3) {
782 WMRunAlertPanel(scr
, mainw
, _("Error"),
783 _("Could not extract version from Window Maker. "
784 "Make sure it is correctly installed and the path "
785 "where it installed is in the PATH environment "
786 "variable."), _("OK"), NULL
, NULL
);
789 if (v1
== 0 && (v2
< 18 || v3
< 0)) {
790 sprintf(mbuf
, _("WPrefs only supports Window Maker 0.18.0 or newer.\n"
791 "The version installed is %i.%i.%i\n"), v1
, v2
, v3
);
792 WMRunAlertPanel(scr
, mainw
, _("Error"), mbuf
, _("OK"), NULL
, NULL
);
796 if (v1
> 1 || (v1
== 1 && (v2
> 0))) {
797 sprintf(mbuf
, _("Window Maker %i.%i.%i, which is installed in your system, is not fully supported by this version of WPrefs."),
799 WMRunAlertPanel(scr
, mainw
, _("Warning"), mbuf
, _("OK"), NULL
, NULL
);
805 command
= wstrconcat(path
, " --global_defaults_path");
806 file
= popen(command
, "r");
809 if (!file
|| !fgets(buffer
, 1023, file
)) {
810 wsyserror(_("could not run \"%s --global_defaults_path\"."), path
);
814 ptr
= strchr(buffer
, '\n');
817 strcat(buffer
, "/WindowMaker");
823 gdb
= PLGetProplistWithPath(buffer
);
825 if (!PLIsDictionary(gdb
)) {
828 sprintf(mbuf
, _("Window Maker domain (%s) is corrupted!"), buffer
);
829 WMRunAlertPanel(scr
, mainw
, _("Error"), mbuf
, _("OK"), NULL
, NULL
);
832 sprintf(mbuf
, _("Could not load global Window Maker domain (%s)."),
834 WMRunAlertPanel(scr
, mainw
, _("Error"), mbuf
, _("OK"), NULL
, NULL
);
838 db
= PLMakeDictionaryFromEntries(NULL
, NULL
, NULL
);
841 gdb
= PLMakeDictionaryFromEntries(NULL
, NULL
, NULL
);
851 GetObjectForKey(char *defaultName
)
853 proplist_t object
= NULL
;
854 proplist_t key
= PLMakeString(defaultName
);
856 object
= PLGetDictionaryEntry(WindowMakerDB
, key
);
858 object
= PLGetDictionaryEntry(GlobalDB
, key
);
867 SetObjectForKey(proplist_t object
, char *defaultName
)
869 proplist_t key
= PLMakeString(defaultName
);
871 PLInsertDictionaryEntry(WindowMakerDB
, key
, object
);
877 RemoveObjectForKey(char *defaultName
)
879 proplist_t key
= PLMakeString(defaultName
);
881 PLRemoveDictionaryEntry(WindowMakerDB
, key
);
888 GetStringForKey(char *defaultName
)
892 val
= GetObjectForKey(defaultName
);
897 if (!PLIsString(val
))
900 return PLGetString(val
);
906 GetArrayForKey(char *defaultName
)
910 val
= GetObjectForKey(defaultName
);
923 GetDictionaryForKey(char *defaultName
)
927 val
= GetObjectForKey(defaultName
);
932 if (!PLIsDictionary(val
))
940 GetIntegerForKey(char *defaultName
)
946 val
= GetObjectForKey(defaultName
);
951 if (!PLIsString(val
))
954 str
= PLGetString(val
);
958 if (sscanf(str
, "%i", &value
)!=1)
966 GetBoolForKey(char *defaultName
)
971 str
= GetStringForKey(defaultName
);
976 if (sscanf(str
, "%i", &value
)==1 && value
!=0)
979 if (strcasecmp(str
, "YES")==0)
982 if (strcasecmp(str
, "Y")==0)
990 SetIntegerForKey(int value
, char *defaultName
)
995 sprintf(buffer
, "%i", value
);
996 object
= PLMakeString(buffer
);
998 SetObjectForKey(object
, defaultName
);
1005 SetStringForKey(char *value
, char *defaultName
)
1009 object
= PLMakeString(value
);
1011 SetObjectForKey(object
, defaultName
);
1017 SetBoolForKey(Bool value
, char *defaultName
)
1019 static proplist_t yes
= NULL
, no
= NULL
;
1022 yes
= PLMakeString("YES");
1023 no
= PLMakeString("NO");
1026 SetObjectForKey(value
? yes
: no
, defaultName
);
1031 SetSpeedForKey(int speed
, char *defaultName
)
1056 SetStringForKey(str
, defaultName
);
1061 GetSpeedForKey(char *defaultName
)
1066 str
= GetStringForKey(defaultName
);
1070 if (strcasecmp(str
, "ultraslow")==0)
1072 else if (strcasecmp(str
, "slow")==0)
1074 else if (strcasecmp(str
, "medium")==0)
1076 else if (strcasecmp(str
, "fast")==0)
1078 else if (strcasecmp(str
, "ultrafast")==0)
1081 wwarning(_("bad speed value for option %s\n. Using default Medium"),