Introduced wrapper macros snew(), snewn() and sresize() for the
[u/mdw/putty] / windlg.c
index 2614457..6656c96 100644 (file)
--- a/windlg.c
+++ b/windlg.c
@@ -3,6 +3,8 @@
 #include <commdlg.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <limits.h>
+#include <assert.h>
 #include <ctype.h>
 #include <time.h>
 
@@ -11,6 +13,7 @@
 #include "winstuff.h"
 #include "win_res.h"
 #include "storage.h"
+#include "dialog.h"
 
 #ifdef MSVC4
 #define TVINSERTSTRUCT  TV_INSERTSTRUCT
 #define ICON_BIG        1
 #endif
 
+/*
+ * These are the various bits of data required to handle the
+ * portable-dialog stuff in the config box. Having them at file
+ * scope in here isn't too bad a place to put them; if we were ever
+ * to need more than one config box per process we could always
+ * shift them to a per-config-box structure stored in GWL_USERDATA.
+ */
+static struct controlbox *ctrlbox;
+/*
+ * ctrls_base holds the OK and Cancel buttons: the controls which
+ * are present in all dialog panels. ctrls_panel holds the ones
+ * which change from panel to panel.
+ */
+static struct winctrls ctrls_base, ctrls_panel;
+static struct dlgparam dp;
+
 static char **events = NULL;
 static int nevents = 0, negsize = 0;
 
-static int readytogo;
-static int sesslist_has_focus;
 static int requested_help;
 
-static struct prefslist cipherlist;
+extern Config cfg;                    /* defined in window.c */
+
+struct sesslist sesslist;             /* exported to window.c */
+
+#define PRINTER_DISABLED_STRING "None (printing disabled)"
 
 void force_normal(HWND hwnd)
 {
@@ -45,31 +66,6 @@ void force_normal(HWND hwnd)
     recurse = 0;
 }
 
-static void MyGetDlgItemInt(HWND hwnd, int id, int *result)
-{
-    BOOL ok;
-    int n;
-    n = GetDlgItemInt(hwnd, id, &ok, FALSE);
-    if (ok)
-       *result = n;
-}
-
-static void MyGetDlgItemFlt(HWND hwnd, int id, int *result, int scale)
-{
-    char text[80];
-    BOOL ok;
-    ok = GetDlgItemText(hwnd, id, text, sizeof(text) - 1);
-    if (ok && text[0])
-       *result = (int) (scale * atof(text));
-}
-
-static void MySetDlgItemFlt(HWND hwnd, int id, double value)
-{
-    char text[80];
-    sprintf(text, "%g", value);
-    SetDlgItemText(hwnd, id, text);
-}
-
 static int CALLBACK LogProc(HWND hwnd, UINT msg,
                            WPARAM wParam, LPARAM lParam)
 {
@@ -106,7 +102,7 @@ static int CALLBACK LogProc(HWND hwnd, UINT msg,
                    break;
                }
 
-               selitems = smalloc(selcount * sizeof(int));
+               selitems = snewn(selcount, int);
                if (selitems) {
                    int count = SendDlgItemMessage(hwnd, IDN_LIST,
                                                   LB_GETSELITEMS,
@@ -127,7 +123,7 @@ static int CALLBACK LogProc(HWND hwnd, UINT msg,
                        size +=
                            strlen(events[selitems[i]]) + sizeof(sel_nl);
 
-                   clipdata = smalloc(size);
+                   clipdata = snewn(size, char);
                    if (clipdata) {
                        char *p = clipdata;
                        for (i = 0; i < count; i++) {
@@ -138,7 +134,7 @@ static int CALLBACK LogProc(HWND hwnd, UINT msg,
                            memcpy(p, sel_nl, sizeof(sel_nl));
                            p += sizeof(sel_nl);
                        }
-                       write_aclip(clipdata, size, TRUE);
+                       write_aclip(NULL, clipdata, size, TRUE);
                        sfree(clipdata);
                    }
                    sfree(selitems);
@@ -225,976 +221,21 @@ static int CALLBACK NullDlgProc(HWND hwnd, UINT msg,
     return 0;
 }
 
-static char savedsession[2048];
-
-enum { IDCX_ABOUT =
-       IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue,
-
-    sessionpanelstart,
-    IDC_TITLE_SESSION,
-    IDC_BOX_SESSION1,
-    IDC_BOX_SESSION2,
-    IDC_BOX_SESSION3,
-    IDC_HOSTSTATIC,
-    IDC_HOST,
-    IDC_PORTSTATIC,
-    IDC_PORT,
-    IDC_PROTSTATIC,
-    IDC_PROTRAW,
-    IDC_PROTTELNET,
-    IDC_PROTRLOGIN,
-    IDC_PROTSSH,
-    IDC_SESSSTATIC,
-    IDC_SESSEDIT,
-    IDC_SESSLIST,
-    IDC_SESSLOAD,
-    IDC_SESSSAVE,
-    IDC_SESSDEL,
-    IDC_CLOSEEXIT,
-    IDC_COEALWAYS,
-    IDC_COENEVER,
-    IDC_COENORMAL,
-    sessionpanelend,
-
-    loggingpanelstart,
-    IDC_TITLE_LOGGING,
-    IDC_BOX_LOGGING1,
-    IDC_LSTATSTATIC,
-    IDC_LSTATOFF,
-    IDC_LSTATASCII,
-    IDC_LSTATRAW,
-    IDC_LSTATPACKET,
-    IDC_LGFSTATIC,
-    IDC_LGFEDIT,
-    IDC_LGFBUTTON,
-    IDC_LGFEXPLAIN,
-    IDC_LSTATXIST,
-    IDC_LSTATXOVR,
-    IDC_LSTATXAPN,
-    IDC_LSTATXASK,
-    loggingpanelend,
-
-    keyboardpanelstart,
-    IDC_TITLE_KEYBOARD,
-    IDC_BOX_KEYBOARD1,
-    IDC_BOX_KEYBOARD2,
-    IDC_BOX_KEYBOARD3,
-    IDC_DELSTATIC,
-    IDC_DEL008,
-    IDC_DEL127,
-    IDC_HOMESTATIC,
-    IDC_HOMETILDE,
-    IDC_HOMERXVT,
-    IDC_FUNCSTATIC,
-    IDC_FUNCTILDE,
-    IDC_FUNCLINUX,
-    IDC_FUNCXTERM,
-    IDC_FUNCVT400,
-    IDC_FUNCVT100P,
-    IDC_FUNCSCO,
-    IDC_KPSTATIC,
-    IDC_KPNORMAL,
-    IDC_KPAPPLIC,
-    IDC_KPNH,
-    IDC_NOAPPLICK,
-    IDC_NOAPPLICC,
-    IDC_CURSTATIC,
-    IDC_CURNORMAL,
-    IDC_CURAPPLIC,
-    IDC_COMPOSEKEY,
-    IDC_CTRLALTKEYS,
-    keyboardpanelend,
-
-    terminalpanelstart,
-    IDC_TITLE_TERMINAL,
-    IDC_BOX_TERMINAL1,
-    IDC_BOX_TERMINAL2,
-    IDC_WRAPMODE,
-    IDC_DECOM,
-    IDC_LFHASCR,
-    IDC_BCE,
-    IDC_BLINKTEXT,
-    IDC_ANSWERBACK,
-    IDC_ANSWEREDIT,
-    IDC_ECHOSTATIC,
-    IDC_ECHOBACKEND,
-    IDC_ECHOYES,
-    IDC_ECHONO,
-    IDC_EDITSTATIC,
-    IDC_EDITBACKEND,
-    IDC_EDITYES,
-    IDC_EDITNO,
-    terminalpanelend,
-
-    bellpanelstart,
-    IDC_TITLE_BELL,
-    IDC_BOX_BELL1,
-    IDC_BOX_BELL2,
-    IDC_BELLSTATIC,
-    IDC_BELL_DISABLED,
-    IDC_BELL_DEFAULT,
-    IDC_BELL_WAVEFILE,
-    IDC_BELL_VISUAL,
-    IDC_BELL_WAVESTATIC,
-    IDC_BELL_WAVEEDIT,
-    IDC_BELL_WAVEBROWSE,
-    IDC_B_IND_STATIC,
-    IDC_B_IND_DISABLED,
-    IDC_B_IND_FLASH,
-    IDC_B_IND_STEADY,
-    IDC_BELLOVL,
-    IDC_BELLOVLNSTATIC,
-    IDC_BELLOVLN,
-    IDC_BELLOVLTSTATIC,
-    IDC_BELLOVLT,
-    IDC_BELLOVLEXPLAIN,
-    IDC_BELLOVLSSTATIC,
-    IDC_BELLOVLS,
-    bellpanelend,
-
-    windowpanelstart,
-    IDC_TITLE_WINDOW,
-    IDC_BOX_WINDOW1,
-    IDC_BOX_WINDOW2,
-    IDC_BOX_WINDOW3,
-    IDC_ROWSSTATIC,
-    IDC_ROWSEDIT,
-    IDC_COLSSTATIC,
-    IDC_COLSEDIT,
-    IDC_RESIZESTATIC,
-    IDC_RESIZETERM,
-    IDC_RESIZEFONT,
-    IDC_RESIZENONE,
-    IDC_RESIZEEITHER,
-    IDC_SCROLLBAR,
-    IDC_SCROLLBARFULLSCREEN,
-    IDC_SAVESTATIC,
-    IDC_SAVEEDIT,
-    IDC_SCROLLKEY,
-    IDC_SCROLLDISP,
-    windowpanelend,
-
-    behaviourpanelstart,
-    IDC_TITLE_BEHAVIOUR,
-    IDC_BOX_BEHAVIOUR1,
-    IDC_CLOSEWARN,
-    IDC_ALTF4,
-    IDC_ALTSPACE,
-    IDC_ALTONLY,
-    IDC_ALWAYSONTOP,
-    IDC_FULLSCREENONALTENTER,
-    behaviourpanelend,
-
-    appearancepanelstart,
-    IDC_TITLE_APPEARANCE,
-    IDC_BOX_APPEARANCE1,
-    IDC_BOX_APPEARANCE2,
-    IDC_BOX_APPEARANCE3,
-    IDC_BOX_APPEARANCE4,
-    IDC_BOX_APPEARANCE5,
-    IDC_CURSORSTATIC,
-    IDC_CURBLOCK,
-    IDC_CURUNDER,
-    IDC_CURVERT,
-    IDC_BLINKCUR,
-    IDC_FONTSTATIC,
-    IDC_CHOOSEFONT,
-    IDC_WINTITLE,
-    IDC_WINEDIT,
-    IDC_WINNAME,
-    IDC_HIDEMOUSE,
-    IDC_SUNKENEDGE,
-    IDC_WINBSTATIC,
-    IDC_WINBEDIT,
-    appearancepanelend,
-
-    connectionpanelstart,
-    IDC_TITLE_CONNECTION,
-    IDC_BOX_CONNECTION1,
-    IDC_BOX_CONNECTION2,
-    IDC_BOX_CONNECTION3,
-    IDC_TTSTATIC,
-    IDC_TTEDIT,
-    IDC_LOGSTATIC,
-    IDC_LOGEDIT,
-    IDC_PINGSTATIC,
-    IDC_PINGEDIT,
-    IDC_NODELAY,
-    connectionpanelend,
-
-    telnetpanelstart,
-    IDC_TITLE_TELNET,
-    IDC_BOX_TELNET1,
-    IDC_BOX_TELNET2,
-    IDC_TSSTATIC,
-    IDC_TSEDIT,
-    IDC_ENVSTATIC,
-    IDC_VARSTATIC,
-    IDC_VAREDIT,
-    IDC_VALSTATIC,
-    IDC_VALEDIT,
-    IDC_ENVLIST,
-    IDC_ENVADD,
-    IDC_ENVREMOVE,
-    IDC_EMSTATIC,
-    IDC_EMBSD,
-    IDC_EMRFC,
-    IDC_ACTSTATIC,
-    IDC_TPASSIVE,
-    IDC_TACTIVE,
-    IDC_TELNETKEY,
-    IDC_TELNETRET,
-    telnetpanelend,
-
-    rloginpanelstart,
-    IDC_TITLE_RLOGIN,
-    IDC_BOX_RLOGIN1,
-    IDC_BOX_RLOGIN2,
-    IDC_R_TSSTATIC,
-    IDC_R_TSEDIT,
-    IDC_RLLUSERSTATIC,
-    IDC_RLLUSEREDIT,
-    rloginpanelend,
-
-    sshpanelstart,
-    IDC_TITLE_SSH,
-    IDC_BOX_SSH1,
-    IDC_BOX_SSH2,
-    IDC_BOX_SSH3,
-    IDC_NOPTY,
-    IDC_BOX_SSHCIPHER,
-    IDC_CIPHERSTATIC2,
-    IDC_CIPHERLIST,
-    IDC_CIPHERUP,
-    IDC_CIPHERDN,
-    IDC_BUGGYMAC,
-    IDC_SSH2DES,
-    IDC_SSHPROTSTATIC,
-    IDC_SSHPROT1,
-    IDC_SSHPROT2,
-    IDC_CMDSTATIC,
-    IDC_CMDEDIT,
-    IDC_COMPRESS,
-    sshpanelend,
-
-    sshauthpanelstart,
-    IDC_TITLE_SSHAUTH,
-    IDC_BOX_SSHAUTH1,
-    IDC_BOX_SSHAUTH2,
-    IDC_PKSTATIC,
-    IDC_PKEDIT,
-    IDC_PKBUTTON,
-    IDC_AGENTFWD,
-    IDC_CHANGEUSER,
-    IDC_AUTHTIS,
-    IDC_AUTHKI,
-    sshauthpanelend,
-
-    selectionpanelstart,
-    IDC_TITLE_SELECTION,
-    IDC_BOX_SELECTION1,
-    IDC_BOX_SELECTION2,
-    IDC_BOX_SELECTION3,
-    IDC_MBSTATIC,
-    IDC_MBWINDOWS,
-    IDC_MBXTERM,
-    IDC_MOUSEOVERRIDE,
-    IDC_SELTYPESTATIC,
-    IDC_SELTYPELEX,
-    IDC_SELTYPERECT,
-    IDC_CCSTATIC,
-    IDC_CCLIST,
-    IDC_CCSET,
-    IDC_CCSTATIC2,
-    IDC_CCEDIT,
-    IDC_RAWCNP,
-    IDC_RTFPASTE,
-    selectionpanelend,
-
-    colourspanelstart,
-    IDC_TITLE_COLOURS,
-    IDC_BOX_COLOURS1,
-    IDC_BOX_COLOURS2,
-    IDC_BOLDCOLOUR,
-    IDC_PALETTE,
-    IDC_COLOURSTATIC,
-    IDC_COLOURLIST,
-    IDC_RSTATIC,
-    IDC_GSTATIC,
-    IDC_BSTATIC,
-    IDC_RVALUE,
-    IDC_GVALUE,
-    IDC_BVALUE,
-    IDC_CHANGE,
-    colourspanelend,
-
-    translationpanelstart,
-    IDC_TITLE_TRANSLATION,
-    IDC_BOX_TRANSLATION1,
-    IDC_BOX_TRANSLATION2,
-    IDC_BOX_TRANSLATION3,
-    IDC_CODEPAGESTATIC,
-    IDC_CODEPAGE,
-    IDC_CAPSLOCKCYR,
-    IDC_VTSTATIC,
-    IDC_VTXWINDOWS,
-    IDC_VTOEMANSI,
-    IDC_VTOEMONLY,
-    IDC_VTPOORMAN,
-    IDC_VTUNICODE,
-    translationpanelend,
-
-    tunnelspanelstart,
-    IDC_TITLE_TUNNELS,
-    IDC_BOX_TUNNELS1,
-    IDC_BOX_TUNNELS2,
-    IDC_X11_FORWARD,
-    IDC_X11_DISPSTATIC,
-    IDC_X11_DISPLAY,
-    IDC_LPORT_ALL,
-    IDC_RPORT_ALL,
-    IDC_PFWDSTATIC,
-    IDC_PFWDSTATIC2,
-    IDC_PFWDREMOVE,
-    IDC_PFWDLIST,
-    IDC_PFWDADD,
-    IDC_SPORTSTATIC,
-    IDC_SPORTEDIT,
-    IDC_DPORTSTATIC,
-    IDC_DPORTEDIT,
-    IDC_PFWDLOCAL,
-    IDC_PFWDREMOTE,
-
-    tunnelspanelend,
-
-    controlendvalue
+enum {
+    IDCX_ABOUT = IDC_ABOUT,
+    IDCX_TVSTATIC,
+    IDCX_TREEVIEW,
+    IDCX_STDBASE,
+    IDCX_PANELBASE = IDCX_STDBASE + 32
 };
 
-static const char *const colours[] = {
-    "Default Foreground", "Default Bold Foreground",
-    "Default Background", "Default Bold Background",
-    "Cursor Text", "Cursor Colour",
-    "ANSI Black", "ANSI Black Bold",
-    "ANSI Red", "ANSI Red Bold",
-    "ANSI Green", "ANSI Green Bold",
-    "ANSI Yellow", "ANSI Yellow Bold",
-    "ANSI Blue", "ANSI Blue Bold",
-    "ANSI Magenta", "ANSI Magenta Bold",
-    "ANSI Cyan", "ANSI Cyan Bold",
-    "ANSI White", "ANSI White Bold"
-};
-static const int permcolour[] = {
-    TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
-    TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
-    TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
-};
-
-static void fmtfont(char *buf)
-{
-    sprintf(buf, "Font: %s, ", cfg.font);
-    if (cfg.fontisbold)
-       strcat(buf, "bold, ");
-    if (cfg.fontheight == 0)
-       strcat(buf, "default height");
-    else
-       sprintf(buf + strlen(buf), "%d-point",
-               (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight));
-}
-
-char *help_context_cmd(int id)
-{
-    switch (id) {
-      case IDC_HOSTSTATIC:
-      case IDC_HOST:
-      case IDC_PORTSTATIC:
-      case IDC_PORT:
-      case IDC_PROTSTATIC:
-      case IDC_PROTRAW:
-      case IDC_PROTTELNET:
-      case IDC_PROTRLOGIN:
-      case IDC_PROTSSH:
-        return "JI(`',`session.hostname')";
-      case IDC_SESSSTATIC:
-      case IDC_SESSEDIT:
-      case IDC_SESSLIST:
-      case IDC_SESSLOAD:
-      case IDC_SESSSAVE:
-      case IDC_SESSDEL:
-        return "JI(`',`session.saved')";
-      case IDC_CLOSEEXIT:
-      case IDC_COEALWAYS:
-      case IDC_COENEVER:
-      case IDC_COENORMAL:
-        return "JI(`',`session.coe')";
-      case IDC_LSTATSTATIC:
-      case IDC_LSTATOFF:
-      case IDC_LSTATASCII:
-      case IDC_LSTATRAW:
-      case IDC_LSTATPACKET:
-        return "JI(`',`logging.main')";
-      case IDC_LGFSTATIC:
-      case IDC_LGFEDIT:
-      case IDC_LGFBUTTON:
-      case IDC_LGFEXPLAIN:
-        return "JI(`',`logging.filename')";
-      case IDC_LSTATXIST:
-      case IDC_LSTATXOVR:
-      case IDC_LSTATXAPN:
-      case IDC_LSTATXASK:
-        return "JI(`',`logging.exists')";
-
-      case IDC_DELSTATIC:
-      case IDC_DEL008:
-      case IDC_DEL127:
-        return "JI(`',`keyboard.backspace')";
-      case IDC_HOMESTATIC:
-      case IDC_HOMETILDE:
-      case IDC_HOMERXVT:
-        return "JI(`',`keyboard.homeend')";
-      case IDC_FUNCSTATIC:
-      case IDC_FUNCTILDE:
-      case IDC_FUNCLINUX:
-      case IDC_FUNCXTERM:
-      case IDC_FUNCVT400:
-      case IDC_FUNCVT100P:
-      case IDC_FUNCSCO:
-        return "JI(`',`keyboard.funkeys')";
-      case IDC_KPSTATIC:
-      case IDC_KPNORMAL:
-      case IDC_KPAPPLIC:
-      case IDC_NOAPPLICK:
-        return "JI(`',`keyboard.appkeypad')";
-      case IDC_NOAPPLICC:
-      case IDC_CURSTATIC:
-      case IDC_CURNORMAL:
-      case IDC_CURAPPLIC:
-        return "JI(`',`keyboard.appcursor')";
-      case IDC_KPNH:
-        return "JI(`',`keyboard.nethack')";
-      case IDC_COMPOSEKEY:
-        return "JI(`',`keyboard.compose')";
-      case IDC_CTRLALTKEYS:
-        return "JI(`',`keyboard.ctrlalt')";
-
-      case IDC_WRAPMODE:
-        return "JI(`',`terminal.autowrap')";
-      case IDC_DECOM:
-        return "JI(`',`terminal.decom')";
-      case IDC_LFHASCR:
-        return "JI(`',`terminal.lfhascr')";
-      case IDC_BCE:
-        return "JI(`',`terminal.bce')";
-      case IDC_BLINKTEXT:
-        return "JI(`',`terminal.blink')";
-      case IDC_ANSWERBACK:
-      case IDC_ANSWEREDIT:
-        return "JI(`',`terminal.answerback')";
-      case IDC_ECHOSTATIC:
-      case IDC_ECHOBACKEND:
-      case IDC_ECHOYES:
-      case IDC_ECHONO:
-        return "JI(`',`terminal.localecho')";
-      case IDC_EDITSTATIC:
-      case IDC_EDITBACKEND:
-      case IDC_EDITYES:
-      case IDC_EDITNO:
-        return "JI(`',`terminal.localedit')";
-
-      case IDC_BELLSTATIC:
-      case IDC_BELL_DISABLED:
-      case IDC_BELL_DEFAULT:
-      case IDC_BELL_WAVEFILE:
-      case IDC_BELL_VISUAL:
-      case IDC_BELL_WAVESTATIC:
-      case IDC_BELL_WAVEEDIT:
-      case IDC_BELL_WAVEBROWSE:
-        return "JI(`',`bell.style')";
-      case IDC_B_IND_STATIC:
-      case IDC_B_IND_DISABLED:
-      case IDC_B_IND_FLASH:
-      case IDC_B_IND_STEADY:
-        return "JI(`',`bell.taskbar')";
-      case IDC_BELLOVL:
-      case IDC_BELLOVLNSTATIC:
-      case IDC_BELLOVLN:
-      case IDC_BELLOVLTSTATIC:
-      case IDC_BELLOVLT:
-      case IDC_BELLOVLEXPLAIN:
-      case IDC_BELLOVLSSTATIC:
-      case IDC_BELLOVLS:
-        return "JI(`',`bell.overload')";
-
-      case IDC_ROWSSTATIC:
-      case IDC_ROWSEDIT:
-      case IDC_COLSSTATIC:
-      case IDC_COLSEDIT:
-        return "JI(`',`window.size')";
-      case IDC_RESIZESTATIC:
-      case IDC_RESIZETERM:
-      case IDC_RESIZEFONT:
-      case IDC_RESIZENONE:
-      case IDC_RESIZEEITHER:
-        return "JI(`',`window.resize')";
-      case IDC_SCROLLBAR:
-      case IDC_SCROLLBARFULLSCREEN:
-      case IDC_SAVESTATIC:
-      case IDC_SAVEEDIT:
-      case IDC_SCROLLKEY:
-      case IDC_SCROLLDISP:
-        return "JI(`',`window.scrollback')";
-
-      case IDC_CLOSEWARN:
-        return "JI(`',`behaviour.closewarn')";
-      case IDC_ALTF4:
-        return "JI(`',`behaviour.altf4')";
-      case IDC_ALTSPACE:
-        return "JI(`',`behaviour.altspace')";
-      case IDC_ALTONLY:
-        return "JI(`',`behaviour.altonly')";
-      case IDC_ALWAYSONTOP:
-        return "JI(`',`behaviour.alwaysontop')";
-      case IDC_FULLSCREENONALTENTER:
-        return "JI(`',`behaviour.altenter')";
-
-      case IDC_CURSORSTATIC:
-      case IDC_CURBLOCK:
-      case IDC_CURUNDER:
-      case IDC_CURVERT:
-      case IDC_BLINKCUR:
-        return "JI(`',`appearance.cursor')";
-      case IDC_FONTSTATIC:
-      case IDC_CHOOSEFONT:
-        return "JI(`',`appearance.font')";
-      case IDC_WINTITLE:
-      case IDC_WINEDIT:
-      case IDC_WINNAME:
-        return "JI(`',`appearance.title')";
-      case IDC_HIDEMOUSE:
-        return "JI(`',`appearance.hidemouse')";
-      case IDC_SUNKENEDGE:
-      case IDC_WINBSTATIC:
-      case IDC_WINBEDIT:
-        return "JI(`',`appearance.border')";
-
-      case IDC_TTSTATIC:
-      case IDC_TTEDIT:
-        return "JI(`',`connection.termtype')";
-      case IDC_LOGSTATIC:
-      case IDC_LOGEDIT:
-        return "JI(`',`connection.username')";
-      case IDC_PINGSTATIC:
-      case IDC_PINGEDIT:
-        return "JI(`',`connection.keepalive')";
-      case IDC_NODELAY:
-        return "JI(`',`connection.nodelay')";
-
-      case IDC_TSSTATIC:
-      case IDC_TSEDIT:
-        return "JI(`',`telnet.termspeed')";
-      case IDC_ENVSTATIC:
-      case IDC_VARSTATIC:
-      case IDC_VAREDIT:
-      case IDC_VALSTATIC:
-      case IDC_VALEDIT:
-      case IDC_ENVLIST:
-      case IDC_ENVADD:
-      case IDC_ENVREMOVE:
-        return "JI(`',`telnet.environ')";
-      case IDC_EMSTATIC:
-      case IDC_EMBSD:
-      case IDC_EMRFC:
-        return "JI(`',`telnet.oldenviron')";
-      case IDC_ACTSTATIC:
-      case IDC_TPASSIVE:
-      case IDC_TACTIVE:
-        return "JI(`',`telnet.passive')";
-      case IDC_TELNETKEY:
-        return "JI(`',`telnet.specialkeys')";
-      case IDC_TELNETRET:
-        return "JI(`',`telnet.newline')";
-
-      case IDC_R_TSSTATIC:
-      case IDC_R_TSEDIT:
-        return "JI(`',`rlogin.termspeed')";
-      case IDC_RLLUSERSTATIC:
-      case IDC_RLLUSEREDIT:
-        return "JI(`',`rlogin.localuser')";
-
-      case IDC_NOPTY:
-        return "JI(`',`ssh.nopty')";
-      case IDC_CIPHERSTATIC2:
-      case IDC_CIPHERLIST:
-      case IDC_CIPHERUP:
-      case IDC_CIPHERDN:
-      case IDC_SSH2DES:
-        return "JI(`',`ssh.ciphers')";
-      case IDC_BUGGYMAC:
-        return "JI(`',`ssh.buggymac')";
-      case IDC_SSHPROTSTATIC:
-      case IDC_SSHPROT1:
-      case IDC_SSHPROT2:
-        return "JI(`',`ssh.protocol')";
-      case IDC_CMDSTATIC:
-      case IDC_CMDEDIT:
-        return "JI(`',`ssh.command')";
-      case IDC_COMPRESS:
-        return "JI(`',`ssh.compress')";
-
-      case IDC_PKSTATIC:
-      case IDC_PKEDIT:
-      case IDC_PKBUTTON:
-        return "JI(`',`ssh.auth.privkey')";
-      case IDC_AGENTFWD:
-        return "JI(`',`ssh.auth.agentfwd')";
-      case IDC_CHANGEUSER:
-        return "JI(`',`ssh.auth.changeuser')";
-      case IDC_AUTHTIS:
-        return "JI(`',`ssh.auth.tis')";
-      case IDC_AUTHKI:
-        return "JI(`',`ssh.auth.ki')";
-
-      case IDC_MBSTATIC:
-      case IDC_MBWINDOWS:
-      case IDC_MBXTERM:
-        return "JI(`',`selection.buttons')";
-      case IDC_MOUSEOVERRIDE:
-        return "JI(`',`selection.shiftdrag')";
-      case IDC_SELTYPESTATIC:
-      case IDC_SELTYPELEX:
-      case IDC_SELTYPERECT:
-        return "JI(`',`selection.rect')";
-      case IDC_CCSTATIC:
-      case IDC_CCLIST:
-      case IDC_CCSET:
-      case IDC_CCSTATIC2:
-      case IDC_CCEDIT:
-        return "JI(`',`selection.charclasses')";
-      case IDC_RAWCNP:
-        return "JI(`',`selection.linedraw')";
-      case IDC_RTFPASTE:
-        return "JI(`',`selection.rtf')";
-
-      case IDC_BOLDCOLOUR:
-        return "JI(`',`colours.bold')";
-      case IDC_PALETTE:
-        return "JI(`',`colours.logpal')";
-      case IDC_COLOURSTATIC:
-      case IDC_COLOURLIST:
-      case IDC_RSTATIC:
-      case IDC_GSTATIC:
-      case IDC_BSTATIC:
-      case IDC_RVALUE:
-      case IDC_GVALUE:
-      case IDC_BVALUE:
-      case IDC_CHANGE:
-        return "JI(`',`colours.config')";
-
-      case IDC_CODEPAGESTATIC:
-      case IDC_CODEPAGE:
-        return "JI(`',`translation.codepage')";
-      case IDC_CAPSLOCKCYR:
-        return "JI(`',`translation.cyrillic')";
-      case IDC_VTSTATIC:
-      case IDC_VTXWINDOWS:
-      case IDC_VTOEMANSI:
-      case IDC_VTOEMONLY:
-      case IDC_VTPOORMAN:
-      case IDC_VTUNICODE:
-        return "JI(`',`translation.linedraw')";
-
-      case IDC_X11_FORWARD:
-      case IDC_X11_DISPSTATIC:
-      case IDC_X11_DISPLAY:
-        return "JI(`',`ssh.tunnels.x11')";
-      case IDC_PFWDSTATIC:
-      case IDC_PFWDSTATIC2:
-      case IDC_PFWDREMOVE:
-      case IDC_PFWDLIST:
-      case IDC_PFWDADD:
-      case IDC_SPORTSTATIC:
-      case IDC_SPORTEDIT:
-      case IDC_DPORTSTATIC:
-      case IDC_DPORTEDIT:
-      case IDC_PFWDLOCAL:
-      case IDC_PFWDREMOTE:
-        return "JI(`',`ssh.tunnels.portfwd')";
-      case IDC_LPORT_ALL:
-      case IDC_RPORT_ALL:
-        return "JI(`',`ssh.tunnels.portfwd.localhost')";
-
-      default:
-        return NULL;
-    }
-}
-
-/* 2nd arg: NZ => don't redraw session list (use when loading
- * a new session) */
-static void init_dlg_ctrls(HWND hwnd, int keepsess)
-{
-    int i;
-    char fontstatic[256];
-
-    SetDlgItemText(hwnd, IDC_HOST, cfg.host);
-    SetDlgItemText(hwnd, IDC_SESSEDIT, savedsession);
-    if (!keepsess) {
-       int i, n;
-       n = SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_GETCOUNT, 0, 0);
-       for (i = n; i-- > 0;)
-           SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_DELETESTRING, i, 0);
-       for (i = 0; i < nsessions; i++)
-           SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_ADDSTRING,
-                              0, (LPARAM) (sessions[i]));
-    }
-    SetDlgItemInt(hwnd, IDC_PORT, cfg.port, FALSE);
-    CheckRadioButton(hwnd, IDC_PROTRAW, IDC_PROTSSH,
-                    cfg.protocol == PROT_SSH ? IDC_PROTSSH :
-                    cfg.protocol == PROT_TELNET ? IDC_PROTTELNET :
-                    cfg.protocol ==
-                    PROT_RLOGIN ? IDC_PROTRLOGIN : IDC_PROTRAW);
-    SetDlgItemInt(hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
-    CheckDlgButton(hwnd, IDC_NODELAY, cfg.tcp_nodelay);
-
-    CheckRadioButton(hwnd, IDC_DEL008, IDC_DEL127,
-                    cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
-    CheckRadioButton(hwnd, IDC_HOMETILDE, IDC_HOMERXVT,
-                    cfg.rxvt_homeend ? IDC_HOMERXVT : IDC_HOMETILDE);
-    CheckRadioButton(hwnd, IDC_FUNCTILDE, IDC_FUNCSCO,
-                    cfg.funky_type == 0 ? IDC_FUNCTILDE :
-                    cfg.funky_type == 1 ? IDC_FUNCLINUX :
-                    cfg.funky_type == 2 ? IDC_FUNCXTERM :
-                    cfg.funky_type == 3 ? IDC_FUNCVT400 :
-                    cfg.funky_type == 4 ? IDC_FUNCVT100P :
-                    cfg.funky_type == 5 ? IDC_FUNCSCO : IDC_FUNCTILDE);
-    CheckDlgButton(hwnd, IDC_NOAPPLICC, cfg.no_applic_c);
-    CheckDlgButton(hwnd, IDC_NOAPPLICK, cfg.no_applic_k);
-    CheckRadioButton(hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
-                    cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
-    CheckRadioButton(hwnd, IDC_KPNORMAL, IDC_KPNH,
-                    cfg.nethack_keypad ? IDC_KPNH :
-                    cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL);
-    CheckDlgButton(hwnd, IDC_ALTF4, cfg.alt_f4);
-    CheckDlgButton(hwnd, IDC_ALTSPACE, cfg.alt_space);
-    CheckDlgButton(hwnd, IDC_ALTONLY, cfg.alt_only);
-    CheckDlgButton(hwnd, IDC_COMPOSEKEY, cfg.compose_key);
-    CheckDlgButton(hwnd, IDC_CTRLALTKEYS, cfg.ctrlaltkeys);
-    CheckDlgButton(hwnd, IDC_TELNETKEY, cfg.telnet_keyboard);
-    CheckDlgButton(hwnd, IDC_TELNETRET, cfg.telnet_newline);
-    CheckRadioButton(hwnd, IDC_ECHOBACKEND, IDC_ECHONO,
-                    cfg.localecho == LD_BACKEND ? IDC_ECHOBACKEND :
-                    cfg.localecho == LD_YES ? IDC_ECHOYES : IDC_ECHONO);
-    CheckRadioButton(hwnd, IDC_EDITBACKEND, IDC_EDITNO,
-                    cfg.localedit == LD_BACKEND ? IDC_EDITBACKEND :
-                    cfg.localedit == LD_YES ? IDC_EDITYES : IDC_EDITNO);
-    SetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback);
-    CheckDlgButton(hwnd, IDC_ALWAYSONTOP, cfg.alwaysontop);
-    CheckDlgButton(hwnd, IDC_FULLSCREENONALTENTER, cfg.fullscreenonaltenter);
-    CheckDlgButton(hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
-    CheckDlgButton(hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp);
-
-    CheckDlgButton(hwnd, IDC_WRAPMODE, cfg.wrap_mode);
-    CheckDlgButton(hwnd, IDC_DECOM, cfg.dec_om);
-    CheckDlgButton(hwnd, IDC_LFHASCR, cfg.lfhascr);
-    SetDlgItemInt(hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
-    SetDlgItemInt(hwnd, IDC_COLSEDIT, cfg.width, FALSE);
-    SetDlgItemInt(hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
-    fmtfont(fontstatic);
-    SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
-    CheckRadioButton(hwnd, IDC_BELL_DISABLED, IDC_BELL_VISUAL,
-                    cfg.beep == BELL_DISABLED ? IDC_BELL_DISABLED :
-                    cfg.beep == BELL_DEFAULT ? IDC_BELL_DEFAULT :
-                    cfg.beep == BELL_WAVEFILE ? IDC_BELL_WAVEFILE :
-                    cfg.beep ==
-                    BELL_VISUAL ? IDC_BELL_VISUAL : IDC_BELL_DEFAULT);
-    CheckRadioButton(hwnd, IDC_B_IND_DISABLED, IDC_B_IND_STEADY,
-                    cfg.beep_ind ==
-                    B_IND_DISABLED ? IDC_B_IND_DISABLED : cfg.beep_ind ==
-                    B_IND_FLASH ? IDC_B_IND_FLASH : cfg.beep_ind ==
-                    B_IND_STEADY ? IDC_B_IND_STEADY : IDC_B_IND_DISABLED);
-    SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT, cfg.bell_wavefile);
-    CheckDlgButton(hwnd, IDC_BELLOVL, cfg.bellovl);
-    SetDlgItemInt(hwnd, IDC_BELLOVLN, cfg.bellovl_n, FALSE);
-    MySetDlgItemFlt(hwnd, IDC_BELLOVLT, cfg.bellovl_t / 1000.0);
-    MySetDlgItemFlt(hwnd, IDC_BELLOVLS, cfg.bellovl_s / 1000.0);
-
-    CheckDlgButton(hwnd, IDC_BCE, cfg.bce);
-    CheckDlgButton(hwnd, IDC_BLINKTEXT, cfg.blinktext);
-
-    SetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle);
-    CheckDlgButton(hwnd, IDC_WINNAME, cfg.win_name_always);
-    CheckDlgButton(hwnd, IDC_HIDEMOUSE, cfg.hide_mouseptr);
-    CheckDlgButton(hwnd, IDC_SUNKENEDGE, cfg.sunken_edge);
-    SetDlgItemInt(hwnd, IDC_WINBEDIT, cfg.window_border, FALSE);
-    CheckRadioButton(hwnd, IDC_CURBLOCK, IDC_CURVERT,
-                    cfg.cursor_type == 0 ? IDC_CURBLOCK :
-                    cfg.cursor_type == 1 ? IDC_CURUNDER : IDC_CURVERT);
-    CheckDlgButton(hwnd, IDC_BLINKCUR, cfg.blink_cur);
-    CheckDlgButton(hwnd, IDC_SCROLLBAR, cfg.scrollbar);
-    CheckDlgButton(hwnd, IDC_SCROLLBARFULLSCREEN, cfg.scrollbar_in_fullscreen);
-    CheckRadioButton(hwnd, IDC_RESIZETERM, IDC_RESIZEEITHER,
-                    cfg.resize_action == RESIZE_TERM ? IDC_RESIZETERM :
-                    cfg.resize_action == RESIZE_FONT ? IDC_RESIZEFONT :
-                    cfg.resize_action == RESIZE_EITHER ? IDC_RESIZEEITHER :
-                    IDC_RESIZENONE);
-    CheckRadioButton(hwnd, IDC_COEALWAYS, IDC_COENORMAL,
-                    cfg.close_on_exit == COE_NORMAL ? IDC_COENORMAL :
-                    cfg.close_on_exit ==
-                    COE_NEVER ? IDC_COENEVER : IDC_COEALWAYS);
-    CheckDlgButton(hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
-
-    SetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype);
-    SetDlgItemText(hwnd, IDC_TSEDIT, cfg.termspeed);
-    SetDlgItemText(hwnd, IDC_R_TSEDIT, cfg.termspeed);
-    SetDlgItemText(hwnd, IDC_RLLUSEREDIT, cfg.localusername);
-    SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
-    SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
-    CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATPACKET,
-                    cfg.logtype == LGTYP_NONE ? IDC_LSTATOFF :
-                    cfg.logtype == LGTYP_ASCII ? IDC_LSTATASCII :
-                    cfg.logtype == LGTYP_DEBUG ? IDC_LSTATRAW :
-                    IDC_LSTATPACKET);
-    CheckRadioButton(hwnd, IDC_LSTATXOVR, IDC_LSTATXASK,
-                    cfg.logxfovr == LGXF_OVR ? IDC_LSTATXOVR :
-                    cfg.logxfovr == LGXF_ASK ? IDC_LSTATXASK :
-                    IDC_LSTATXAPN);
-    {
-       char *p = cfg.environmt;
-       SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_RESETCONTENT, 0, 0);
-       while (*p) {
-           SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
-                              (LPARAM) p);
-           p += strlen(p) + 1;
-       }
-       p = cfg.portfwd;
-       while (*p) {
-           SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_ADDSTRING, 0,
-                              (LPARAM) p);
-           p += strlen(p) + 1;
-       }
-    }
-    CheckRadioButton(hwnd, IDC_EMBSD, IDC_EMRFC,
-                    cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
-    CheckRadioButton(hwnd, IDC_TPASSIVE, IDC_TACTIVE,
-                    cfg.passive_telnet ? IDC_TPASSIVE : IDC_TACTIVE);
-
-    SetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype);
-    SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
-    CheckDlgButton(hwnd, IDC_NOPTY, cfg.nopty);
-    CheckDlgButton(hwnd, IDC_COMPRESS, cfg.compression);
-    CheckDlgButton(hwnd, IDC_BUGGYMAC, cfg.buggymac);
-    CheckDlgButton(hwnd, IDC_SSH2DES, cfg.ssh2_des_cbc);
-    CheckDlgButton(hwnd, IDC_AGENTFWD, cfg.agentfwd);
-    CheckDlgButton(hwnd, IDC_CHANGEUSER, cfg.change_username);
-    CheckRadioButton(hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
-                    cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
-    CheckDlgButton(hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
-    CheckDlgButton(hwnd, IDC_AUTHKI, cfg.try_ki_auth);
-    SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile);
-    SetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd);
-
-    {
-       int i;
-       static const struct { char *s; int c; } ciphers[] = {
-           { "3DES",                   CIPHER_3DES },
-           { "Blowfish",               CIPHER_BLOWFISH },
-           { "DES",                    CIPHER_DES },
-           { "AES (SSH 2 only)",       CIPHER_AES },
-           { "-- warn below here --",  CIPHER_WARN }
-       };
-
-       /* Set up the "selected ciphers" box. */
-       /* (cipherlist assumed to contain all ciphers) */
-       SendDlgItemMessage(hwnd, IDC_CIPHERLIST, LB_RESETCONTENT, 0, 0);
-       for (i = 0; i < CIPHER_MAX; i++) {
-           int c = cfg.ssh_cipherlist[i];
-           int j, pos;
-           char *cstr = NULL;
-           for (j = 0; j < (sizeof ciphers) / (sizeof ciphers[0]); j++) {
-               if (ciphers[j].c == c) {
-                   cstr = ciphers[j].s;
-                   break;
-               }
-           }
-           pos = SendDlgItemMessage(hwnd, IDC_CIPHERLIST, LB_ADDSTRING,
-                                    0, (LPARAM) cstr);
-           SendDlgItemMessage(hwnd, IDC_CIPHERLIST, LB_SETITEMDATA,
-                              pos, (LPARAM) c);
-       }
-
-    }
-
-    CheckRadioButton(hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
-                    cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
-    CheckRadioButton(hwnd, IDC_SELTYPELEX, IDC_SELTYPERECT,
-                    cfg.rect_select == 0 ? IDC_SELTYPELEX : IDC_SELTYPERECT);
-    CheckDlgButton(hwnd, IDC_MOUSEOVERRIDE, cfg.mouse_override);
-    CheckDlgButton(hwnd, IDC_RAWCNP, cfg.rawcnp);
-    CheckDlgButton(hwnd, IDC_RTFPASTE, cfg.rtf_paste);
-    {
-       static int tabs[4] = { 25, 61, 96, 128 };
-       SendDlgItemMessage(hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
-                          (LPARAM) tabs);
-    }
-    for (i = 0; i < 128; i++) {
-       char str[100];
-       sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
-               (i >= 0x21 && i != 0x7F) ? i : ' ', cfg.wordness[i]);
-       SendDlgItemMessage(hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
-                          (LPARAM) str);
-    }
-
-    CheckDlgButton(hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
-    CheckDlgButton(hwnd, IDC_PALETTE, cfg.try_palette);
-    {
-       int i, n;
-       n = SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
-       for (i = n; i-- > 0;)
-           SendDlgItemMessage(hwnd, IDC_COLOURLIST,
-                              LB_DELETESTRING, i, 0);
-       for (i = 0; i < 22; i++)
-           if (cfg.bold_colour || permcolour[i])
-               SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
-                                  (LPARAM) colours[i]);
-    }
-    SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
-    SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
-    SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
-    SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
-
-    {
-       int i;
-       char *cp;
-       strcpy(cfg.line_codepage, cp_name(decode_codepage(cfg.line_codepage)));
-       SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_RESETCONTENT, 0, 0);
-       CheckDlgButton (hwnd, IDC_CAPSLOCKCYR, cfg.xlat_capslockcyr);
-       for (i = 0; (cp = cp_enumerate(i)) != NULL; i++) {
-           SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_ADDSTRING,
-                              0, (LPARAM) cp);
-       }
-       SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
-    }
-    
-    CheckRadioButton(hwnd, IDC_VTXWINDOWS, IDC_VTUNICODE,
-                    cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
-                    cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
-                    cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
-                    cfg.vtmode == VT_UNICODE ? IDC_VTUNICODE :
-                    IDC_VTPOORMAN);
-
-    CheckDlgButton(hwnd, IDC_X11_FORWARD, cfg.x11_forward);
-    SetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display);
-
-    CheckDlgButton(hwnd, IDC_LPORT_ALL, cfg.lport_acceptall);
-    CheckDlgButton(hwnd, IDC_RPORT_ALL, cfg.rport_acceptall);
-    CheckRadioButton(hwnd, IDC_PFWDLOCAL, IDC_PFWDREMOTE, IDC_PFWDLOCAL);
-}
-
 struct treeview_faff {
     HWND treeview;
     HTREEITEM lastat[4];
 };
 
 static HTREEITEM treeview_insert(struct treeview_faff *faff,
-                                int level, char *text)
+                                int level, char *text, char *path)
 {
     TVINSERTSTRUCT ins;
     int i;
@@ -1206,8 +247,10 @@ static HTREEITEM treeview_insert(struct treeview_faff *faff,
 #else
 #define INSITEM item
 #endif
-    ins.INSITEM.mask = TVIF_TEXT;
+    ins.INSITEM.mask = TVIF_TEXT | TVIF_PARAM;
     ins.INSITEM.pszText = text;
+    ins.INSITEM.cchTextMax = strlen(text)+1;
+    ins.INSITEM.lParam = (LPARAM)path;
     newitem = TreeView_InsertItem(faff->treeview, &ins);
     if (level > 0)
        TreeView_Expand(faff->treeview, faff->lastat[level - 1],
@@ -1221,578 +264,50 @@ static HTREEITEM treeview_insert(struct treeview_faff *faff,
 /*
  * Create the panelfuls of controls in the configuration box.
  */
-static void create_controls(HWND hwnd, int dlgtype, int panel)
+static void create_controls(HWND hwnd, char *path)
 {
-    if (panel == sessionpanelstart) {
-       /* The Session panel. Accelerators used: [acgo] nprtih elsd w */
-       struct ctlpos cp;
-       ctlposinit(&cp, hwnd, 80, 3, 13);
-       bartitle(&cp, "Basic options for your PuTTY session",
-                IDC_TITLE_SESSION);
-       if (dlgtype == 0) {
-           beginbox(&cp, "Specify your connection by host name or IP address",
-                    IDC_BOX_SESSION1);
-           multiedit(&cp,
-                     "Host &Name (or IP address)",
-                     IDC_HOSTSTATIC, IDC_HOST, 75,
-                     "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
-           if (backends[3].backend == NULL) {
-               /* this is PuTTYtel, so only three protocols available */
-               radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3,
-                         "&Raw", IDC_PROTRAW,
-                         "&Telnet", IDC_PROTTELNET,
-                         "Rlog&in", IDC_PROTRLOGIN, NULL);
-           } else {
-               radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
-                         "&Raw", IDC_PROTRAW,
-                         "&Telnet", IDC_PROTTELNET,
-                         "Rlog&in", IDC_PROTRLOGIN,
-#ifdef FWHACK
-                         "SS&H/hack",
-#else
-                         "SS&H",
-#endif
-                         IDC_PROTSSH, NULL);
-           }
-           endbox(&cp);
-           beginbox(&cp, "Load, save or delete a stored session",
-                    IDC_BOX_SESSION2);
-           sesssaver(&cp, "Sav&ed Sessions",
-                     IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
-                     "&Load", IDC_SESSLOAD,
-                     "&Save", IDC_SESSSAVE, "&Delete", IDC_SESSDEL, NULL);
-           endbox(&cp);
-       }
-       beginbox(&cp, NULL, IDC_BOX_SESSION3);
-       radioline(&cp, "Close &window on exit:", IDC_CLOSEEXIT, 4,
-                 "Always", IDC_COEALWAYS,
-                 "Never", IDC_COENEVER,
-                 "Only on clean exit", IDC_COENORMAL, NULL);
-       endbox(&cp);
-    }
+    struct ctlpos cp;
+    int index;
+    int base_id;
+    struct winctrls *wc;
 
-    if (panel == loggingpanelstart) {
-       /* The Logging panel. Accelerators used: [acgo] tplsfwe */
-       struct ctlpos cp;
-       ctlposinit(&cp, hwnd, 80, 3, 13);
-       bartitle(&cp, "Options controlling session logging",
-                IDC_TITLE_LOGGING);
-       beginbox(&cp, NULL, IDC_BOX_LOGGING1);
-       radiobig(&cp,
-                "Session logging:", IDC_LSTATSTATIC,
-                "Logging &turned off completely", IDC_LSTATOFF,
-                "Log &printable output only", IDC_LSTATASCII,
-                "&Log all session output", IDC_LSTATRAW,
-                "Log &SSH packet data", IDC_LSTATPACKET,
-                NULL);
-       editbutton(&cp, "Log &file name:",
-                  IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...",
-                  IDC_LGFBUTTON);
-       statictext(&cp, "(Log file name can contain &&Y, &&M, &&D for date,"
-                  " &&T for time, and &&H for host name)", 2, IDC_LGFEXPLAIN);
-       radiobig(&cp,
-                "What to do if the log file already &exists:",
-                IDC_LSTATXIST, "Always overwrite it", IDC_LSTATXOVR,
-                "Always append to the end of it", IDC_LSTATXAPN,
-                "Ask the user every time", IDC_LSTATXASK, NULL);
-       endbox(&cp);
-    }
-
-    if (panel == terminalpanelstart) {
-       /* The Terminal panel. Accelerators used: [acgo] wdlen hts */
-       struct ctlpos cp;
-       ctlposinit(&cp, hwnd, 80, 3, 13);
-       bartitle(&cp, "Options controlling the terminal emulation",
-                IDC_TITLE_TERMINAL);
-       beginbox(&cp, "Set various terminal options", IDC_BOX_TERMINAL1);
-       checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
-       checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
-       checkbox(&cp, "Implicit CR in every &LF", IDC_LFHASCR);
-       checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
-       checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
-       multiedit(&cp,
-                 "An&swerback to ^E:", IDC_ANSWERBACK,
-                 IDC_ANSWEREDIT, 100, NULL);
-       endbox(&cp);
-
-       beginbox(&cp, "Line discipline options", IDC_BOX_TERMINAL2);
-       radioline(&cp, "Local ec&ho:", IDC_ECHOSTATIC, 3,
-                 "Auto", IDC_ECHOBACKEND,
-                 "Force on", IDC_ECHOYES, "Force off", IDC_ECHONO, NULL);
-       radioline(&cp, "Local line edi&ting:", IDC_EDITSTATIC, 3,
-                 "Auto", IDC_EDITBACKEND,
-                 "Force on", IDC_EDITYES, "Force off", IDC_EDITNO, NULL);
-       endbox(&cp);
-    }
-
-    if (panel == bellpanelstart) {
-       /* The Bell panel. Accelerators used: [acgo] bdsm wit */
-       struct ctlpos cp;
-       ctlposinit(&cp, hwnd, 80, 3, 13);
-       bartitle(&cp, "Options controlling the terminal bell",
-                IDC_TITLE_BELL);
-       beginbox(&cp, "Set the style of bell", IDC_BOX_BELL1);
-       radiobig(&cp,
-                "Action to happen when a &bell occurs:", IDC_BELLSTATIC,
-                "None (bell disabled)", IDC_BELL_DISABLED,
-                "Play Windows Default Sound", IDC_BELL_DEFAULT,
-                "Play a custom sound file", IDC_BELL_WAVEFILE,
-                "Visual bell (flash window)", IDC_BELL_VISUAL, NULL);
-       editbutton(&cp, "Custom sound file to play as a bell:",
-                  IDC_BELL_WAVESTATIC, IDC_BELL_WAVEEDIT,
-                  "Bro&wse...", IDC_BELL_WAVEBROWSE);
-       radioline(&cp, "Taskbar/caption &indication on bell:",
-                 IDC_B_IND_STATIC, 3, "Disabled", IDC_B_IND_DISABLED,
-                 "Flashing", IDC_B_IND_FLASH, "Steady", IDC_B_IND_STEADY,
-                 NULL);
-       endbox(&cp);
-       beginbox(&cp, "Control the bell overload behaviour",
-                IDC_BOX_BELL2);
-       checkbox(&cp, "Bell is temporarily &disabled when over-used",
-                IDC_BELLOVL);
-       staticedit(&cp, "Over-use means this &many bells...",
-                  IDC_BELLOVLNSTATIC, IDC_BELLOVLN, 20);
-       staticedit(&cp, "... in &this many seconds",
-                  IDC_BELLOVLTSTATIC, IDC_BELLOVLT, 20);
-       statictext(&cp,
-                  "The bell is re-enabled after a few seconds of silence.",
-                  1, IDC_BELLOVLEXPLAIN);
-       staticedit(&cp, "Seconds of &silence required", IDC_BELLOVLSSTATIC,
-                  IDC_BELLOVLS, 20);
-       endbox(&cp);
-    }
-
-    if (panel == keyboardpanelstart) {
-       /* The Keyboard panel. Accelerators used: [acgo] bhf ruyntd */
-       struct ctlpos cp;
-       ctlposinit(&cp, hwnd, 80, 3, 13);
-       bartitle(&cp, "Options controlling the effects of keys",
-                IDC_TITLE_KEYBOARD);
-       beginbox(&cp, "Change the sequences sent by:", IDC_BOX_KEYBOARD1);
-       radioline(&cp, "The &Backspace key", IDC_DELSTATIC, 2,
-                 "Control-H", IDC_DEL008,
-                 "Control-? (127)", IDC_DEL127, NULL);
-       radioline(&cp, "The &Home and End keys", IDC_HOMESTATIC, 2,
-                 "Standard", IDC_HOMETILDE, "rxvt", IDC_HOMERXVT, NULL);
-       radioline(&cp, "The &Function keys and keypad", IDC_FUNCSTATIC, 3,
-                 "ESC[n~", IDC_FUNCTILDE,
-                 "Linux", IDC_FUNCLINUX,
-                 "Xterm R6", IDC_FUNCXTERM,
-                 "VT400", IDC_FUNCVT400,
-                 "VT100+", IDC_FUNCVT100P, "SCO", IDC_FUNCSCO, NULL);
-       endbox(&cp);
-       beginbox(&cp, "Application keypad settings:", IDC_BOX_KEYBOARD2);
-       checkbox(&cp,
-                "Application c&ursor keys totally disabled",
-                IDC_NOAPPLICC);
-       radioline(&cp, "Initial state of cu&rsor keys:", IDC_CURSTATIC, 2,
-                 "Normal", IDC_CURNORMAL,
-                 "Application", IDC_CURAPPLIC, NULL);
-       checkbox(&cp,
-                "Application ke&ypad keys totally disabled",
-                IDC_NOAPPLICK);
-       radioline(&cp, "Initial state of &numeric keypad:", IDC_KPSTATIC,
-                 3, "Normal", IDC_KPNORMAL, "Application", IDC_KPAPPLIC,
-                 "NetHack", IDC_KPNH, NULL);
-       endbox(&cp);
-       beginbox(&cp, "Enable extra keyboard features:",
-                IDC_BOX_KEYBOARD3);
-       checkbox(&cp, "AltGr ac&ts as Compose key", IDC_COMPOSEKEY);
-       checkbox(&cp, "Control-Alt is &different from AltGr",
-                IDC_CTRLALTKEYS);
-       endbox(&cp);
-    }
-
-    if (panel == windowpanelstart) {
-       /* The Window panel. Accelerators used: [acgo] rmz sdikp */
-       struct ctlpos cp;
-       ctlposinit(&cp, hwnd, 80, 3, 13);
-       bartitle(&cp, "Options controlling PuTTY's window",
-                IDC_TITLE_WINDOW);
-       beginbox(&cp, "Set the size of the window", IDC_BOX_WINDOW1);
-       multiedit(&cp,
-                 "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
-                 "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50, NULL);
-       radiobig(&cp, "When window is resi&zed:", IDC_RESIZESTATIC,
-                "Change the number of rows and columns", IDC_RESIZETERM,
-                "Change the size of the font", IDC_RESIZEFONT,
-                "Change font size only when maximised", IDC_RESIZEEITHER,
-                "Forbid resizing completely", IDC_RESIZENONE, NULL);
-       endbox(&cp);
-       beginbox(&cp, "Control the scrollback in the window",
-                IDC_BOX_WINDOW2);
-       staticedit(&cp, "Lines of &scrollback",
-                  IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
-       checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
-       checkbox(&cp, "D&isplay scrollbar in full screen mode", IDC_SCROLLBARFULLSCREEN);
-       checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
-       checkbox(&cp, "Reset scrollback on dis&play activity",
-                IDC_SCROLLDISP);
-       endbox(&cp);
-    }
-
-    if (panel == appearancepanelstart) {
-       /* The Appearance panel. Accelerators used: [acgo] luvb h ti p s */
-       struct ctlpos cp;
-       ctlposinit(&cp, hwnd, 80, 3, 13);
-       bartitle(&cp, "Configure the appearance of PuTTY's window",
-                IDC_TITLE_APPEARANCE);
-       beginbox(&cp, "Adjust the use of the cursor", IDC_BOX_APPEARANCE1);
-       radioline(&cp, "Cursor appearance:", IDC_CURSORSTATIC, 3,
-                 "B&lock", IDC_CURBLOCK,
-                 "&Underline", IDC_CURUNDER,
-                 "&Vertical line", IDC_CURVERT, NULL);
-       checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
-       endbox(&cp);
-       beginbox(&cp, "Set the font used in the terminal window",
-                IDC_BOX_APPEARANCE2);
-       staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
-       endbox(&cp);
-       beginbox(&cp, "Adjust the use of the window title",
-                IDC_BOX_APPEARANCE3);
-       multiedit(&cp,
-                 "Window &title:", IDC_WINTITLE, IDC_WINEDIT, 100, NULL);
-       checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
-       endbox(&cp);
-       beginbox(&cp, "Adjust the use of the mouse pointer",
-                IDC_BOX_APPEARANCE4);
-       checkbox(&cp, "Hide mouse &pointer when typing in window",
-                IDC_HIDEMOUSE);
-       endbox(&cp);
-       beginbox(&cp, "Adjust the window border", IDC_BOX_APPEARANCE5);
-       checkbox(&cp, "&Sunken-edge border (slightly thicker)",
-                IDC_SUNKENEDGE);
-       staticedit(&cp, "Gap between text and window edge",
-                  IDC_WINBSTATIC, IDC_WINBEDIT, 20);
-       endbox(&cp);
-    }
-
-    if (panel == behaviourpanelstart) {
-       /* The Behaviour panel. Accelerators used: [acgo] w4yltf */
-       struct ctlpos cp;
-       ctlposinit(&cp, hwnd, 80, 3, 13);
-       bartitle(&cp, "Configure the behaviour of PuTTY's window",
-                IDC_TITLE_WINDOW);
-       beginbox(&cp, NULL, IDC_BOX_BEHAVIOUR1);
-       checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
-       checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
-       checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
-       checkbox(&cp, "System menu appears on A&LT alone", IDC_ALTONLY);
-       checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP);
-       checkbox(&cp, "&Full screen on Alt-Enter", IDC_FULLSCREENONALTENTER);
-       endbox(&cp);
-    }
-
-    if (panel == translationpanelstart) {
-       /* The Translation panel. Accelerators used: [acgo] rxbepus */
-       struct ctlpos cp;
-       ctlposinit(&cp, hwnd, 80, 3, 13);
-       bartitle(&cp, "Options controlling character set translation",
-                IDC_TITLE_TRANSLATION);
-       beginbox(&cp, "Character set translation on received data",
-                IDC_BOX_TRANSLATION1);
-       combobox(&cp, "&Received data assumed to be in which character set:",
-                IDC_CODEPAGESTATIC, IDC_CODEPAGE);
-       endbox(&cp);
-        beginbox(&cp, "Enable character set translation on input data",
-                 IDC_BOX_TRANSLATION2);
-        checkbox(&cp, "Cap&s Lock acts as Cyrillic switch",
-                 IDC_CAPSLOCKCYR);
-        endbox(&cp);
-       beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
-                IDC_BOX_TRANSLATION3);
-       radiobig(&cp,
-                "Handling of line drawing characters:", IDC_VTSTATIC,
-                "Font has &XWindows encoding", IDC_VTXWINDOWS,
-                "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
-                "Use font in O&EM mode only", IDC_VTOEMONLY,
-                "&Poor man's line drawing (" "+" ", " "-" " and " "|" ")",
-                IDC_VTPOORMAN, "&Unicode mode", IDC_VTUNICODE, NULL);
-       endbox(&cp);
-    }
-
-    if (panel == selectionpanelstart) {
-       /* The Selection panel. Accelerators used: [acgo] df wxp hst nr */
-       struct ctlpos cp;
-       ctlposinit(&cp, hwnd, 80, 3, 13);
-       bartitle(&cp, "Options controlling copy and paste",
-                IDC_TITLE_SELECTION);
-       beginbox(&cp, "Translation of pasted characters",
-                IDC_BOX_SELECTION1);
-       checkbox(&cp,
-                "&Don't translate line drawing chars into +, - and |",
-                IDC_RAWCNP);
-       checkbox(&cp,
-                "Paste to clipboard in RT&F as well as plain text",
-                IDC_RTFPASTE);
-       endbox(&cp);
-       beginbox(&cp, "Control which mouse button does which thing",
-                IDC_BOX_SELECTION2);
-       radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
-                "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
-                "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
-                NULL);
-       checkbox(&cp,
-                "Shift overrides a&pplication's use of mouse",
-                IDC_MOUSEOVERRIDE);
-        radioline(&cp,
-                  "Default selection mode (Alt+drag does the other one):",
-                  IDC_SELTYPESTATIC, 2,
-                 "&Normal", IDC_SELTYPELEX,
-                 "&Rectangular block", IDC_SELTYPERECT, NULL);
-       endbox(&cp);
-       beginbox(&cp, "Control the select-one-word-at-a-time mode",
-                IDC_BOX_SELECTION3);
-       charclass(&cp, "C&haracter classes:", IDC_CCSTATIC, IDC_CCLIST,
-                 "&Set", IDC_CCSET, IDC_CCEDIT,
-                 "&to class", IDC_CCSTATIC2);
-       endbox(&cp);
-    }
-
-    if (panel == colourspanelstart) {
-       /* The Colours panel. Accelerators used: [acgo] blum */
-       struct ctlpos cp;
-       ctlposinit(&cp, hwnd, 80, 3, 13);
-       bartitle(&cp, "Options controlling use of colours",
-                IDC_TITLE_COLOURS);
-       beginbox(&cp, "General options for colour usage",
-                IDC_BOX_COLOURS1);
-       checkbox(&cp, "&Bolded text is a different colour",
-                IDC_BOLDCOLOUR);
-       checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
-       endbox(&cp);
-       beginbox(&cp, "Adjust the precise colours PuTTY displays",
-                IDC_BOX_COLOURS2);
-       colouredit(&cp, "Select a colo&ur and then click to modify it:",
-                  IDC_COLOURSTATIC, IDC_COLOURLIST,
-                  "&Modify...", IDC_CHANGE,
-                  "Red:", IDC_RSTATIC, IDC_RVALUE,
-                  "Green:", IDC_GSTATIC, IDC_GVALUE,
-                  "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
-       endbox(&cp);
-    }
-
-    if (panel == connectionpanelstart) {
-       /* The Connection panel. Accelerators used: [acgo] tukn */
-       struct ctlpos cp;
-       ctlposinit(&cp, hwnd, 80, 3, 13);
-       bartitle(&cp, "Options controlling the connection",
-                IDC_TITLE_CONNECTION);
-       if (dlgtype == 0) {
-           beginbox(&cp, "Data to send to the server",
-                    IDC_BOX_CONNECTION1);
-           staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC,
-                      IDC_TTEDIT, 50);
-           staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC,
-                      IDC_LOGEDIT, 50);
-           endbox(&cp);
-       } else {
-           beginbox(&cp, "Adjust telnet session.", IDC_BOX_CONNECTION1);
-           checkbox(&cp, "Keyboard sends telnet Backspace and Interrupt",
-                    IDC_TELNETKEY);
-           checkbox(&cp, "Return key sends telnet New Line instead of ^M",
-                    IDC_TELNETRET);
-           endbox(&cp);
-       }
-       beginbox(&cp, "Sending of null packets to keep session active",
-                IDC_BOX_CONNECTION2);
-       staticedit(&cp, "Seconds between &keepalives (0 to turn off)",
-                  IDC_PINGSTATIC, IDC_PINGEDIT, 20);
-       endbox(&cp);
-       if (dlgtype == 0) {
-           beginbox(&cp, "Low-level TCP connection options",
-                    IDC_BOX_CONNECTION3);
-           checkbox(&cp, "Disable &Nagle's algorithm (TCP_NODELAY option)",
-                    IDC_NODELAY);
-           endbox(&cp);
-       }
-    }
-
-    if (panel == telnetpanelstart) {
-       /* The Telnet panel. Accelerators used: [acgo] svldr bftk */
-       struct ctlpos cp;
-       ctlposinit(&cp, hwnd, 80, 3, 13);
-       if (dlgtype == 0) {
-           bartitle(&cp, "Options controlling Telnet connections",
-                    IDC_TITLE_TELNET);
-           beginbox(&cp, "Data to send to the server", IDC_BOX_TELNET1);
-           staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC,
-                      IDC_TSEDIT, 50);
-           envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
-                     "&Variable", IDC_VARSTATIC, IDC_VAREDIT, "Va&lue",
-                     IDC_VALSTATIC, IDC_VALEDIT, IDC_ENVLIST, "A&dd",
-                     IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
-           endbox(&cp);
-           beginbox(&cp, "Telnet protocol adjustments", IDC_BOX_TELNET2);
-           radioline(&cp, "Handling of OLD_ENVIRON ambiguity:",
-                     IDC_EMSTATIC, 2, "&BSD (commonplace)", IDC_EMBSD,
-                     "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
-           radioline(&cp, "&Telnet negotiation mode:", IDC_ACTSTATIC, 2,
-                     "Passive", IDC_TPASSIVE, "Active",
-                     IDC_TACTIVE, NULL);
-           checkbox(&cp, "&Keyboard sends telnet Backspace and Interrupt",
-                    IDC_TELNETKEY);
-           checkbox(&cp, "Return key sends telnet New Line instead of ^M",
-                    IDC_TELNETRET);
-           endbox(&cp);
-       }
-    }
-
-    if (panel == rloginpanelstart) {
-       /* The Rlogin panel. Accelerators used: [acgo] sl */
-       struct ctlpos cp;
-       ctlposinit(&cp, hwnd, 80, 3, 13);
-       if (dlgtype == 0) {
-           bartitle(&cp, "Options controlling Rlogin connections",
-                    IDC_TITLE_RLOGIN);
-           beginbox(&cp, "Data to send to the server", IDC_BOX_RLOGIN1);
-           staticedit(&cp, "Terminal-&speed string", IDC_R_TSSTATIC,
-                      IDC_R_TSEDIT, 50);
-           staticedit(&cp, "&Local username:", IDC_RLLUSERSTATIC,
-                      IDC_RLLUSEREDIT, 50);
-           endbox(&cp);
-       }
-    }
-
-    if (panel == sshpanelstart) {
-       /* The SSH panel. Accelerators used: [acgo] r pe12i sd */
-       struct ctlpos cp;
-       ctlposinit(&cp, hwnd, 80, 3, 13);
-       if (dlgtype == 0) {
-           bartitle(&cp, "Options controlling SSH connections",
-                    IDC_TITLE_SSH);
-           beginbox(&cp, "Data to send to the server", IDC_BOX_SSH1);
-           multiedit(&cp,
-                     "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
-                     NULL);
-           endbox(&cp);
-           beginbox(&cp, "Protocol options", IDC_BOX_SSH2);
-           checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
-           checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
-           radioline(&cp, "Preferred SSH protocol version:",
-                     IDC_SSHPROTSTATIC, 2,
-                     "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
-           checkbox(&cp, "&Imitate SSH 2 MAC bug in commercial <= v2.3.x",
-                    IDC_BUGGYMAC);
-           endbox(&cp);
-           beginbox(&cp, "Encryption options", IDC_BOX_SSH3);
-           prefslist(&cipherlist, &cp, "Encryption cipher &selection policy:",
-                     IDC_CIPHERSTATIC2, IDC_CIPHERLIST, IDC_CIPHERUP,
-                     IDC_CIPHERDN);
-           checkbox(&cp, "Enable non-standard use of single-&DES in SSH 2",
-                    IDC_SSH2DES);
-           endbox(&cp);
-       }
-    }
-
-    if (panel == sshauthpanelstart) {
-       /* The SSH authentication panel. Accelerators used: [acgo] m fkiuw */
-       struct ctlpos cp;
+    if (!path[0]) {
+       /*
+        * Here we must create the basic standard controls.
+        */
+       ctlposinit(&cp, hwnd, 3, 3, 235);
+       wc = &ctrls_base;
+       base_id = IDCX_STDBASE;
+    } else {
+       /*
+        * Otherwise, we're creating the controls for a particular
+        * panel.
+        */
        ctlposinit(&cp, hwnd, 80, 3, 13);
-       if (dlgtype == 0) {
-           bartitle(&cp, "Options controlling SSH authentication",
-                    IDC_TITLE_SSHAUTH);
-           beginbox(&cp, "Authentication methods",
-                    IDC_BOX_SSHAUTH1);
-           checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication (SSH1)",
-                    IDC_AUTHTIS);
-           checkbox(&cp, "Attempt \"keyboard-&interactive\" authentication"
-                    " (SSH2)", IDC_AUTHKI);
-           endbox(&cp);
-           beginbox(&cp, "Authentication parameters",
-                    IDC_BOX_SSHAUTH2);
-           checkbox(&cp, "Allow agent &forwarding", IDC_AGENTFWD);
-           checkbox(&cp, "Allow attempted changes of &username in SSH2",
-                    IDC_CHANGEUSER);
-           editbutton(&cp, "Private &key file for authentication:",
-                      IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...",
-                      IDC_PKBUTTON);
-           endbox(&cp);
-       }
+       wc = &ctrls_panel;
+       base_id = IDCX_PANELBASE;
     }
 
-    if (panel == tunnelspanelstart) {
-       /* The Tunnels panel. Accelerators used: [acgo] deilmrsthx */
-       struct ctlpos cp;
-       ctlposinit(&cp, hwnd, 80, 3, 13);
-       if (dlgtype == 0) {
-           bartitle(&cp, "Options controlling SSH tunnelling",
-                    IDC_TITLE_TUNNELS);
-           beginbox(&cp, "X11 forwarding", IDC_BOX_TUNNELS1);
-           checkbox(&cp, "&Enable X11 forwarding", IDC_X11_FORWARD);
-           multiedit(&cp, "&X display location", IDC_X11_DISPSTATIC,
-                     IDC_X11_DISPLAY, 50, NULL);
-           endbox(&cp);
-           beginbox(&cp, "Port forwarding", IDC_BOX_TUNNELS2);
-           checkbox(&cp, "Local ports accept connections from o&ther hosts",
-                    IDC_LPORT_ALL);
-           checkbox(&cp, "Remote ports do t&he same (SSH v2 only)",
-                    IDC_RPORT_ALL);
-           staticbtn(&cp, "Forwarded ports:", IDC_PFWDSTATIC,
-                     "&Remove", IDC_PFWDREMOVE);
-           fwdsetter(&cp, IDC_PFWDLIST,
-                     "Add new forwarded port:", IDC_PFWDSTATIC2,
-                     "&Source port", IDC_SPORTSTATIC, IDC_SPORTEDIT,
-                     "Dest&ination", IDC_DPORTSTATIC, IDC_DPORTEDIT,
-                     "A&dd", IDC_PFWDADD);
-           bareradioline(&cp, 2,
-                         "&Local", IDC_PFWDLOCAL,
-                         "Re&mote", IDC_PFWDREMOTE, NULL);
-           endbox(&cp);
-
-       }
+    for (index=-1; (index = ctrl_find_path(ctrlbox, path, index)) >= 0 ;) {
+       struct controlset *s = ctrlbox->ctrlsets[index];
+       winctrl_layout(&dp, wc, &cp, s, &base_id);
     }
 }
 
-/* 
- * Helper function to load the session selected in SESSLIST
- * if any, as this is done in more than one place in
- * GenericMainDlgProc(). 0 => failure.
- */
-static int load_selected_session(HWND hwnd)
-{
-    int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
-                              LB_GETCURSEL, 0, 0);
-    int isdef;
-    if (n == LB_ERR) {
-       MessageBeep(0);
-       return 0;
-    }
-    isdef = !strcmp(sessions[n], "Default Settings");
-    load_settings(sessions[n], !isdef, &cfg);
-    init_dlg_ctrls(hwnd, TRUE);
-    if (!isdef)
-       SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
-    else
-       SetDlgItemText(hwnd, IDC_SESSEDIT, "");
-    /* Restore the selection, which will have been clobbered by
-     * SESSEDIT handling. */
-    SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL, n, 0);
-    return 1;
-}
-
 /*
  * This function is the configuration box.
  */
-static int GenericMainDlgProc(HWND hwnd, UINT msg,
-                             WPARAM wParam, LPARAM lParam, int dlgtype)
+static int CALLBACK GenericMainDlgProc(HWND hwnd, UINT msg,
+                                      WPARAM wParam, LPARAM lParam)
 {
     HWND hw, treeview;
     struct treeview_faff tvfaff;
-    HTREEITEM hsession;
-    OPENFILENAME of;
-    char filename[sizeof(cfg.keyfile)];
-    CHOOSEFONT cf;
-    LOGFONT lf;
-    char fontstatic[256];
-    char portname[32];
-    struct servent *service;
-    int i;
-    static UINT draglistmsg = WM_NULL;
+    int ret;
 
     switch (msg) {
       case WM_INITDIALOG:
-       readytogo = 0;
+       dp.hwnd = hwnd;
+       create_controls(hwnd, "");     /* Open and Cancel buttons etc */
        SetWindowLong(hwnd, GWL_USERDATA, 0);
         if (help_path)
             SetWindowLong(hwnd, GWL_EXSTYLE,
@@ -1864,49 +379,73 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
        /*
         * Set up the tree view contents.
         */
-       hsession = treeview_insert(&tvfaff, 0, "Session");
-       treeview_insert(&tvfaff, 1, "Logging");
-       treeview_insert(&tvfaff, 0, "Terminal");
-       treeview_insert(&tvfaff, 1, "Keyboard");
-       treeview_insert(&tvfaff, 1, "Bell");
-       treeview_insert(&tvfaff, 0, "Window");
-       treeview_insert(&tvfaff, 1, "Appearance");
-       treeview_insert(&tvfaff, 1, "Behaviour");
-       treeview_insert(&tvfaff, 1, "Translation");
-       treeview_insert(&tvfaff, 1, "Selection");
-       treeview_insert(&tvfaff, 1, "Colours");
-       treeview_insert(&tvfaff, 0, "Connection");
-       if (dlgtype == 0) {
-           treeview_insert(&tvfaff, 1, "Telnet");
-           treeview_insert(&tvfaff, 1, "Rlogin");
-           if (backends[3].backend != NULL) {
-               treeview_insert(&tvfaff, 1, "SSH");
-               /* XXX long name is ugly */
-               /* XXX make it closed by default? */
-               treeview_insert(&tvfaff, 2, "Auth");
-               treeview_insert(&tvfaff, 2, "Tunnels");
+       {
+           HTREEITEM hfirst = NULL;
+           int i;
+           char *path = NULL;
+
+           for (i = 0; i < ctrlbox->nctrlsets; i++) {
+               struct controlset *s = ctrlbox->ctrlsets[i];
+               HTREEITEM item;
+               int j;
+               char *c;
+
+               if (!s->pathname[0])
+                   continue;
+               j = path ? ctrl_path_compare(s->pathname, path) : 0;
+               if (j == INT_MAX)
+                   continue;          /* same path, nothing to add to tree */
+
+               /*
+                * We expect never to find an implicit path
+                * component. For example, we expect never to see
+                * A/B/C followed by A/D/E, because that would
+                * _implicitly_ create A/D. All our path prefixes
+                * are expected to contain actual controls and be
+                * selectable in the treeview; so we would expect
+                * to see A/D _explicitly_ before encountering
+                * A/D/E.
+                */
+               assert(j == ctrl_path_elements(s->pathname) - 1);
+
+               c = strrchr(s->pathname, '/');
+               if (!c)
+                       c = s->pathname;
+               else
+                       c++;
+
+               item = treeview_insert(&tvfaff, j, c, s->pathname);
+               if (!hfirst)
+                   hfirst = item;
+
+               path = s->pathname;
            }
-       }
 
-       /*
-        * Put the treeview selection on to the Session panel. This
-        * should also cause creation of the relevant controls.
-        */
-       TreeView_SelectItem(treeview, hsession);
+           /*
+            * Put the treeview selection on to the Session panel.
+            * This should also cause creation of the relevant
+            * controls.
+            */
+           TreeView_SelectItem(treeview, hfirst);
+       }
 
        /*
         * Set focus into the first available control.
         */
        {
-           HWND ctl;
-           ctl = GetDlgItem(hwnd, IDC_HOST);
-           if (!ctl)
-               ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
-           SetFocus(ctl);
+           int i;
+           struct winctrl *c;
+
+           for (i = 0; (c = winctrl_findbyindex(&ctrls_panel, i)) != NULL;
+                i++) {
+               if (c->ctrl) {
+                   dlg_set_focus(c->ctrl, &dp);
+                   break;
+               }
+           }
        }
 
        SetWindowLong(hwnd, GWL_USERDATA, 1);
-       sesslist_has_focus = 0;
        return 0;
       case WM_LBUTTONUP:
        /*
@@ -1914,8 +453,8 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
         * previous double click on the session list.
         */
        ReleaseCapture();
-       if (readytogo)
-           SendMessage(hwnd, WM_COMMAND, IDOK, 0);
+       if (dp.ended)
+           EndDialog(hwnd, dp.endresult ? 1 : 0);
        break;
       case WM_NOTIFY:
        if (LOWORD(wParam) == IDCX_TREEVIEW &&
@@ -1923,7 +462,6 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
            HTREEITEM i =
                TreeView_GetSelection(((LPNMHDR) lParam)->hwndFrom);
            TVITEM item;
-           int j;
            char buffer[64];
  
            SendMessage (hwnd, WM_SETREDRAW, FALSE, 0);
@@ -1931,49 +469,29 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
            item.hItem = i;
            item.pszText = buffer;
            item.cchTextMax = sizeof(buffer);
-           item.mask = TVIF_TEXT;
+           item.mask = TVIF_TEXT | TVIF_PARAM;
            TreeView_GetItem(((LPNMHDR) lParam)->hwndFrom, &item);
-           for (j = controlstartvalue; j < controlendvalue; j++) {
-               HWND item = GetDlgItem(hwnd, j);
-               if (item)
-                   DestroyWindow(item);
+           {
+               /* Destroy all controls in the currently visible panel. */
+               int k;
+               HWND item;
+               struct winctrl *c;
+
+               while ((c = winctrl_findbyindex(&ctrls_panel, 0)) != NULL) {
+                   for (k = 0; k < c->num_ids; k++) {
+                       item = GetDlgItem(hwnd, c->base_id + k);
+                       if (item)
+                           DestroyWindow(item);
+                   }
+                   winctrl_rem_shortcuts(&dp, c);
+                   winctrl_remove(&ctrls_panel, c);
+                   sfree(c->data);
+                   sfree(c);
+               }
            }
-           if (!strcmp(buffer, "Session"))
-               create_controls(hwnd, dlgtype, sessionpanelstart);
-           if (!strcmp(buffer, "Logging"))
-               create_controls(hwnd, dlgtype, loggingpanelstart);
-           if (!strcmp(buffer, "Keyboard"))
-               create_controls(hwnd, dlgtype, keyboardpanelstart);
-           if (!strcmp(buffer, "Terminal"))
-               create_controls(hwnd, dlgtype, terminalpanelstart);
-           if (!strcmp(buffer, "Bell"))
-               create_controls(hwnd, dlgtype, bellpanelstart);
-           if (!strcmp(buffer, "Window"))
-               create_controls(hwnd, dlgtype, windowpanelstart);
-           if (!strcmp(buffer, "Appearance"))
-               create_controls(hwnd, dlgtype, appearancepanelstart);
-           if (!strcmp(buffer, "Behaviour"))
-               create_controls(hwnd, dlgtype, behaviourpanelstart);
-           if (!strcmp(buffer, "Tunnels"))
-               create_controls(hwnd, dlgtype, tunnelspanelstart);
-           if (!strcmp(buffer, "Connection"))
-               create_controls(hwnd, dlgtype, connectionpanelstart);
-           if (!strcmp(buffer, "Telnet"))
-               create_controls(hwnd, dlgtype, telnetpanelstart);
-           if (!strcmp(buffer, "Rlogin"))
-               create_controls(hwnd, dlgtype, rloginpanelstart);
-           if (!strcmp(buffer, "SSH"))
-               create_controls(hwnd, dlgtype, sshpanelstart);
-           if (!strcmp(buffer, "Auth"))
-               create_controls(hwnd, dlgtype, sshauthpanelstart);
-           if (!strcmp(buffer, "Selection"))
-               create_controls(hwnd, dlgtype, selectionpanelstart);
-           if (!strcmp(buffer, "Colours"))
-               create_controls(hwnd, dlgtype, colourspanelstart);
-           if (!strcmp(buffer, "Translation"))
-               create_controls(hwnd, dlgtype, translationpanelstart);
-
-           init_dlg_ctrls(hwnd, FALSE);
+           create_controls(hwnd, (char *)item.lParam);
+
+           dlg_refresh(NULL, &dp);    /* set up control values */
  
            SendMessage (hwnd, WM_SETREDRAW, TRUE, 0);
            InvalidateRect (hwnd, NULL, TRUE);
@@ -1983,1174 +501,25 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
        }
        break;
       case WM_COMMAND:
+      case WM_DRAWITEM:
+      default:                        /* also handle drag list msg here */
        /*
         * Only process WM_COMMAND once the dialog is fully formed.
         */
-       if (GetWindowLong(hwnd, GWL_USERDATA) == 1)
-           switch (LOWORD(wParam)) {
-             case IDOK:
-               /* Behaviour of the "Open" button is different if the
-                * session list has focus, *unless* the user just
-                * double-clicked... */
-               if (sesslist_has_focus && !readytogo) {
-                   if (!load_selected_session(hwnd)) {
-                       MessageBeep(0);
-                       return 0;
-                   }
-               }
-               /* If at this point we have a valid session, go! */
-               if (*cfg.host) {
-                    if (requested_help) {
-                        WinHelp(hwnd, help_path, HELP_QUIT, 0);
-                        requested_help = FALSE;
-                    }
-                   EndDialog(hwnd, 1);
-                } else
-                   MessageBeep(0);
-               return 0;
-             case IDC_HELPBTN:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED) {
-                    if (help_path) {
-                        WinHelp(hwnd, help_path,
-                                help_has_contents ? HELP_FINDER : HELP_CONTENTS,
-                                0);
-                        requested_help = TRUE;
-                    }
-                }
-                break;
-             case IDCANCEL:
-                if (requested_help) {
-                    WinHelp(hwnd, help_path, HELP_QUIT, 0);
-                    requested_help = FALSE;
-                }
-               EndDialog(hwnd, 0);
-               return 0;
-             case IDC_PROTTELNET:
-             case IDC_PROTRLOGIN:
-             case IDC_PROTSSH:
-             case IDC_PROTRAW:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED) {
-                   int i = IsDlgButtonChecked(hwnd, IDC_PROTSSH);
-                   int j = IsDlgButtonChecked(hwnd, IDC_PROTTELNET);
-                   int k = IsDlgButtonChecked(hwnd, IDC_PROTRLOGIN);
-                   cfg.protocol =
-                       i ? PROT_SSH : j ? PROT_TELNET : k ? PROT_RLOGIN :
-                       PROT_RAW;
-                   if ((cfg.protocol == PROT_SSH && cfg.port != 22)
-                       || (cfg.protocol == PROT_TELNET && cfg.port != 23)
-                       || (cfg.protocol == PROT_RLOGIN
-                           && cfg.port != 513)) {
-                       cfg.port = i ? 22 : j ? 23 : 513;
-                       SetDlgItemInt(hwnd, IDC_PORT, cfg.port, FALSE);
-                   }
-               }
-               break;
-             case IDC_HOST:
-               if (HIWORD(wParam) == EN_CHANGE)
-                   GetDlgItemText(hwnd, IDC_HOST, cfg.host,
-                                  sizeof(cfg.host) - 1);
-               break;
-             case IDC_PORT:
-               if (HIWORD(wParam) == EN_CHANGE) {
-                   GetDlgItemText(hwnd, IDC_PORT, portname, 31);
-                   if (isdigit(portname[0]))
-                       MyGetDlgItemInt(hwnd, IDC_PORT, &cfg.port);
-                   else {
-                       service = getservbyname(portname, NULL);
-                       if (service)
-                           cfg.port = ntohs(service->s_port);
-                       else
-                           cfg.port = 0;
-                   }
-               }
-               break;
-             case IDC_SESSEDIT:
-               if (HIWORD(wParam) == EN_CHANGE) {
-                   SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
-                                      (WPARAM) - 1, 0);
-                   GetDlgItemText(hwnd, IDC_SESSEDIT,
-                                  savedsession, sizeof(savedsession) - 1);
-                   savedsession[sizeof(savedsession) - 1] = '\0';
-               }
-               break;
-             case IDC_SESSSAVE:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED) {
-                   /*
-                    * Save a session
-                    */
-                   char str[2048];
-                   GetDlgItemText(hwnd, IDC_SESSEDIT, str,
-                                  sizeof(str) - 1);
-                   if (!*str) {
-                       int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
-                                                  LB_GETCURSEL, 0, 0);
-                       if (n == LB_ERR) {
-                           MessageBeep(0);
-                           break;
-                       }
-                       strcpy(str, sessions[n]);
-                   }
-                   save_settings(str, !!strcmp(str, "Default Settings"),
-                                 &cfg);
-                   get_sesslist(FALSE);
-                   get_sesslist(TRUE);
-                   SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
-                                      FALSE, 0);
-                   SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
-                                      0, 0);
-                   for (i = 0; i < nsessions; i++)
-                       SendDlgItemMessage(hwnd, IDC_SESSLIST,
-                                          LB_ADDSTRING, 0,
-                                          (LPARAM) (sessions[i]));
-                   SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
-                                      (WPARAM) - 1, 0);
-                   SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
-                                      TRUE, 0);
-                   InvalidateRect(GetDlgItem(hwnd, IDC_SESSLIST), NULL,
-                                  TRUE);
-               }
-               break;
-             case IDC_SESSLIST:
-             case IDC_SESSLOAD:
-               if (LOWORD(wParam) == IDC_SESSLIST) {
-                   if (HIWORD(wParam) == LBN_SETFOCUS)
-                       sesslist_has_focus = 1;
-                   else if (HIWORD(wParam) == LBN_KILLFOCUS)
-                       sesslist_has_focus = 0;
-               }
-               if (LOWORD(wParam) == IDC_SESSLOAD &&
-                   HIWORD(wParam) != BN_CLICKED &&
-                   HIWORD(wParam) != BN_DOUBLECLICKED) break;
-               if (LOWORD(wParam) == IDC_SESSLIST &&
-                   HIWORD(wParam) != LBN_DBLCLK) break;
-               /* Load the session selected in SESSLIST. */
-               if (load_selected_session(hwnd) &&
-                   LOWORD(wParam) == IDC_SESSLIST) {
-                   /*
-                    * A double-click on a saved session should
-                    * actually start the session, not just load it.
-                    * Unless it's Default Settings or some other
-                    * host-less set of saved settings.
-                    */
-                   if (*cfg.host) {
-                       readytogo = TRUE;
-                       SetCapture(hwnd);
-                   }
-               }
-               break;
-             case IDC_SESSDEL:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED) {
-                   int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
-                                              LB_GETCURSEL, 0, 0);
-                   if (n == LB_ERR || n == 0) {
-                       MessageBeep(0);
-                       break;
-                   }
-                   del_settings(sessions[n]);
-                   get_sesslist(FALSE);
-                   get_sesslist(TRUE);
-                   SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
-                                      FALSE, 0);
-                   SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
-                                      0, 0);
-                   for (i = 0; i < nsessions; i++)
-                       SendDlgItemMessage(hwnd, IDC_SESSLIST,
-                                          LB_ADDSTRING, 0,
-                                          (LPARAM) (sessions[i]));
-                   SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
-                                      (WPARAM) - 1, 0);
-                   SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
-                                      TRUE, 0);
-                   InvalidateRect(GetDlgItem(hwnd, IDC_SESSLIST), NULL,
-                                  TRUE);
-               }
-             case IDC_PINGEDIT:
-               if (HIWORD(wParam) == EN_CHANGE)
-                   MyGetDlgItemInt(hwnd, IDC_PINGEDIT,
-                                   &cfg.ping_interval);
-               break;
-             case IDC_NODELAY:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.tcp_nodelay =
-                       IsDlgButtonChecked(hwnd, IDC_NODELAY);
-               break;
-             case IDC_DEL008:
-             case IDC_DEL127:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.bksp_is_delete =
-                       IsDlgButtonChecked(hwnd, IDC_DEL127);
-               break;
-             case IDC_HOMETILDE:
-             case IDC_HOMERXVT:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.rxvt_homeend =
-                       IsDlgButtonChecked(hwnd, IDC_HOMERXVT);
-               break;
-             case IDC_FUNCTILDE:
-             case IDC_FUNCLINUX:
-             case IDC_FUNCXTERM:
-             case IDC_FUNCVT400:
-             case IDC_FUNCVT100P:
-             case IDC_FUNCSCO:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       switch (LOWORD(wParam)) {
-                     case IDC_FUNCTILDE:
-                       cfg.funky_type = 0;
-                       break;
-                     case IDC_FUNCLINUX:
-                       cfg.funky_type = 1;
-                       break;
-                     case IDC_FUNCXTERM:
-                       cfg.funky_type = 2;
-                       break;
-                     case IDC_FUNCVT400:
-                       cfg.funky_type = 3;
-                       break;
-                     case IDC_FUNCVT100P:
-                       cfg.funky_type = 4;
-                       break;
-                     case IDC_FUNCSCO:
-                       cfg.funky_type = 5;
-                       break;
-                   }
-               break;
-             case IDC_KPNORMAL:
-             case IDC_KPAPPLIC:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED) {
-                   cfg.app_keypad =
-                       IsDlgButtonChecked(hwnd, IDC_KPAPPLIC);
-                   cfg.nethack_keypad = FALSE;
-               }
-               break;
-             case IDC_KPNH:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED) {
-                   cfg.app_keypad = FALSE;
-                   cfg.nethack_keypad = TRUE;
-               }
-               break;
-             case IDC_CURNORMAL:
-             case IDC_CURAPPLIC:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.app_cursor =
-                       IsDlgButtonChecked(hwnd, IDC_CURAPPLIC);
-               break;
-             case IDC_NOAPPLICC:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.no_applic_c =
-                       IsDlgButtonChecked(hwnd, IDC_NOAPPLICC);
-               break;
-             case IDC_NOAPPLICK:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.no_applic_k =
-                       IsDlgButtonChecked(hwnd, IDC_NOAPPLICK);
-               break;
-             case IDC_ALTF4:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.alt_f4 = IsDlgButtonChecked(hwnd, IDC_ALTF4);
-               break;
-             case IDC_ALTSPACE:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.alt_space =
-                       IsDlgButtonChecked(hwnd, IDC_ALTSPACE);
-               break;
-             case IDC_ALTONLY:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.alt_only =
-                       IsDlgButtonChecked(hwnd, IDC_ALTONLY);
-               break;
-             case IDC_ECHOBACKEND:
-             case IDC_ECHOYES:
-             case IDC_ECHONO:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED) {
-                   if (LOWORD(wParam) == IDC_ECHOBACKEND)
-                       cfg.localecho = LD_BACKEND;
-                   if (LOWORD(wParam) == IDC_ECHOYES)
-                       cfg.localecho = LD_YES;
-                   if (LOWORD(wParam) == IDC_ECHONO)
-                       cfg.localecho = LD_NO;
-               }
-               break;
-             case IDC_EDITBACKEND:
-             case IDC_EDITYES:
-             case IDC_EDITNO:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED) {
-                   if (LOWORD(wParam) == IDC_EDITBACKEND)
-                       cfg.localedit = LD_BACKEND;
-                   if (LOWORD(wParam) == IDC_EDITYES)
-                       cfg.localedit = LD_YES;
-                   if (LOWORD(wParam) == IDC_EDITNO)
-                       cfg.localedit = LD_NO;
-               }
-               break;
-             case IDC_ANSWEREDIT:
-               if (HIWORD(wParam) == EN_CHANGE)
-                   GetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback,
-                                  sizeof(cfg.answerback) - 1);
-               break;
-             case IDC_ALWAYSONTOP:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.alwaysontop =
-                       IsDlgButtonChecked(hwnd, IDC_ALWAYSONTOP);
-               break;
-             case IDC_FULLSCREENONALTENTER:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.fullscreenonaltenter =
-                       IsDlgButtonChecked(hwnd, IDC_FULLSCREENONALTENTER);
-               break;
-             case IDC_SCROLLKEY:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.scroll_on_key =
-                       IsDlgButtonChecked(hwnd, IDC_SCROLLKEY);
-               break;
-             case IDC_SCROLLDISP:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.scroll_on_disp =
-                       IsDlgButtonChecked(hwnd, IDC_SCROLLDISP);
-               break;
-             case IDC_COMPOSEKEY:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.compose_key =
-                       IsDlgButtonChecked(hwnd, IDC_COMPOSEKEY);
-               break;
-             case IDC_CTRLALTKEYS:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.ctrlaltkeys =
-                       IsDlgButtonChecked(hwnd, IDC_CTRLALTKEYS);
-               break;
-             case IDC_TELNETKEY:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.telnet_keyboard =
-                       IsDlgButtonChecked(hwnd, IDC_TELNETKEY);
-               break;
-             case IDC_TELNETRET:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.telnet_newline =
-                       IsDlgButtonChecked(hwnd, IDC_TELNETRET);
-               break;
-             case IDC_WRAPMODE:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.wrap_mode =
-                       IsDlgButtonChecked(hwnd, IDC_WRAPMODE);
-               break;
-             case IDC_DECOM:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.dec_om = IsDlgButtonChecked(hwnd, IDC_DECOM);
-               break;
-             case IDC_LFHASCR:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.lfhascr =
-                       IsDlgButtonChecked(hwnd, IDC_LFHASCR);
-               break;
-             case IDC_ROWSEDIT:
-               if (HIWORD(wParam) == EN_CHANGE)
-                   MyGetDlgItemInt(hwnd, IDC_ROWSEDIT, &cfg.height);
-               break;
-             case IDC_COLSEDIT:
-               if (HIWORD(wParam) == EN_CHANGE)
-                   MyGetDlgItemInt(hwnd, IDC_COLSEDIT, &cfg.width);
-               break;
-             case IDC_SAVEEDIT:
-               if (HIWORD(wParam) == EN_CHANGE)
-                   MyGetDlgItemInt(hwnd, IDC_SAVEEDIT, &cfg.savelines);
-               break;
-             case IDC_CHOOSEFONT:
-               {
-                   HDC hdc = GetDC(0);
-                   lf.lfHeight = -MulDiv(cfg.fontheight,
-                                         GetDeviceCaps(hdc, LOGPIXELSY),
-                                         72);
-                   ReleaseDC(0, hdc);
-               }
-               lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
-               lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
-               lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
-               lf.lfCharSet = cfg.fontcharset;
-               lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
-               lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
-               lf.lfQuality = DEFAULT_QUALITY;
-               lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
-               strncpy(lf.lfFaceName, cfg.font,
-                       sizeof(lf.lfFaceName) - 1);
-               lf.lfFaceName[sizeof(lf.lfFaceName) - 1] = '\0';
-
-               cf.lStructSize = sizeof(cf);
-               cf.hwndOwner = hwnd;
-               cf.lpLogFont = &lf;
-               cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
-                   CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
-
-               if (ChooseFont(&cf)) {
-                   strncpy(cfg.font, lf.lfFaceName, sizeof(cfg.font) - 1);
-                   cfg.font[sizeof(cfg.font) - 1] = '\0';
-                   cfg.fontisbold = (lf.lfWeight == FW_BOLD);
-                   cfg.fontcharset = lf.lfCharSet;
-                   cfg.fontheight = cf.iPointSize / 10;
-                   fmtfont(fontstatic);
-                   SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
-               }
-               break;
-             case IDC_BELL_DISABLED:
-             case IDC_BELL_DEFAULT:
-             case IDC_BELL_WAVEFILE:
-             case IDC_BELL_VISUAL:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED) {
-                   if (LOWORD(wParam) == IDC_BELL_DISABLED)
-                       cfg.beep = BELL_DISABLED;
-                   if (LOWORD(wParam) == IDC_BELL_DEFAULT)
-                       cfg.beep = BELL_DEFAULT;
-                   if (LOWORD(wParam) == IDC_BELL_WAVEFILE)
-                       cfg.beep = BELL_WAVEFILE;
-                   if (LOWORD(wParam) == IDC_BELL_VISUAL)
-                       cfg.beep = BELL_VISUAL;
-               }
-               break;
-             case IDC_B_IND_DISABLED:
-             case IDC_B_IND_FLASH:
-             case IDC_B_IND_STEADY:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED) {
-                   if (LOWORD(wParam) == IDC_B_IND_DISABLED)
-                       cfg.beep_ind = B_IND_DISABLED;
-                   if (LOWORD(wParam) == IDC_B_IND_FLASH)
-                       cfg.beep_ind = B_IND_FLASH;
-                   if (LOWORD(wParam) == IDC_B_IND_STEADY)
-                       cfg.beep_ind = B_IND_STEADY;
-               }
-               break;
-             case IDC_BELL_WAVEBROWSE:
-               memset(&of, 0, sizeof(of));
-#ifdef OPENFILENAME_SIZE_VERSION_400
-               of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
-#else
-               of.lStructSize = sizeof(of);
-#endif
-               of.hwndOwner = hwnd;
-               of.lpstrFilter = "Wave Files\0*.WAV\0AllFiles\0*\0\0\0";
-               of.lpstrCustomFilter = NULL;
-               of.nFilterIndex = 1;
-               of.lpstrFile = filename;
-               strcpy(filename, cfg.bell_wavefile);
-               of.nMaxFile = sizeof(filename);
-               of.lpstrFileTitle = NULL;
-               of.lpstrInitialDir = NULL;
-               of.lpstrTitle = "Select Bell Sound File";
-               of.Flags = 0;
-               if (GetOpenFileName(&of)) {
-                   strcpy(cfg.bell_wavefile, filename);
-                   SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
-                                  cfg.bell_wavefile);
-               }
-               break;
-             case IDC_BELL_WAVEEDIT:
-               if (HIWORD(wParam) == EN_CHANGE)
-                   GetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
-                                  cfg.bell_wavefile,
-                                  sizeof(cfg.bell_wavefile) - 1);
-               break;
-             case IDC_BELLOVL:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.bellovl =
-                       IsDlgButtonChecked(hwnd, IDC_BELLOVL);
-               break;
-             case IDC_BELLOVLN:
-               if (HIWORD(wParam) == EN_CHANGE)
-                   MyGetDlgItemInt(hwnd, IDC_BELLOVLN, &cfg.bellovl_n);
-               break;
-             case IDC_BELLOVLT:
-               if (HIWORD(wParam) == EN_CHANGE)
-                   MyGetDlgItemFlt(hwnd, IDC_BELLOVLT, &cfg.bellovl_t,
-                                   1000);
-               break;
-             case IDC_BELLOVLS:
-               if (HIWORD(wParam) == EN_CHANGE)
-                   MyGetDlgItemFlt(hwnd, IDC_BELLOVLS, &cfg.bellovl_s,
-                                   1000);
-               break;
-             case IDC_BLINKTEXT:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.blinktext =
-                       IsDlgButtonChecked(hwnd, IDC_BLINKTEXT);
-               break;
-             case IDC_BCE:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.bce = IsDlgButtonChecked(hwnd, IDC_BCE);
-               break;
-             case IDC_WINNAME:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.win_name_always =
-                       IsDlgButtonChecked(hwnd, IDC_WINNAME);
-               break;
-             case IDC_HIDEMOUSE:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.hide_mouseptr =
-                       IsDlgButtonChecked(hwnd, IDC_HIDEMOUSE);
-               break;
-             case IDC_SUNKENEDGE:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.sunken_edge =
-                       IsDlgButtonChecked(hwnd, IDC_SUNKENEDGE);
-               break;
-             case IDC_WINBEDIT:
-               if (HIWORD(wParam) == EN_CHANGE)
-                   MyGetDlgItemInt(hwnd, IDC_WINBEDIT,
-                                   &cfg.window_border);
-               if (cfg.window_border > 32)
-                   cfg.window_border = 32;
-               break;
-             case IDC_CURBLOCK:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.cursor_type = 0;
-               break;
-             case IDC_CURUNDER:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.cursor_type = 1;
-               break;
-             case IDC_CURVERT:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.cursor_type = 2;
-               break;
-             case IDC_BLINKCUR:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.blink_cur =
-                       IsDlgButtonChecked(hwnd, IDC_BLINKCUR);
-               break;
-             case IDC_SCROLLBAR:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.scrollbar =
-                       IsDlgButtonChecked(hwnd, IDC_SCROLLBAR);
-               break;
-             case IDC_SCROLLBARFULLSCREEN:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                   cfg.scrollbar_in_fullscreen =
-                   IsDlgButtonChecked(hwnd, IDC_SCROLLBARFULLSCREEN);
-               break;
-             case IDC_RESIZETERM:
-             case IDC_RESIZEFONT:
-             case IDC_RESIZENONE:
-             case IDC_RESIZEEITHER:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED) {
-                   cfg.resize_action =
-                       IsDlgButtonChecked(hwnd,
-                                          IDC_RESIZETERM) ? RESIZE_TERM :
-                       IsDlgButtonChecked(hwnd,
-                                          IDC_RESIZEFONT) ? RESIZE_FONT :
-                       IsDlgButtonChecked(hwnd,
-                                          IDC_RESIZEEITHER) ? RESIZE_EITHER :
-                       RESIZE_DISABLED;
-               }
-               break;
-             case IDC_WINEDIT:
-               if (HIWORD(wParam) == EN_CHANGE)
-                   GetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle,
-                                  sizeof(cfg.wintitle) - 1);
-               break;
-             case IDC_COEALWAYS:
-             case IDC_COENEVER:
-             case IDC_COENORMAL:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED) {
-                   cfg.close_on_exit =
-                       IsDlgButtonChecked(hwnd,
-                                          IDC_COEALWAYS) ? COE_ALWAYS :
-                       IsDlgButtonChecked(hwnd,
-                                          IDC_COENEVER) ? COE_NEVER :
-                       COE_NORMAL;
-               }
-               break;
-             case IDC_CLOSEWARN:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.warn_on_close =
-                       IsDlgButtonChecked(hwnd, IDC_CLOSEWARN);
-               break;
-             case IDC_TTEDIT:
-               if (HIWORD(wParam) == EN_CHANGE)
-                   GetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype,
-                                  sizeof(cfg.termtype) - 1);
-               break;
-             case IDC_LGFEDIT:
-               if (HIWORD(wParam) == EN_CHANGE)
-                   GetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename,
-                                  sizeof(cfg.logfilename) - 1);
-               break;
-             case IDC_LGFBUTTON:
-               memset(&of, 0, sizeof(of));
-#ifdef OPENFILENAME_SIZE_VERSION_400
-               of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
-#else
-               of.lStructSize = sizeof(of);
-#endif
-               of.hwndOwner = hwnd;
-               of.lpstrFilter = "All Files\0*\0\0\0";
-               of.lpstrCustomFilter = NULL;
-               of.nFilterIndex = 1;
-               of.lpstrFile = filename;
-               strcpy(filename, cfg.logfilename);
-               of.nMaxFile = sizeof(filename);
-               of.lpstrFileTitle = NULL;
-               of.lpstrInitialDir = NULL;
-               of.lpstrTitle = "Select session log file";
-               of.Flags = 0;
-               if (GetSaveFileName(&of)) {
-                   strcpy(cfg.logfilename, filename);
-                   SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
-               }
-               break;
-             case IDC_LSTATOFF:
-             case IDC_LSTATASCII:
-             case IDC_LSTATRAW:
-             case IDC_LSTATPACKET:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED) {
-                   if (IsDlgButtonChecked(hwnd, IDC_LSTATOFF))
-                       cfg.logtype = LGTYP_NONE;
-                   if (IsDlgButtonChecked(hwnd, IDC_LSTATASCII))
-                       cfg.logtype = LGTYP_ASCII;
-                   if (IsDlgButtonChecked(hwnd, IDC_LSTATRAW))
-                       cfg.logtype = LGTYP_DEBUG;
-                   if (IsDlgButtonChecked(hwnd, IDC_LSTATPACKET))
-                       cfg.logtype = LGTYP_PACKETS;
-               }
-               break;
-             case IDC_LSTATXASK:
-             case IDC_LSTATXAPN:
-             case IDC_LSTATXOVR:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED) {
-                   if (IsDlgButtonChecked(hwnd, IDC_LSTATXASK))
-                       cfg.logxfovr = LGXF_ASK;
-                   if (IsDlgButtonChecked(hwnd, IDC_LSTATXAPN))
-                       cfg.logxfovr = LGXF_APN;
-                   if (IsDlgButtonChecked(hwnd, IDC_LSTATXOVR))
-                       cfg.logxfovr = LGXF_OVR;
-               }
-               break;
-             case IDC_TSEDIT:
-             case IDC_R_TSEDIT:
-               if (HIWORD(wParam) == EN_CHANGE)
-                   GetDlgItemText(hwnd, LOWORD(wParam), cfg.termspeed,
-                                  sizeof(cfg.termspeed) - 1);
-               break;
-             case IDC_LOGEDIT:
-               if (HIWORD(wParam) == EN_CHANGE)
-                   GetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username,
-                                  sizeof(cfg.username) - 1);
-               break;
-             case IDC_RLLUSEREDIT:
-               if (HIWORD(wParam) == EN_CHANGE)
-                   GetDlgItemText(hwnd, IDC_RLLUSEREDIT,
-                                  cfg.localusername,
-                                  sizeof(cfg.localusername) - 1);
-               break;
-             case IDC_EMBSD:
-             case IDC_EMRFC:
-               cfg.rfc_environ = IsDlgButtonChecked(hwnd, IDC_EMRFC);
-               break;
-             case IDC_TPASSIVE:
-             case IDC_TACTIVE:
-               cfg.passive_telnet =
-                   IsDlgButtonChecked(hwnd, IDC_TPASSIVE);
-               break;
-             case IDC_ENVADD:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED) {
-                   char str[sizeof(cfg.environmt)];
-                   char *p;
-                   GetDlgItemText(hwnd, IDC_VAREDIT, str,
-                                  sizeof(str) - 1);
-                   if (!*str) {
-                       MessageBeep(0);
-                       break;
-                   }
-                   p = str + strlen(str);
-                   *p++ = '\t';
-                   GetDlgItemText(hwnd, IDC_VALEDIT, p,
-                                  sizeof(str) - 1 - (p - str));
-                   if (!*p) {
-                       MessageBeep(0);
-                       break;
-                   }
-                   p = cfg.environmt;
-                   while (*p) {
-                       while (*p)
-                           p++;
-                       p++;
-                   }
-                   if ((p - cfg.environmt) + strlen(str) + 2 <
-                       sizeof(cfg.environmt)) {
-                       strcpy(p, str);
-                       p[strlen(str) + 1] = '\0';
-                       SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING,
-                                          0, (LPARAM) str);
-                       SetDlgItemText(hwnd, IDC_VAREDIT, "");
-                       SetDlgItemText(hwnd, IDC_VALEDIT, "");
-                   } else {
-                       MessageBox(hwnd, "Environment too big",
-                                  "PuTTY Error", MB_OK | MB_ICONERROR);
-                   }
-               }
-               break;
-             case IDC_ENVREMOVE:
-               if (HIWORD(wParam) != BN_CLICKED &&
-                   HIWORD(wParam) != BN_DOUBLECLICKED) break;
-               i =
-                   SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_GETCURSEL, 0,
-                                      0);
-               if (i == LB_ERR)
-                   MessageBeep(0);
-               else {
-                   char *p, *q;
-
-                   SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_DELETESTRING,
-                                      i, 0);
-                   p = cfg.environmt;
-                   while (i > 0) {
-                       if (!*p)
-                           goto disaster;
-                       while (*p)
-                           p++;
-                       p++;
-                       i--;
-                   }
-                   q = p;
-                   if (!*p)
-                       goto disaster;
-                   while (*p)
-                       p++;
-                   p++;
-                   while (*p) {
-                       while (*p)
-                           *q++ = *p++;
-                       *q++ = *p++;
-                   }
-                   *q = '\0';
-                 disaster:;
-               }
-               break;
-             case IDC_NOPTY:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.nopty = IsDlgButtonChecked(hwnd, IDC_NOPTY);
-               break;
-             case IDC_COMPRESS:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.compression =
-                       IsDlgButtonChecked(hwnd, IDC_COMPRESS);
-               break;
-             case IDC_BUGGYMAC:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.buggymac =
-                       IsDlgButtonChecked(hwnd, IDC_BUGGYMAC);
-               break;
-             case IDC_SSH2DES:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.ssh2_des_cbc =
-                       IsDlgButtonChecked(hwnd, IDC_SSH2DES);
-               break;
-             case IDC_AGENTFWD:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.agentfwd =
-                       IsDlgButtonChecked(hwnd, IDC_AGENTFWD);
-               break;
-             case IDC_CHANGEUSER:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.change_username =
-                       IsDlgButtonChecked(hwnd, IDC_CHANGEUSER);
-               break;
-             case IDC_CIPHERLIST:
-             case IDC_CIPHERUP:
-             case IDC_CIPHERDN:
-               handle_prefslist(&cipherlist,
-                                cfg.ssh_cipherlist, CIPHER_MAX,
-                                0, hwnd, wParam, lParam);
-               break;
-             case IDC_SSHPROT1:
-             case IDC_SSHPROT2:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED) {
-                   if (IsDlgButtonChecked(hwnd, IDC_SSHPROT1))
-                       cfg.sshprot = 1;
-                   else if (IsDlgButtonChecked(hwnd, IDC_SSHPROT2))
-                       cfg.sshprot = 2;
-               }
-               break;
-             case IDC_AUTHTIS:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.try_tis_auth =
-                       IsDlgButtonChecked(hwnd, IDC_AUTHTIS);
-               break;
-             case IDC_AUTHKI:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.try_ki_auth =
-                       IsDlgButtonChecked(hwnd, IDC_AUTHKI);
-               break;
-             case IDC_PKEDIT:
-               if (HIWORD(wParam) == EN_CHANGE)
-                   GetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile,
-                                  sizeof(cfg.keyfile) - 1);
-               break;
-             case IDC_CMDEDIT:
-               if (HIWORD(wParam) == EN_CHANGE)
-                   GetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd,
-                                  sizeof(cfg.remote_cmd) - 1);
-               break;
-             case IDC_PKBUTTON:
-               memset(&of, 0, sizeof(of));
-#ifdef OPENFILENAME_SIZE_VERSION_400
-               of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
-#else
-               of.lStructSize = sizeof(of);
-#endif
-               of.hwndOwner = hwnd;
-               of.lpstrFilter = "All Files\0*\0\0\0";
-               of.lpstrCustomFilter = NULL;
-               of.nFilterIndex = 1;
-               of.lpstrFile = filename;
-               strcpy(filename, cfg.keyfile);
-               of.nMaxFile = sizeof(filename);
-               of.lpstrFileTitle = NULL;
-               of.lpstrInitialDir = NULL;
-               of.lpstrTitle = "Select Private Key File";
-               of.Flags = 0;
-               if (GetOpenFileName(&of)) {
-                   strcpy(cfg.keyfile, filename);
-                   SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile);
-               }
-               break;
-             case IDC_RAWCNP:
-               cfg.rawcnp = IsDlgButtonChecked(hwnd, IDC_RAWCNP);
-               break;
-             case IDC_RTFPASTE:
-               cfg.rtf_paste = IsDlgButtonChecked(hwnd, IDC_RTFPASTE);
-               break;
-             case IDC_MBWINDOWS:
-             case IDC_MBXTERM:
-               cfg.mouse_is_xterm = IsDlgButtonChecked(hwnd, IDC_MBXTERM);
-               break;
-             case IDC_SELTYPELEX:
-             case IDC_SELTYPERECT:
-               cfg.rect_select = IsDlgButtonChecked(hwnd, IDC_SELTYPERECT);
-               break;
-             case IDC_MOUSEOVERRIDE:
-               cfg.mouse_override = IsDlgButtonChecked(hwnd, IDC_MOUSEOVERRIDE);
-               break;
-             case IDC_CCSET:
-               {
-                   BOOL ok;
-                   int i;
-                   int n = GetDlgItemInt(hwnd, IDC_CCEDIT, &ok, FALSE);
-
-                   if (!ok)
-                       MessageBeep(0);
-                   else {
-                       for (i = 0; i < 128; i++)
-                           if (SendDlgItemMessage
-                               (hwnd, IDC_CCLIST, LB_GETSEL, i, 0)) {
-                               char str[100];
-                               cfg.wordness[i] = n;
-                               SendDlgItemMessage(hwnd, IDC_CCLIST,
-                                                  LB_DELETESTRING, i, 0);
-                               sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
-                                       (i >= 0x21 && i != 0x7F) ? i : ' ',
-                                       cfg.wordness[i]);
-                               SendDlgItemMessage(hwnd, IDC_CCLIST,
-                                                  LB_INSERTSTRING, i,
-                                                  (LPARAM) str);
-                           }
-                   }
-               }
-               break;
-             case IDC_BOLDCOLOUR:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED) {
-                   int n, i;
-                   cfg.bold_colour =
-                       IsDlgButtonChecked(hwnd, IDC_BOLDCOLOUR);
-                   SendDlgItemMessage(hwnd, IDC_COLOURLIST, WM_SETREDRAW,
-                                      FALSE, 0);
-                   n =
-                       SendDlgItemMessage(hwnd, IDC_COLOURLIST,
-                                          LB_GETCOUNT, 0, 0);
-                   if (n != 12 + 10 * cfg.bold_colour) {
-                       for (i = n; i-- > 0;)
-                           SendDlgItemMessage(hwnd, IDC_COLOURLIST,
-                                              LB_DELETESTRING, i, 0);
-                       for (i = 0; i < 22; i++)
-                           if (cfg.bold_colour || permcolour[i])
-                               SendDlgItemMessage(hwnd, IDC_COLOURLIST,
-                                                  LB_ADDSTRING, 0,
-                                                  (LPARAM) colours[i]);
-                   }
-                   SendDlgItemMessage(hwnd, IDC_COLOURLIST, WM_SETREDRAW,
-                                      TRUE, 0);
-                   InvalidateRect(GetDlgItem(hwnd, IDC_COLOURLIST), NULL,
-                                  TRUE);
-               }
-               break;
-             case IDC_PALETTE:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                       cfg.try_palette =
-                       IsDlgButtonChecked(hwnd, IDC_PALETTE);
-               break;
-             case IDC_COLOURLIST:
-               if (HIWORD(wParam) == LBN_DBLCLK ||
-                   HIWORD(wParam) == LBN_SELCHANGE) {
-                   int i =
-                       SendDlgItemMessage(hwnd, IDC_COLOURLIST,
-                                          LB_GETCURSEL,
-                                          0, 0);
-                   if (!cfg.bold_colour)
-                       i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
-                   SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
-                                 FALSE);
-                   SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
-                                 FALSE);
-                   SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
-                                 FALSE);
-               }
-               break;
-             case IDC_CHANGE:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED) {
-                   static CHOOSECOLOR cc;
-                   static DWORD custom[16] = { 0 };    /* zero initialisers */
-                   int i =
-                       SendDlgItemMessage(hwnd, IDC_COLOURLIST,
-                                          LB_GETCURSEL,
-                                          0, 0);
-                   if (!cfg.bold_colour)
-                       i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
-                   cc.lStructSize = sizeof(cc);
-                   cc.hwndOwner = hwnd;
-                   cc.hInstance = (HWND) hinst;
-                   cc.lpCustColors = custom;
-                   cc.rgbResult =
-                       RGB(cfg.colours[i][0], cfg.colours[i][1],
-                           cfg.colours[i][2]);
-                   cc.Flags = CC_FULLOPEN | CC_RGBINIT;
-                   if (ChooseColor(&cc)) {
-                       cfg.colours[i][0] =
-                           (unsigned char) (cc.rgbResult & 0xFF);
-                       cfg.colours[i][1] =
-                           (unsigned char) (cc.rgbResult >> 8) & 0xFF;
-                       cfg.colours[i][2] =
-                           (unsigned char) (cc.rgbResult >> 16) & 0xFF;
-                       SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
-                                     FALSE);
-                       SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
-                                     FALSE);
-                       SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
-                                     FALSE);
-                   }
-               }
-               break;
-             case IDC_CODEPAGE:
-               if (HIWORD(wParam) == CBN_SELCHANGE) {
-                   int index = SendDlgItemMessage(hwnd, IDC_CODEPAGE,
-                                                  CB_GETCURSEL, 0, 0);
-                   SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_GETLBTEXT,
-                                      index, (LPARAM)cfg.line_codepage);
-               } else if (HIWORD(wParam) == CBN_EDITCHANGE) {
-                   GetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage,
-                                  sizeof(cfg.line_codepage) - 1);
-               } else if (HIWORD(wParam) == CBN_KILLFOCUS) {
-                   strcpy(cfg.line_codepage,
-                          cp_name(decode_codepage(cfg.line_codepage)));
-                   SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
-               }
-               break;
-             case IDC_CAPSLOCKCYR:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED) {
-                   cfg.xlat_capslockcyr =
-                       IsDlgButtonChecked (hwnd, IDC_CAPSLOCKCYR);
-               }
-               break;
-             case IDC_VTXWINDOWS:
-             case IDC_VTOEMANSI:
-             case IDC_VTOEMONLY:
-             case IDC_VTPOORMAN:
-             case IDC_VTUNICODE:
-               cfg.vtmode =
-                   (IsDlgButtonChecked(hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS
-                    : IsDlgButtonChecked(hwnd,
-                                         IDC_VTOEMANSI) ? VT_OEMANSI :
-                    IsDlgButtonChecked(hwnd,
-                                       IDC_VTOEMONLY) ? VT_OEMONLY :
-                    IsDlgButtonChecked(hwnd,
-                                       IDC_VTUNICODE) ? VT_UNICODE :
-                    VT_POORMAN);
-               break;
-             case IDC_X11_FORWARD:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                   cfg.x11_forward =
-                   IsDlgButtonChecked(hwnd, IDC_X11_FORWARD);
-               break;
-             case IDC_LPORT_ALL:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                   cfg.lport_acceptall =
-                   IsDlgButtonChecked(hwnd, IDC_LPORT_ALL);
-               break;
-             case IDC_RPORT_ALL:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED)
-                   cfg.rport_acceptall =
-                   IsDlgButtonChecked(hwnd, IDC_RPORT_ALL);
-               break;
-             case IDC_X11_DISPLAY:
-               if (HIWORD(wParam) == EN_CHANGE)
-                   GetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display,
-                                  sizeof(cfg.x11_display) - 1);
-               break;
-             case IDC_PFWDADD:
-               if (HIWORD(wParam) == BN_CLICKED ||
-                   HIWORD(wParam) == BN_DOUBLECLICKED) {
-                   char str[sizeof(cfg.portfwd)];
-                   char *p;
-                   if (IsDlgButtonChecked(hwnd, IDC_PFWDLOCAL))
-                       str[0] = 'L';
-                   else
-                       str[0] = 'R';
-                   GetDlgItemText(hwnd, IDC_SPORTEDIT, str+1,
-                                  sizeof(str) - 2);
-                   if (!str[1]) {
-                       MessageBox(hwnd,
-                                  "You need to specify a source port number",
-                                  "PuTTY Error", MB_OK | MB_ICONERROR);
-                       break;
-                   }
-                   p = str + strlen(str);
-                   *p++ = '\t';
-                   GetDlgItemText(hwnd, IDC_DPORTEDIT, p,
-                                  sizeof(str) - 1 - (p - str));
-                   if (!*p || !strchr(p, ':')) {
-                       MessageBox(hwnd,
-                                  "You need to specify a destination address\n"
-                                  "in the form \"host.name:port\"",
-                                  "PuTTY Error", MB_OK | MB_ICONERROR);
-                       break;
-                   }
-                   p = cfg.portfwd;
-                   while (*p) {
-                       while (*p)
-                           p++;
-                       p++;
-                   }
-                   if ((p - cfg.portfwd) + strlen(str) + 2 <
-                       sizeof(cfg.portfwd)) {
-                       strcpy(p, str);
-                       p[strlen(str) + 1] = '\0';
-                       SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_ADDSTRING,
-                                          0, (LPARAM) str);
-                       SetDlgItemText(hwnd, IDC_SPORTEDIT, "");
-                       SetDlgItemText(hwnd, IDC_DPORTEDIT, "");
-                   } else {
-                       MessageBox(hwnd, "Too many forwardings",
-                                  "PuTTY Error", MB_OK | MB_ICONERROR);
-                   }
-               }
-               break;
-             case IDC_PFWDREMOVE:
-               if (HIWORD(wParam) != BN_CLICKED &&
-                   HIWORD(wParam) != BN_DOUBLECLICKED) break;
-               i = SendDlgItemMessage(hwnd, IDC_PFWDLIST,
-                                      LB_GETCURSEL, 0, 0);
-               if (i == LB_ERR)
-                   MessageBeep(0);
-               else {
-                   char *p, *q;
-
-                   SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_DELETESTRING,
-                                      i, 0);
-                   p = cfg.portfwd;
-                   while (i > 0) {
-                       if (!*p)
-                           goto disaster2;
-                       while (*p)
-                           p++;
-                       p++;
-                       i--;
-                   }
-                   q = p;
-                   if (!*p)
-                       goto disaster2;
-                   while (*p)
-                       p++;
-                   p++;
-                   while (*p) {
-                       while (*p)
-                           *q++ = *p++;
-                       *q++ = *p++;
-                   }
-                   *q = '\0';
-                 disaster2:;
-               }
-               break;
-           }
-       return 0;
+       if (GetWindowLong(hwnd, GWL_USERDATA) == 1) {
+           ret = winctrl_handle_command(&dp, msg, wParam, lParam);
+           if (dp.ended && GetCapture() != hwnd)
+               EndDialog(hwnd, dp.endresult ? 1 : 0);
+       } else
+           ret = 0;
+       return ret;
       case WM_HELP:
         if (help_path) {
-            int id = ((LPHELPINFO)lParam)->iCtrlId;
-            char *cmd = help_context_cmd(id);
-            if (cmd) {
-                WinHelp(hwnd, help_path, HELP_COMMAND, (DWORD)cmd);
+           if (winctrl_context_help(&dp, hwnd,
+                                    ((LPHELPINFO)lParam)->iCtrlId))
                 requested_help = TRUE;
-            } else {
+           else
                 MessageBeep(0);
-            }
         }
         break;
       case WM_CLOSE:
@@ -3167,47 +536,26 @@ static int GenericMainDlgProc(HWND hwnd, UINT msg,
            force_normal(hwnd);
        return 0;
 
-      default:
-       /*
-        * Handle application-defined messages eg. DragListBox
-        */
-       /* First find out what the number is (once). */
-       if (draglistmsg == WM_NULL)
-           draglistmsg = RegisterWindowMessage (DRAGLISTMSGSTRING);
-
-       if (msg == draglistmsg) {
-           /* Only process once dialog is fully formed. */
-           if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) {
-             case IDC_CIPHERLIST:
-               return handle_prefslist(&cipherlist,
-                                       cfg.ssh_cipherlist, CIPHER_MAX,
-                                       1, hwnd, wParam, lParam);
-           }
-       }
-       return 0;
-
     }
     return 0;
 }
 
-static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
-                               WPARAM wParam, LPARAM lParam)
+void modal_about_box(HWND hwnd)
 {
-    if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
-    }
-    if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
-       EnableWindow(hwnd, 0);
-       DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
-       EnableWindow(hwnd, 1);
-       SetActiveWindow(hwnd);
-    }
-    return GenericMainDlgProc(hwnd, msg, wParam, lParam, 0);
+    EnableWindow(hwnd, 0);
+    DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
+    EnableWindow(hwnd, 1);
+    SetActiveWindow(hwnd);
 }
 
-static int CALLBACK ReconfDlgProc(HWND hwnd, UINT msg,
-                                 WPARAM wParam, LPARAM lParam)
+void show_help(HWND hwnd)
 {
-    return GenericMainDlgProc(hwnd, msg, wParam, lParam, 1);
+    if (help_path) {
+       WinHelp(hwnd, help_path,
+               help_has_contents ? HELP_FINDER : HELP_CONTENTS,
+               0);
+       requested_help = TRUE;
+    }
 }
 
 void defuse_showwindow(void)
@@ -3231,11 +579,28 @@ int do_config(void)
 {
     int ret;
 
-    get_sesslist(TRUE);
-    savedsession[0] = '\0';
+    ctrlbox = ctrl_new_box();
+    setup_config_box(ctrlbox, &sesslist, FALSE, 0);
+    win_setup_config_box(ctrlbox, &dp.hwnd, (help_path != NULL), FALSE);
+    dp_init(&dp);
+    winctrl_init(&ctrls_base);
+    winctrl_init(&ctrls_panel);
+    dp_add_tree(&dp, &ctrls_base);
+    dp_add_tree(&dp, &ctrls_panel);
+    dp.errtitle = "PuTTY Error";
+    dp.data = &cfg;
+    dp.shortcuts['g'] = TRUE;         /* the treeview: `Cate&gory' */
+
+    get_sesslist(&sesslist, TRUE);
     ret =
-       DialogBox(hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
-    get_sesslist(FALSE);
+       DialogBox(hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL,
+                 GenericMainDlgProc);
+    get_sesslist(&sesslist, FALSE);
+
+    ctrl_free_box(ctrlbox);
+    winctrl_cleanup(&ctrls_panel);
+    winctrl_cleanup(&ctrls_base);
+    dp_cleanup(&dp);
 
     return ret;
 }
@@ -3246,29 +611,51 @@ int do_reconfig(HWND hwnd)
     int ret;
 
     backup_cfg = cfg;                 /* structure copy */
+
+    ctrlbox = ctrl_new_box();
+    setup_config_box(ctrlbox, NULL, TRUE, cfg.protocol);
+    win_setup_config_box(ctrlbox, &dp.hwnd, (help_path != NULL), TRUE);
+    dp_init(&dp);
+    winctrl_init(&ctrls_base);
+    winctrl_init(&ctrls_panel);
+    dp_add_tree(&dp, &ctrls_base);
+    dp_add_tree(&dp, &ctrls_panel);
+    dp.errtitle = "PuTTY Error";
+    dp.data = &cfg;
+    dp.shortcuts['g'] = TRUE;         /* the treeview: `Cate&gory' */
+
     ret =
-       DialogBox(hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
+       DialogBox(hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL,
+                 GenericMainDlgProc);
+
+    ctrl_free_box(ctrlbox);
+    winctrl_cleanup(&ctrls_base);
+    winctrl_cleanup(&ctrls_panel);
+    dp_cleanup(&dp);
+
     if (!ret)
        cfg = backup_cfg;              /* structure copy */
 
     return ret;
 }
 
-void logevent(char *string)
+void logevent(void *frontend, char *string)
 {
     char timebuf[40];
     time_t t;
 
+    log_eventlog(logctx, string);
+
     if (nevents >= negsize) {
        negsize += 64;
-       events = srealloc(events, negsize * sizeof(*events));
+       events = sresize(events, negsize, char *);
     }
 
     time(&t);
     strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S\t",
             localtime(&t));
 
-    events[nevents] = smalloc(strlen(timebuf) + strlen(string) + 1);
+    events[nevents] = snewn(strlen(timebuf) + strlen(string) + 1, char);
     strcpy(events[nevents], timebuf);
     strcat(events[nevents], string);
     if (logbox) {
@@ -3296,7 +683,7 @@ void showabout(HWND hwnd)
     DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
 }
 
-void verify_ssh_host_key(char *host, int port, char *keytype,
+void verify_ssh_host_key(void *frontend, char *host, int port, char *keytype,
                         char *keystr, char *fingerprint)
 {
     int ret;
@@ -3353,7 +740,7 @@ void verify_ssh_host_key(char *host, int port, char *keytype,
        if (mbret == IDYES)
            store_host_key(host, port, keytype, keystr);
        if (mbret == IDCANCEL)
-           exit(0);
+           cleanup_exit(0);
     }
     if (ret == 1) {                   /* key was absent */
        int mbret;
@@ -3363,7 +750,7 @@ void verify_ssh_host_key(char *host, int port, char *keytype,
        if (mbret == IDYES)
            store_host_key(host, port, keytype, keystr);
        if (mbret == IDCANCEL)
-           exit(0);
+           cleanup_exit(0);
     }
 }
 
@@ -3372,7 +759,7 @@ void verify_ssh_host_key(char *host, int port, char *keytype,
  * below the configured 'warn' threshold).
  * cs: 0 = both ways, 1 = client->server, 2 = server->client
  */
-void askcipher(char *ciphername, int cs)
+void askcipher(void *frontend, char *ciphername, int cs)
 {
     static const char mbtitle[] = "PuTTY Security Alert";
     static const char msg[] =
@@ -3394,14 +781,14 @@ void askcipher(char *ciphername, int cs)
     if (mbret == IDYES)
        return;
     else
-       exit(0);
+       cleanup_exit(0);
 }
 
 /*
  * Ask whether to wipe a session log file before writing to it.
  * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
  */
-int askappend(char *filename)
+int askappend(void *frontend, Filename filename)
 {
     static const char mbtitle[] = "PuTTY Log to File";
     static const char msgtemplate[] =
@@ -3413,10 +800,8 @@ int askappend(char *filename)
        "or Cancel to disable logging.";
     char message[sizeof(msgtemplate) + FILENAME_MAX];
     int mbret;
-    if (cfg.logxfovr != LGXF_ASK) {
-       return ((cfg.logxfovr == LGXF_OVR) ? 2 : 1);
-    }
-    sprintf(message, msgtemplate, FILENAME_MAX, filename);
+
+    sprintf(message, msgtemplate, FILENAME_MAX, filename.path);
 
     mbret = MessageBox(NULL, message, mbtitle,
                       MB_ICONQUESTION | MB_YESNOCANCEL);
@@ -3430,6 +815,13 @@ int askappend(char *filename)
 
 /*
  * Warn about the obsolescent key file format.
+ * 
+ * Uniquely among these functions, this one does _not_ expect a
+ * frontend handle. This means that if PuTTY is ported to a
+ * platform which requires frontend handles, this function will be
+ * an anomaly. Fortunately, the problem it addresses will not have
+ * been present on that platform, so it can plausibly be
+ * implemented as an empty function.
  */
 void old_keyfile_warning(void)
 {