/* WPrefs.c- main window and other basic stuff * * WPrefs - Window Maker Preferences Program * * Copyright (c) 1998-2003 Alfredo K. Kojima * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ #include "WPrefs.h" #include extern Panel *InitWindowHandling(WMScreen * scr, WMWidget * parent); extern Panel *InitKeyboardSettings(WMScreen * scr, WMWidget * parent); extern Panel *InitMouseSettings(WMScreen * scr, WMWidget * parent); extern Panel *InitKeyboardShortcuts(WMScreen * scr, WMWidget * parent); extern Panel *InitWorkspace(WMScreen * scr, WMWidget * parent); extern Panel *InitFocus(WMScreen * scr, WMWidget * parent); extern Panel *InitPreferences(WMScreen * scr, WMWidget * parent); extern Panel *InitFont(WMScreen * scr, WMWidget * parent); extern Panel *InitFontSimple(WMScreen * scr, WMWidget * parent); extern Panel *InitConfigurations(WMScreen * scr, WMWidget * parent); extern Panel *InitPaths(WMScreen * scr, WMWidget * parent); extern Panel *InitMenu(WMScreen * scr, WMWidget * parent); extern Panel *InitExpert(WMScreen * scr, WMWidget * parent); extern Panel *InitMenuPreferences(WMScreen * scr, WMWidget * parent); extern Panel *InitIcons(WMScreen * scr, WMWidget * parent); extern Panel *InitThemes(WMScreen * scr, WMWidget * parent); extern Panel *InitAppearance(WMScreen * scr, WMWidget * parent); #define ICON_TITLE_FONT "sans serif:pixelsize=9" #define ICON_TITLE_VFONT "sans serif:pixelsize=9:weight=100" #define MAX_SECTIONS 16 typedef struct _WPrefs { WMWindow *win; WMScrollView *scrollV; WMFrame *buttonF; WMButton *sectionB[MAX_SECTIONS]; int sectionCount; WMButton *saveBtn; WMButton *closeBtn; WMButton *undoBtn; WMButton *undosBtn; WMButton *balloonBtn; WMFrame *banner; WMLabel *nameL; WMLabel *versionL; WMLabel *statusL; Panel *currentPanel; } _WPrefs; static _WPrefs WPrefs; /* system wide defaults dictionary. Read-only */ static WMPropList *GlobalDB = NULL; /* user defaults dictionary */ static WMPropList *WindowMakerDB = NULL; static char *WindowMakerDBPath = NULL; static Bool TIFFOK = False; #define INITIALIZED_PANEL (1<<0) static void loadConfigurations(WMScreen * scr, WMWindow * mainw); static void savePanelData(Panel * panel); static void prepareForClose(); void quit(WMWidget * w, void *data) { prepareForClose(); exit(0); } static void save(WMWidget * w, void *data) { int i; WMPropList *p1, *p2; WMPropList *keyList; WMPropList *key; XEvent ev; /* puts("gathering data"); */ for (i = 0; i < WPrefs.sectionCount; i++) { PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]); if ((rec->callbacks.flags & INITIALIZED_PANEL)) savePanelData((Panel *) rec); } /* puts("compressing data"); */ /* compare the user dictionary with the global and remove redundant data */ keyList = WMGetPLDictionaryKeys(GlobalDB); /* puts(WMGetPropListDescription(WindowMakerDB, False)); */ for (i = 0; i < WMGetPropListItemCount(keyList); i++) { key = WMGetFromPLArray(keyList, i); /* We don't have this value anyway, so no problem. * Probably a new option */ p1 = WMGetFromPLDictionary(WindowMakerDB, key); if (!p1) continue; /* The global doesn't have it, so no problem either. */ p2 = WMGetFromPLDictionary(GlobalDB, key); if (!p2) continue; /* If both values are the same, don't save. */ if (WMIsPropListEqualTo(p1, p2)) WMRemoveFromPLDictionary(WindowMakerDB, key); } /* puts(WMGetPropListDescription(WindowMakerDB, False)); */ WMReleasePropList(keyList); /* puts("storing data"); */ WMWritePropListToFile(WindowMakerDB, WindowMakerDBPath); memset(&ev, 0, sizeof(XEvent)); ev.xclient.type = ClientMessage; ev.xclient.message_type = XInternAtom(WMScreenDisplay(WMWidgetScreen(w)), "_WINDOWMAKER_COMMAND", False); ev.xclient.window = DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w))); ev.xclient.format = 8; strncpy(ev.xclient.data.b, "Reconfigure", sizeof(ev.xclient.data.b)); XSendEvent(WMScreenDisplay(WMWidgetScreen(w)), DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w))), False, SubstructureRedirectMask, &ev); XFlush(WMScreenDisplay(WMWidgetScreen(w))); } static void undo(WMWidget * w, void *data) { PanelRec *rec = (PanelRec *) WPrefs.currentPanel; if (!rec) return; if (rec->callbacks.undoChanges && (rec->callbacks.flags & INITIALIZED_PANEL)) { (*rec->callbacks.undoChanges) (WPrefs.currentPanel); } } static void undoAll(WMWidget * w, void *data) { int i; for (i = 0; i < WPrefs.sectionCount; i++) { PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]); if (rec->callbacks.undoChanges && (rec->callbacks.flags & INITIALIZED_PANEL)) (*rec->callbacks.undoChanges) ((Panel *) rec); } } static void prepareForClose() { int i; for (i = 0; i < WPrefs.sectionCount; i++) { PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]); if (rec->callbacks.prepareForClose && (rec->callbacks.flags & INITIALIZED_PANEL)) (*rec->callbacks.prepareForClose) ((Panel *) rec); } } void toggleBalloons(WMWidget * w, void *data) { WMUserDefaults *udb = WMGetStandardUserDefaults(); Bool flag; flag = WMGetButtonSelected(WPrefs.balloonBtn); WMSetBalloonEnabled(WMWidgetScreen(WPrefs.win), flag); WMSetUDBoolForKey(udb, flag, "BalloonHelp"); } static void createMainWindow(WMScreen * scr) { WMScroller *scroller; WMFont *font; char buffer[128]; WPrefs.win = WMCreateWindow(scr, "wprefs"); WMResizeWidget(WPrefs.win, 520, 390); WMSetWindowTitle(WPrefs.win, _("Window Maker Preferences")); WMSetWindowCloseAction(WPrefs.win, quit, NULL); WMSetWindowMaxSize(WPrefs.win, 520, 390); WMSetWindowMinSize(WPrefs.win, 520, 390); WMSetWindowMiniwindowTitle(WPrefs.win, "Preferences"); WPrefs.scrollV = WMCreateScrollView(WPrefs.win); WMResizeWidget(WPrefs.scrollV, 500, 87); WMMoveWidget(WPrefs.scrollV, 10, 10); WMSetScrollViewRelief(WPrefs.scrollV, WRSunken); WMSetScrollViewHasHorizontalScroller(WPrefs.scrollV, True); WMSetScrollViewHasVerticalScroller(WPrefs.scrollV, False); scroller = WMGetScrollViewHorizontalScroller(WPrefs.scrollV); WMSetScrollerArrowsPosition(scroller, WSANone); WPrefs.buttonF = WMCreateFrame(WPrefs.win); WMSetFrameRelief(WPrefs.buttonF, WRFlat); WMSetScrollViewContentView(WPrefs.scrollV, WMWidgetView(WPrefs.buttonF)); WPrefs.undosBtn = WMCreateCommandButton(WPrefs.win); WMResizeWidget(WPrefs.undosBtn, 90, 28); WMMoveWidget(WPrefs.undosBtn, 135, 350); WMSetButtonText(WPrefs.undosBtn, _("Revert Page")); WMSetButtonAction(WPrefs.undosBtn, undo, NULL); WPrefs.undoBtn = WMCreateCommandButton(WPrefs.win); WMResizeWidget(WPrefs.undoBtn, 90, 28); WMMoveWidget(WPrefs.undoBtn, 235, 350); WMSetButtonText(WPrefs.undoBtn, _("Revert All")); WMSetButtonAction(WPrefs.undoBtn, undoAll, NULL); WPrefs.saveBtn = WMCreateCommandButton(WPrefs.win); WMResizeWidget(WPrefs.saveBtn, 80, 28); WMMoveWidget(WPrefs.saveBtn, 335, 350); WMSetButtonText(WPrefs.saveBtn, _("Save")); WMSetButtonAction(WPrefs.saveBtn, save, NULL); WPrefs.closeBtn = WMCreateCommandButton(WPrefs.win); WMResizeWidget(WPrefs.closeBtn, 80, 28); WMMoveWidget(WPrefs.closeBtn, 425, 350); WMSetButtonText(WPrefs.closeBtn, _("Close")); WMSetButtonAction(WPrefs.closeBtn, quit, NULL); WPrefs.balloonBtn = WMCreateSwitchButton(WPrefs.win); WMResizeWidget(WPrefs.balloonBtn, 200, 28); WMMoveWidget(WPrefs.balloonBtn, 15, 350); WMSetButtonText(WPrefs.balloonBtn, _("Balloon Help")); WMSetButtonAction(WPrefs.balloonBtn, toggleBalloons, NULL); { WMUserDefaults *udb = WMGetStandardUserDefaults(); Bool flag = WMGetUDBoolForKey(udb, "BalloonHelp"); WMSetButtonSelected(WPrefs.balloonBtn, flag); WMSetBalloonEnabled(scr, flag); } /* banner */ WPrefs.banner = WMCreateFrame(WPrefs.win); WMResizeWidget(WPrefs.banner, FRAME_WIDTH, FRAME_HEIGHT); WMMoveWidget(WPrefs.banner, FRAME_LEFT, FRAME_TOP); WMSetFrameRelief(WPrefs.banner, WRFlat); font = WMCreateFont(scr, "Lucida Sans,URW Gothic L,Times New Roman,serif" ":bold:pixelsize=26:antialias=true"); WPrefs.nameL = WMCreateLabel(WPrefs.banner); WMSetLabelTextAlignment(WPrefs.nameL, WACenter); WMResizeWidget(WPrefs.nameL, FRAME_WIDTH - 20, 60); WMMoveWidget(WPrefs.nameL, 10, 50); WMSetLabelFont(WPrefs.nameL, font); WMSetLabelText(WPrefs.nameL, _("Window Maker Preferences")); WMReleaseFont(font); WPrefs.versionL = WMCreateLabel(WPrefs.banner); WMResizeWidget(WPrefs.versionL, FRAME_WIDTH - 20, 20); WMMoveWidget(WPrefs.versionL, 10, 120); WMSetLabelTextAlignment(WPrefs.versionL, WACenter); sprintf(buffer, _("Version %s"), VERSION); WMSetLabelText(WPrefs.versionL, buffer); WPrefs.statusL = WMCreateLabel(WPrefs.banner); WMResizeWidget(WPrefs.statusL, FRAME_WIDTH - 20, 60); WMMoveWidget(WPrefs.statusL, 10, 150); WMSetLabelTextAlignment(WPrefs.statusL, WACenter); WMSetLabelText(WPrefs.statusL, _("Starting...")); WMMapSubwidgets(WPrefs.win); WMUnmapWidget(WPrefs.undosBtn); WMUnmapWidget(WPrefs.undoBtn); WMUnmapWidget(WPrefs.saveBtn); } static void showPanel(Panel * panel) { PanelRec *rec = (PanelRec *) panel; if (!(rec->callbacks.flags & INITIALIZED_PANEL)) { (*rec->callbacks.createWidgets) (panel); rec->callbacks.flags |= INITIALIZED_PANEL; } WMSetWindowTitle(WPrefs.win, rec->sectionName); if (rec->callbacks.showPanel) (*rec->callbacks.showPanel) (panel); WMMapWidget(rec->box); } static void hidePanel(Panel * panel) { PanelRec *rec = (PanelRec *) panel; WMUnmapWidget(rec->box); if (rec->callbacks.hidePanel) (*rec->callbacks.hidePanel) (panel); } static void savePanelData(Panel * panel) { PanelRec *rec = (PanelRec *) panel; if (rec->callbacks.updateDomain) { (*rec->callbacks.updateDomain) (panel); } } static void changeSection(WMWidget * self, void *data) { if (WPrefs.currentPanel == data) return; if (WPrefs.currentPanel == NULL) { WMDestroyWidget(WPrefs.nameL); WMDestroyWidget(WPrefs.versionL); WMDestroyWidget(WPrefs.statusL); WMSetFrameRelief(WPrefs.banner, WRGroove); /* WMMapWidget(WPrefs.undosBtn); WMMapWidget(WPrefs.undoBtn); */ WMMapWidget(WPrefs.saveBtn); } showPanel(data); if (WPrefs.currentPanel) hidePanel(WPrefs.currentPanel); WPrefs.currentPanel = data; } char *LocateImage(char *name) { char *path; char *tmp = wmalloc(strlen(name) + 8); if (TIFFOK) { sprintf(tmp, "%s.tiff", name); path = WMPathForResourceOfType(tmp, "tiff"); } else { sprintf(tmp, "%s.xpm", name); path = WMPathForResourceOfType(tmp, "xpm"); } wfree(tmp); if (!path) { wwarning(_("could not locate image file %s"), name); } return path; } static WMPixmap *makeTitledIcon(WMScreen * scr, WMPixmap * icon, char *title1, char *title2) { return WMRetainPixmap(icon); #if 0 static GC gc = NULL; static XFontStruct *hfont = NULL; static XFontStruct *vfont = NULL; WMPixmap *tmp; Pixmap pix, mask; Display *dpy = WMScreenDisplay(scr); WMColor *black = WMBlackColor(scr); GC fgc; WMSize size = WMGetPixmapSize(icon); tmp = WMCreatePixmap(scr, 60, 60, WMScreenDepth(scr), True); pix = WMGetPixmapXID(tmp); mask = WMGetPixmapMaskXID(tmp); if (gc == NULL) { gc = XCreateGC(dpy, mask, 0, NULL); hfont = XLoadQueryFont(dpy, ICON_TITLE_FONT); vfont = XLoadQueryFont(dpy, ICON_TITLE_VFONT); } if (hfont == NULL) { return WMRetainPixmap(icon); } XSetForeground(dpy, gc, 0); XFillRectangle(dpy, mask, gc, 0, 0, 60, 60); fgc = WMColorGC(black); XSetForeground(dpy, gc, 1); XCopyArea(dpy, WMGetPixmapXID(icon), pix, fgc, 0, 0, size.width, size.height, 12, 12); if (WMGetPixmapMaskXID(icon) != None) XCopyPlane(dpy, WMGetPixmapMaskXID(icon), mask, gc, 0, 0, size.width, size.height, 12, 12, 1); else XFillRectangle(dpy, mask, gc, 12, 12, 48, 48); if (title1) { XSetFont(dpy, fgc, vfont->fid); XSetFont(dpy, gc, vfont->fid); XDrawString(dpy, pix, fgc, 0, vfont->ascent, title1, strlen(title1)); XDrawString(dpy, mask, gc, 0, vfont->ascent, title1, strlen(title1)); } if (title2) { XSetFont(dpy, fgc, hfont->fid); XSetFont(dpy, gc, hfont->fid); XDrawString(dpy, pix, fgc, (title1 ? 12 : 0), hfont->ascent, title2, strlen(title2)); XDrawString(dpy, mask, gc, (title1 ? 12 : 0), hfont->ascent, title2, strlen(title2)); } return tmp; #endif } void SetButtonAlphaImage(WMScreen * scr, WMButton * bPtr, char *file, char *title1, char *title2) { WMPixmap *icon; WMPixmap *icon2; RColor color; char *iconPath; iconPath = LocateImage(file); color.red = 0xae; color.green = 0xaa; color.blue = 0xae; color.alpha = 0; if (iconPath) { icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color); if (!icon) wwarning(_("could not load icon file %s"), iconPath); } else { icon = NULL; } if (icon) { icon2 = makeTitledIcon(scr, icon, title1, title2); if (icon) WMReleasePixmap(icon); } else { icon2 = NULL; } WMSetButtonImage(bPtr, icon2); if (icon2) WMReleasePixmap(icon2); color.red = 0xff; color.green = 0xff; color.blue = 0xff; color.alpha = 0; if (iconPath) { icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color); if (!icon) wwarning(_("could not load icon file %s"), iconPath); } else { icon = NULL; } WMSetButtonAltImage(bPtr, icon); if (icon) WMReleasePixmap(icon); if (iconPath) wfree(iconPath); } void AddSection(Panel * panel, char *iconFile) { WMButton *bPtr; assert(WPrefs.sectionCount < MAX_SECTIONS); bPtr = WMCreateCustomButton(WPrefs.buttonF, WBBStateLightMask | WBBStateChangeMask); WMResizeWidget(bPtr, 64, 64); WMMoveWidget(bPtr, WPrefs.sectionCount * 64, 0); WMSetButtonImagePosition(bPtr, WIPImageOnly); WMSetButtonAction(bPtr, changeSection, panel); WMHangData(bPtr, panel); WMSetBalloonTextForView(((PanelRec *) panel)->description, WMWidgetView(bPtr)); { char *t1, *t2; t1 = wstrdup(((PanelRec *) panel)->sectionName); t2 = strchr(t1, ' '); if (t2) { *t2 = 0; t2++; } SetButtonAlphaImage(WMWidgetScreen(bPtr), bPtr, iconFile, t1, t2); wfree(t1); } WMMapWidget(bPtr); WPrefs.sectionB[WPrefs.sectionCount] = bPtr; if (WPrefs.sectionCount > 0) { WMGroupButtons(WPrefs.sectionB[0], bPtr); } WPrefs.sectionCount++; WMResizeWidget(WPrefs.buttonF, WPrefs.sectionCount * 64, 64); } void Initialize(WMScreen * scr) { char **list; int i; char *path; list = RSupportedFileFormats(); for (i = 0; list[i] != NULL; i++) { if (strcmp(list[i], "TIFF") == 0) { TIFFOK = True; break; } } if (TIFFOK) path = WMPathForResourceOfType("WPrefs.tiff", NULL); else path = WMPathForResourceOfType("WPrefs.xpm", NULL); if (path) { RImage *tmp; tmp = RLoadImage(WMScreenRContext(scr), path, 0); if (!tmp) { wwarning(_("could not load image file %s:%s"), path, RMessageForError(RErrorCode)); } else { WMSetApplicationIconImage(scr, tmp); RReleaseImage(tmp); } wfree(path); } memset(&WPrefs, 0, sizeof(_WPrefs)); createMainWindow(scr); WMRealizeWidget(WPrefs.win); WMSetWindowMiniwindowImage(WPrefs.win, WMGetApplicationIconImage(scr)); WMMapWidget(WPrefs.win); XFlush(WMScreenDisplay(scr)); WMSetLabelText(WPrefs.statusL, _("Loading Window Maker configuration files...")); XFlush(WMScreenDisplay(scr)); loadConfigurations(scr, WPrefs.win); WMSetLabelText(WPrefs.statusL, _("Initializing configuration panels...")); InitFocus(scr, WPrefs.banner); InitWindowHandling(scr, WPrefs.banner); InitMenuPreferences(scr, WPrefs.banner); InitIcons(scr, WPrefs.banner); InitPreferences(scr, WPrefs.banner); InitPaths(scr, WPrefs.banner); InitWorkspace(scr, WPrefs.banner); InitConfigurations(scr, WPrefs.banner); InitMenu(scr, WPrefs.banner); #ifdef not_yet_fully_implemented InitKeyboardSettings(scr, WPrefs.banner); #endif InitKeyboardShortcuts(scr, WPrefs.banner); InitMouseSettings(scr, WPrefs.banner); InitAppearance(scr, WPrefs.banner); InitFontSimple(scr, WPrefs.banner); #ifdef not_yet_fully_implemented InitThemes(scr, WPrefs.banner); #endif InitExpert(scr, WPrefs.banner); WMRealizeWidget(WPrefs.scrollV); WMSetLabelText(WPrefs.statusL, ""); } WMWindow *GetWindow(Panel * panel) { return WPrefs.win; } static void loadConfigurations(WMScreen * scr, WMWindow * mainw) { WMPropList *db, *gdb; char *path; FILE *file; char buffer[1024]; char mbuf[1024]; int v1, v2, v3; path = wdefaultspathfordomain("WindowMaker"); WindowMakerDBPath = path; db = WMReadPropListFromFile(path); if (db) { if (!WMIsPLDictionary(db)) { WMReleasePropList(db); db = NULL; sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), path); WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL); } } else { sprintf(mbuf, _("Could not load Window Maker domain (%s) from defaults database."), path); WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL); } path = getenv("WMAKER_BIN_NAME"); if (!path) path = "wmaker"; { char *command; command = wstrconcat(path, " --version"); file = popen(command, "r"); wfree(command); } if (!file || !fgets(buffer, 1023, file)) { werror(_("could not extract version information from Window Maker")); wfatal(_("Make sure wmaker is in your search path.")); WMRunAlertPanel(scr, mainw, _("Error"), _ ("Could not extract version from Window Maker. Make sure it is correctly installed and is in your PATH environment variable."), _("OK"), NULL, NULL); exit(1); } if (file) pclose(file); if (sscanf(buffer, "Window Maker %i.%i.%i", &v1, &v2, &v3) != 3 && sscanf(buffer, "WindowMaker %i.%i.%i", &v1, &v2, &v3) != 3) { WMRunAlertPanel(scr, mainw, _("Error"), _("Could not extract version from Window Maker. " "Make sure it is correctly installed and the path " "where it installed is in the PATH environment " "variable."), _("OK"), NULL, NULL); exit(1); } if (v1 == 0 && (v2 < 18 || v3 < 0)) { sprintf(mbuf, _("WPrefs only supports Window Maker 0.18.0 or newer.\n" "The version installed is %i.%i.%i\n"), v1, v2, v3); WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL); exit(1); } if (v1 > 1 || (v1 == 1 && (v2 > 0))) { sprintf(mbuf, _ ("Window Maker %i.%i.%i, which is installed in your system, is not fully supported by this version of WPrefs."), v1, v2, v3); WMRunAlertPanel(scr, mainw, _("Warning"), mbuf, _("OK"), NULL, NULL); } { char *command; command = wstrconcat(path, " --global_defaults_path"); file = popen(command, "r"); wfree(command); } if (!file || !fgets(buffer, 1023, file)) { werror(_("could not run \"%s --global_defaults_path\"."), path); exit(1); } else { char *ptr; ptr = strchr(buffer, '\n'); if (ptr) *ptr = 0; strcat(buffer, "/WindowMaker"); } if (file) pclose(file); gdb = WMReadPropListFromFile(buffer); if (gdb) { if (!WMIsPLDictionary(gdb)) { WMReleasePropList(gdb); gdb = NULL; sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), buffer); WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL); } } else { sprintf(mbuf, _("Could not load global Window Maker domain (%s)."), buffer); WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL); } if (!db) { db = WMCreatePLDictionary(NULL, NULL); } if (!gdb) { gdb = WMCreatePLDictionary(NULL, NULL); } GlobalDB = gdb; WindowMakerDB = db; } WMPropList *GetObjectForKey(char *defaultName) { WMPropList *object = NULL; WMPropList *key = WMCreatePLString(defaultName); object = WMGetFromPLDictionary(WindowMakerDB, key); if (!object) object = WMGetFromPLDictionary(GlobalDB, key); WMReleasePropList(key); return object; } void SetObjectForKey(WMPropList * object, char *defaultName) { WMPropList *key = WMCreatePLString(defaultName); WMPutInPLDictionary(WindowMakerDB, key, object); WMReleasePropList(key); } void RemoveObjectForKey(char *defaultName) { WMPropList *key = WMCreatePLString(defaultName); WMRemoveFromPLDictionary(WindowMakerDB, key); WMReleasePropList(key); } char *GetStringForKey(char *defaultName) { WMPropList *val; val = GetObjectForKey(defaultName); if (!val) return NULL; if (!WMIsPLString(val)) return NULL; return WMGetFromPLString(val); } WMPropList *GetArrayForKey(char *defaultName) { WMPropList *val; val = GetObjectForKey(defaultName); if (!val) return NULL; if (!WMIsPLArray(val)) return NULL; return val; } WMPropList *GetDictionaryForKey(char *defaultName) { WMPropList *val; val = GetObjectForKey(defaultName); if (!val) return NULL; if (!WMIsPLDictionary(val)) return NULL; return val; } int GetIntegerForKey(char *defaultName) { WMPropList *val; char *str; int value; val = GetObjectForKey(defaultName); if (!val) return 0; if (!WMIsPLString(val)) return 0; str = WMGetFromPLString(val); if (!str) return 0; if (sscanf(str, "%i", &value) != 1) return 0; return value; } Bool GetBoolForKey(char *defaultName) { int value; char *str; str = GetStringForKey(defaultName); if (!str) return False; if (sscanf(str, "%i", &value) == 1 && value != 0) return True; if (strcasecmp(str, "YES") == 0) return True; if (strcasecmp(str, "Y") == 0) return True; return False; } void SetIntegerForKey(int value, char *defaultName) { WMPropList *object; char buffer[128]; sprintf(buffer, "%i", value); object = WMCreatePLString(buffer); SetObjectForKey(object, defaultName); WMReleasePropList(object); } void SetStringForKey(char *value, char *defaultName) { WMPropList *object; object = WMCreatePLString(value); SetObjectForKey(object, defaultName); WMReleasePropList(object); } void SetBoolForKey(Bool value, char *defaultName) { static WMPropList *yes = NULL, *no = NULL; if (!yes) { yes = WMCreatePLString("YES"); no = WMCreatePLString("NO"); } SetObjectForKey(value ? yes : no, defaultName); } void SetSpeedForKey(int speed, char *defaultName) { char *str; switch (speed) { case 0: str = "ultraslow"; break; case 1: str = "slow"; break; case 2: str = "medium"; break; case 3: str = "fast"; break; case 4: str = "ultrafast"; break; default: str = NULL; } if (str) SetStringForKey(str, defaultName); } int GetSpeedForKey(char *defaultName) { char *str; int i; str = GetStringForKey(defaultName); if (!str) return 2; if (strcasecmp(str, "ultraslow") == 0) i = 0; else if (strcasecmp(str, "slow") == 0) i = 1; else if (strcasecmp(str, "medium") == 0) i = 2; else if (strcasecmp(str, "fast") == 0) i = 3; else if (strcasecmp(str, "ultrafast") == 0) i = 4; else { wwarning(_("bad speed value for option %s; using default Medium"), defaultName); i = 2; } return i; }