Change to the linux kernel coding style
[wmaker-crm.git] / WPrefs.app / WPrefs.c
dissimilarity index 92%
index aabe1d9..5b956f1 100644 (file)
-/* 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 <assert.h>
-
-
-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;
-    char *msg = "Reconfigure";
-    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, True);
-
-
-    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;
-
-    for (i = 0; i <= strlen(msg); i++) {
-        ev.xclient.data.b[i] = msg[i];
-    }
-    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\n"), 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)) {
-        wsyserror(_("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)) {
-        wsyserror(_("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\n. Using default Medium"),
-                 defaultName);
-        i = 2;
-    }
-    return i;
-}
-
-
+/* 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 <assert.h>
+
+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;
+       char *msg = "Reconfigure";
+       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, True);
+
+       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;
+
+       for (i = 0; i <= strlen(msg); i++) {
+               ev.xclient.data.b[i] = msg[i];
+       }
+       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\n"), 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)) {
+               wsyserror(_("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)) {
+               wsyserror(_("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\n. Using default Medium"), defaultName);
+               i = 2;
+       }
+       return i;
+}