X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/57b8bf11164ae575c86b7b739c79d0aa112f28fc..01c034ad857128c51482a563befb374e38ebe668:/windlg.c diff --git a/windlg.c b/windlg.c index 7cc1de22..6f3c35c8 100644 --- a/windlg.c +++ b/windlg.c @@ -1,31 +1,23 @@ #include #include #include -#ifndef AUTO_WINSOCK -#ifdef WINSOCK_TWO -#include -#else -#include -#endif -#endif #include #include +#include +#include #include "ssh.h" #include "putty.h" +#include "winstuff.h" #include "win_res.h" #include "storage.h" static char **events = NULL; static int nevents = 0, negsize = 0; -static HWND logbox = NULL, abtbox = NULL; - -static HINSTANCE hinst; - static int readytogo; -static void force_normal(HWND hwnd) +void force_normal(HWND hwnd) { static int recurse = 0; @@ -35,7 +27,7 @@ static void force_normal(HWND hwnd) recurse = 1; wp.length = sizeof(wp); - if (GetWindowPlacement(hwnd, &wp)) + if (GetWindowPlacement(hwnd, &wp) && wp.showCmd == SW_SHOWMAXIMIZED) { wp.showCmd = SW_SHOWNORMAL; SetWindowPlacement(hwnd, &wp); @@ -51,12 +43,31 @@ static void MyGetDlgItemInt (HWND hwnd, int id, int *result) { *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) { int i; switch (msg) { case WM_INITDIALOG: + { + static int tabs[4] = {78, 108}; + SendDlgItemMessage (hwnd, IDN_LIST, LB_SETTABSTOPS, 2, + (LPARAM) tabs); + } for (i=0; ihwnd = hwnd; - cp->font = SendMessage(hwnd, WM_GETFONT, 0, 0); - cp->ypos = topborder; - GetClientRect(hwnd, &r); - r2.left = r2.top = 0; - r2.right = 4; - r2.bottom = 8; - MapDialogRect(hwnd, &r2); - cp->dlu4inpix = r2.right; - cp->width = (r.right * 4) / (r2.right) - 2*GAPBETWEEN; - cp->xoff = leftborder; - cp->width -= leftborder + rightborder; -} - -static void doctl(struct ctlpos *cp, RECT r, - char *wclass, int wstyle, int exstyle, - char *wtext, int wid) { - HWND ctl; - /* - * Note nonstandard use of RECT. This is deliberate: by - * transforming the width and height directly we arrange to - * have all supposedly same-sized controls really same-sized. - */ - - r.left += cp->xoff; - MapDialogRect(cp->hwnd, &r); - - ctl = CreateWindowEx(exstyle, wclass, wtext, wstyle, - r.left, r.top, r.right, r.bottom, - cp->hwnd, (HMENU)wid, hinst, NULL); - SendMessage(ctl, WM_SETFONT, cp->font, MAKELPARAM(TRUE, 0)); -} - -/* - * A title bar across the top of a sub-dialog. - */ -static void bartitle(struct ctlpos *cp, char *name, int id) { - RECT r; - - r.left = GAPBETWEEN; r.right = cp->width; - r.top = cp->ypos; r.bottom = STATICHEIGHT; - cp->ypos += r.bottom + GAPBETWEEN; - doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, name, id); -} - -/* - * Begin a grouping box, with or without a group title. - */ -static void beginbox(struct ctlpos *cp, char *name, int idbox, int idtext) { - if (name) - cp->ypos += STATICHEIGHT/2; - cp->boxystart = cp->ypos; - if (name) - cp->ypos += STATICHEIGHT - (STATICHEIGHT/2); - cp->ypos += GAPYBOX; - cp->width -= 2*GAPXBOX; - cp->xoff += GAPXBOX; - cp->boxid = idbox; - cp->boxtextid = idtext; - cp->boxtext = name; -} - -/* - * End a grouping box. - */ -static void endbox(struct ctlpos *cp) { - RECT r; - cp->xoff -= GAPXBOX; - cp->width += 2*GAPXBOX; - cp->ypos += GAPYBOX - GAPBETWEEN; - r.left = GAPBETWEEN; r.right = cp->width; - r.top = cp->boxystart; r.bottom = cp->ypos - cp->boxystart; - doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE | SS_ETCHEDFRAME, 0, - "", cp->boxid); - if (cp->boxtext) { - SIZE s; - HDC hdc; - HFONT oldfont, dlgfont; - hdc = GetDC(cp->hwnd); - dlgfont = (HFONT)cp->font; - oldfont = SelectObject(hdc, dlgfont); - GetTextExtentPoint32(hdc, cp->boxtext, strlen(cp->boxtext), &s); - SelectObject(hdc, oldfont); - DeleteDC(hdc); - r.left = GAPXBOX + GAPBETWEEN; - r.right = (s.cx * 4 + cp->dlu4inpix-1) / cp->dlu4inpix; - - r.top = cp->boxystart - STATICHEIGHT/2; r.bottom = STATICHEIGHT; - doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, - cp->boxtext, cp->boxtextid); - } - cp->ypos += GAPYBOX; -} - -/* - * Some edit boxes. Each one has a static above it. The percentages - * of the horizontal space are provided. - */ -static void multiedit(struct ctlpos *cp, ...) { - RECT r; - va_list ap; - int percent, xpos; - - percent = xpos = 0; - va_start(ap, cp); - while (1) { - char *text; - int staticid, editid, pcwidth; - text = va_arg(ap, char *); - if (!text) - break; - staticid = va_arg(ap, int); - editid = va_arg(ap, int); - pcwidth = va_arg(ap, int); - - r.left = xpos + GAPBETWEEN; - percent += pcwidth; - xpos = (cp->width + GAPBETWEEN) * percent / 100; - r.right = xpos - r.left; - - r.top = cp->ypos; r.bottom = STATICHEIGHT; - doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, - text, staticid); - r.top = cp->ypos + 8 + GAPWITHIN; r.bottom = EDITHEIGHT; - doctl(cp, r, "EDIT", - WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL, - WS_EX_CLIENTEDGE, - "", editid); - } - va_end(ap); - cp->ypos += 8+GAPWITHIN+12+GAPBETWEEN; -} - -/* - * A set of radio buttons on the same line, with a static above - * them. `nacross' dictates how many parts the line is divided into - * (you might want this not to equal the number of buttons if you - * needed to line up some 2s and some 3s to look good in the same - * panel). - */ -static void radioline(struct ctlpos *cp, - char *text, int id, int nacross, ...) { - RECT r; - va_list ap; - int group; - int i; - - r.left = GAPBETWEEN; r.top = cp->ypos; - r.right = cp->width; r.bottom = STATICHEIGHT; - cp->ypos += r.bottom + GAPWITHIN; - doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, text, id); - va_start(ap, nacross); - group = WS_GROUP; - i = 0; - while (1) { - char *btext; - int bid; - btext = va_arg(ap, char *); - if (!btext) - break; - bid = va_arg(ap, int); - r.left = GAPBETWEEN + i * (cp->width+GAPBETWEEN)/nacross; - r.right = (i+1) * (cp->width+GAPBETWEEN)/nacross - r.left; - r.top = cp->ypos; r.bottom = RADIOHEIGHT; - doctl(cp, r, "BUTTON", - BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP | group, - 0, - btext, bid); - group = 0; - i++; - } - va_end(ap); - cp->ypos += r.bottom + GAPBETWEEN; -} - -/* - * A set of radio buttons on multiple lines, with a static above - * them. - */ -static void radiobig(struct ctlpos *cp, char *text, int id, ...) { - RECT r; - va_list ap; - int group; - - r.left = GAPBETWEEN; r.top = cp->ypos; - r.right = cp->width; r.bottom = STATICHEIGHT; - cp->ypos += r.bottom + GAPWITHIN; - doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, text, id); - va_start(ap, id); - group = WS_GROUP; - while (1) { - char *btext; - int bid; - btext = va_arg(ap, char *); - if (!btext) - break; - bid = va_arg(ap, int); - r.left = GAPBETWEEN; r.top = cp->ypos; - r.right = cp->width; r.bottom = STATICHEIGHT; - cp->ypos += r.bottom + GAPWITHIN; - doctl(cp, r, "BUTTON", - BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP | group, - 0, - btext, bid); - group = 0; - } - va_end(ap); - cp->ypos += GAPBETWEEN - GAPWITHIN; -} - -/* - * A single standalone checkbox. - */ -static void checkbox(struct ctlpos *cp, char *text, int id) { - RECT r; - - r.left = GAPBETWEEN; r.top = cp->ypos; - r.right = cp->width; r.bottom = CHECKBOXHEIGHT; - cp->ypos += r.bottom + GAPBETWEEN; - doctl(cp, r, "BUTTON", - BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 0, - text, id); -} - -/* - * A button on the right hand side, with a static to its left. - */ -static void staticbtn(struct ctlpos *cp, char *stext, int sid, - char *btext, int bid) { - const int height = (PUSHBTNHEIGHT > STATICHEIGHT ? - PUSHBTNHEIGHT : STATICHEIGHT); - RECT r; - int lwid, rwid, rpos; - - rpos = GAPBETWEEN + 3 * (cp->width + GAPBETWEEN) / 4; - lwid = rpos - 2*GAPBETWEEN; - rwid = cp->width + GAPBETWEEN - rpos; - - r.left = GAPBETWEEN; r.top = cp->ypos + (height-STATICHEIGHT)/2; - r.right = lwid; r.bottom = STATICHEIGHT; - doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid); - - r.left = rpos; r.top = cp->ypos + (height-PUSHBTNHEIGHT)/2; - r.right = rwid; r.bottom = PUSHBTNHEIGHT; - doctl(cp, r, "BUTTON", - WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON, - 0, - btext, bid); - - cp->ypos += height + GAPBETWEEN; -} - -/* - * An edit control on the right hand side, with a static to its left. - */ -static void staticedit(struct ctlpos *cp, char *stext, - int sid, int eid, int percentedit) { - const int height = (EDITHEIGHT > STATICHEIGHT ? - EDITHEIGHT : STATICHEIGHT); - RECT r; - int lwid, rwid, rpos; - - rpos = GAPBETWEEN + (100-percentedit) * (cp->width + GAPBETWEEN) / 100; - lwid = rpos - 2*GAPBETWEEN; - rwid = cp->width + GAPBETWEEN - rpos; - - r.left = GAPBETWEEN; r.top = cp->ypos + (height-STATICHEIGHT)/2; - r.right = lwid; r.bottom = STATICHEIGHT; - doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid); - - r.left = rpos; r.top = cp->ypos + (height-EDITHEIGHT)/2; - r.right = rwid; r.bottom = EDITHEIGHT; - doctl(cp, r, "EDIT", - WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL, - WS_EX_CLIENTEDGE, - "", eid); - - cp->ypos += height + GAPBETWEEN; -} - -/* - * A tab-control substitute when a real tab control is unavailable. - */ -static void ersatztab(struct ctlpos *cp, char *stext, int sid, - int lid, int s2id) { - const int height = (COMBOHEIGHT > STATICHEIGHT ? - COMBOHEIGHT : STATICHEIGHT); - RECT r; - int bigwid, lwid, rwid, rpos; - static const int BIGGAP = 15; - static const int MEDGAP = 3; - - bigwid = cp->width + 2*GAPBETWEEN - 2*BIGGAP; - cp->ypos += MEDGAP; - rpos = BIGGAP + (bigwid + BIGGAP) / 2; - lwid = rpos - 2*BIGGAP; - rwid = bigwid + BIGGAP - rpos; - - r.left = BIGGAP; r.top = cp->ypos + (height-STATICHEIGHT)/2; - r.right = lwid; r.bottom = STATICHEIGHT; - doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid); - - r.left = rpos; r.top = cp->ypos + (height-COMBOHEIGHT)/2; - r.right = rwid; r.bottom = COMBOHEIGHT*10; - doctl(cp, r, "COMBOBOX", - WS_CHILD | WS_VISIBLE | WS_TABSTOP | - CBS_DROPDOWNLIST | CBS_HASSTRINGS, - WS_EX_CLIENTEDGE, - "", lid); - - cp->ypos += height + MEDGAP + GAPBETWEEN; - - r.left = GAPBETWEEN; r.top = cp->ypos; - r.right = cp->width; r.bottom = 2; - doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE | SS_ETCHEDHORZ, - 0, "", s2id); -} - -/* - * A static line, followed by an edit control on the left hand side - * and a button on the right. - */ -static void editbutton(struct ctlpos *cp, char *stext, int sid, - int eid, char *btext, int bid) { - const int height = (EDITHEIGHT > PUSHBTNHEIGHT ? - EDITHEIGHT : PUSHBTNHEIGHT); - RECT r; - int lwid, rwid, rpos; - - r.left = GAPBETWEEN; r.top = cp->ypos; - r.right = cp->width; r.bottom = STATICHEIGHT; - cp->ypos += r.bottom + GAPWITHIN; - doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid); - - rpos = GAPBETWEEN + 3 * (cp->width + GAPBETWEEN) / 4; - lwid = rpos - 2*GAPBETWEEN; - rwid = cp->width + GAPBETWEEN - rpos; - - r.left = GAPBETWEEN; r.top = cp->ypos + (height-EDITHEIGHT)/2; - r.right = lwid; r.bottom = EDITHEIGHT; - doctl(cp, r, "EDIT", - WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL, - WS_EX_CLIENTEDGE, - "", eid); - - r.left = rpos; r.top = cp->ypos + (height-PUSHBTNHEIGHT)/2; - r.right = rwid; r.bottom = PUSHBTNHEIGHT; - doctl(cp, r, "BUTTON", - WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON, - 0, - btext, bid); - - cp->ypos += height + GAPBETWEEN; -} - -/* - * Special control which was hard to describe generically: the - * session-saver assembly. A static; below that an edit box; below - * that a list box. To the right of the list box, a column of - * buttons. - */ -static void sesssaver(struct ctlpos *cp, char *text, - int staticid, int editid, int listid, ...) { - RECT r; - va_list ap; - int lwid, rwid, rpos; - int y; - const int LISTDEFHEIGHT = 66; - - rpos = GAPBETWEEN + 3 * (cp->width + GAPBETWEEN) / 4; - lwid = rpos - 2*GAPBETWEEN; - rwid = cp->width + GAPBETWEEN - rpos; - - /* The static control. */ - r.left = GAPBETWEEN; r.top = cp->ypos; - r.right = lwid; r.bottom = STATICHEIGHT; - cp->ypos += r.bottom + GAPWITHIN; - doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, text, staticid); - - /* The edit control. */ - r.left = GAPBETWEEN; r.top = cp->ypos; - r.right = lwid; r.bottom = EDITHEIGHT; - cp->ypos += r.bottom + GAPWITHIN; - doctl(cp, r, "EDIT", - WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL, - WS_EX_CLIENTEDGE, - "", editid); - - /* - * The buttons (we should hold off on the list box until we - * know how big the buttons are). - */ - va_start(ap, listid); - y = cp->ypos; - while (1) { - char *btext = va_arg(ap, char *); - int bid; - if (!btext) break; - bid = va_arg(ap, int); - r.left = rpos; r.top = y; - r.right = rwid; r.bottom = PUSHBTNHEIGHT; - y += r.bottom + GAPWITHIN; - doctl(cp, r, "BUTTON", - WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON, - 0, - btext, bid); - } - - /* Compute list box height. LISTDEFHEIGHT, or height of buttons. */ - y -= cp->ypos; - y -= GAPWITHIN; - if (y < LISTDEFHEIGHT) y = LISTDEFHEIGHT; - r.left = GAPBETWEEN; r.top = cp->ypos; - r.right = lwid; r.bottom = y; - cp->ypos += y + GAPBETWEEN; - doctl(cp, r, "LISTBOX", - WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | - LBS_NOTIFY | LBS_HASSTRINGS, - WS_EX_CLIENTEDGE, - "", listid); -} - /* - * Another special control: the environment-variable setter. A - * static line first; then a pair of edit boxes with associated - * statics, and two buttons; then a list box. + * Null dialog procedure. */ -static void envsetter(struct ctlpos *cp, char *stext, int sid, - char *e1stext, int e1sid, int e1id, - char *e2stext, int e2sid, int e2id, - int listid, - char *b1text, int b1id, char *b2text, int b2id) { - RECT r; - const int height = (STATICHEIGHT > EDITHEIGHT && STATICHEIGHT > PUSHBTNHEIGHT ? - STATICHEIGHT : - EDITHEIGHT > PUSHBTNHEIGHT ? - EDITHEIGHT : PUSHBTNHEIGHT); - const static int percents[] = { 20, 35, 10, 25 }; - int i, j, xpos, percent; - const int LISTHEIGHT = 42; - - /* The static control. */ - r.left = GAPBETWEEN; r.top = cp->ypos; - r.right = cp->width; r.bottom = STATICHEIGHT; - cp->ypos += r.bottom + GAPWITHIN; - doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid); - - /* The statics+edits+buttons. */ - for (j = 0; j < 2; j++) { - percent = 10; - for (i = 0; i < 4; i++) { - xpos = (cp->width + GAPBETWEEN) * percent / 100; - r.left = xpos + GAPBETWEEN; - percent += percents[i]; - xpos = (cp->width + GAPBETWEEN) * percent / 100; - r.right = xpos - r.left; - r.top = cp->ypos; - r.bottom = (i==0 ? STATICHEIGHT : - i==1 ? EDITHEIGHT : - PUSHBTNHEIGHT); - r.top += (height-r.bottom)/2; - if (i==0) { - doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, - j==0 ? e1stext : e2stext, j==0 ? e1sid : e2sid); - } else if (i==1) { - doctl(cp, r, "EDIT", - WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL, - WS_EX_CLIENTEDGE, - "", j==0 ? e1id : e2id); - } else if (i==3) { - doctl(cp, r, "BUTTON", - WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON, - 0, - j==0 ? b1text : b2text, j==0 ? b1id : b2id); - } - } - cp->ypos += height + GAPWITHIN; - } - - /* The list box. */ - r.left = GAPBETWEEN; r.top = cp->ypos; - r.right = cp->width; r.bottom = LISTHEIGHT; - cp->ypos += r.bottom + GAPBETWEEN; - doctl(cp, r, "LISTBOX", - WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | LBS_HASSTRINGS | - LBS_USETABSTOPS, - WS_EX_CLIENTEDGE, - "", listid); -} - -/* - * Yet another special control: the character-class setter. A - * static, then a list, then a line containing a - * button-and-static-and-edit. - */ -static void charclass(struct ctlpos *cp, char *stext, int sid, int listid, - char *btext, int bid, int eid, char *s2text, int s2id) { - RECT r; - const int height = (STATICHEIGHT > EDITHEIGHT && STATICHEIGHT > PUSHBTNHEIGHT ? - STATICHEIGHT : - EDITHEIGHT > PUSHBTNHEIGHT ? - EDITHEIGHT : PUSHBTNHEIGHT); - const static int percents[] = { 30, 40, 30 }; - int i, xpos, percent; - const int LISTHEIGHT = 66; - - /* The static control. */ - r.left = GAPBETWEEN; r.top = cp->ypos; - r.right = cp->width; r.bottom = STATICHEIGHT; - cp->ypos += r.bottom + GAPWITHIN; - doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid); - - /* The list box. */ - r.left = GAPBETWEEN; r.top = cp->ypos; - r.right = cp->width; r.bottom = LISTHEIGHT; - cp->ypos += r.bottom + GAPWITHIN; - doctl(cp, r, "LISTBOX", - WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | LBS_HASSTRINGS | - LBS_USETABSTOPS, - WS_EX_CLIENTEDGE, - "", listid); - - /* The button+static+edit. */ - percent = xpos = 0; - for (i = 0; i < 3; i++) { - r.left = xpos + GAPBETWEEN; - percent += percents[i]; - xpos = (cp->width + GAPBETWEEN) * percent / 100; - r.right = xpos - r.left; - r.top = cp->ypos; - r.bottom = (i==0 ? PUSHBTNHEIGHT : - i==1 ? STATICHEIGHT : - EDITHEIGHT); - r.top += (height-r.bottom)/2; - if (i==0) { - doctl(cp, r, "BUTTON", - WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON, - 0, btext, bid); - } else if (i==1) { - doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE | SS_CENTER, - 0, s2text, s2id); - } else if (i==2) { - doctl(cp, r, "EDIT", - WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL, - WS_EX_CLIENTEDGE, "", eid); - } - } - cp->ypos += height + GAPBETWEEN; -} - -/* - * A special control (horrors!). The colour editor. A static line; - * then on the left, a list box, and on the right, a sequence of - * two-part statics followed by a button. - */ -static void colouredit(struct ctlpos *cp, char *stext, int sid, int listid, - char *btext, int bid, ...) { - RECT r; - int y; - va_list ap; - int lwid, rwid, rpos; - const int LISTHEIGHT = 66; - - /* The static control. */ - r.left = GAPBETWEEN; r.top = cp->ypos; - r.right = cp->width; r.bottom = STATICHEIGHT; - cp->ypos += r.bottom + GAPWITHIN; - doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid); - - rpos = GAPBETWEEN + 2 * (cp->width + GAPBETWEEN) / 3; - lwid = rpos - 2*GAPBETWEEN; - rwid = cp->width + GAPBETWEEN - rpos; - - /* The list box. */ - r.left = GAPBETWEEN; r.top = cp->ypos; - r.right = lwid; r.bottom = LISTHEIGHT; - doctl(cp, r, "LISTBOX", - WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | LBS_HASSTRINGS | - LBS_USETABSTOPS, - WS_EX_CLIENTEDGE, - "", listid); - - /* The statics. */ - y = cp->ypos; - va_start(ap, bid); - while (1) { - char *ltext; - int lid, rid; - ltext = va_arg(ap, char *); - if (!ltext) break; - lid = va_arg(ap, int); - rid = va_arg(ap, int); - r.top = y; r.bottom = STATICHEIGHT; - y += r.bottom + GAPWITHIN; - r.left = rpos; r.right = rwid/2; - doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, ltext, lid); - r.left = rpos + r.right; r.right = rwid - r.right; - doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE | SS_RIGHT, 0, "", rid); - } - va_end(ap); - - /* The button. */ - r.top = y + 2*GAPWITHIN; r.bottom = PUSHBTNHEIGHT; - r.left = rpos; r.right = rwid; - doctl(cp, r, "BUTTON", - WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON, - 0, btext, bid); - - cp->ypos += LISTHEIGHT + GAPBETWEEN; +static int CALLBACK NullDlgProc (HWND hwnd, UINT msg, + WPARAM wParam, LPARAM lParam) { + return 0; } static char savedsession[2048]; @@ -819,8 +212,8 @@ enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue, sessionpanelstart, IDC_TITLE_SESSION, - IDC_BOX_SESSION1, IDC_BOXT_SESSION1, - IDC_BOX_SESSION2, IDC_BOXT_SESSION2, + IDC_BOX_SESSION1, + IDC_BOX_SESSION2, IDC_BOX_SESSION3, IDC_HOSTSTATIC, IDC_HOST, @@ -829,6 +222,7 @@ enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue, IDC_PROTSTATIC, IDC_PROTRAW, IDC_PROTTELNET, + IDC_PROTRLOGIN, IDC_PROTSSH, IDC_SESSSTATIC, IDC_SESSEDIT, @@ -837,12 +231,32 @@ enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue, 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_LGFSTATIC, + IDC_LGFEDIT, + IDC_LGFBUTTON, + IDC_LSTATXIST, + IDC_LSTATXOVR, + IDC_LSTATXAPN, + IDC_LSTATXASK, + loggingpanelend, + keyboardpanelstart, IDC_TITLE_KEYBOARD, - IDC_BOX_KEYBOARD1, IDC_BOXT_KEYBOARD1, - IDC_BOX_KEYBOARD2, IDC_BOXT_KEYBOARD2, + IDC_BOX_KEYBOARD1, + IDC_BOX_KEYBOARD2, + IDC_BOX_KEYBOARD3, IDC_DELSTATIC, IDC_DEL008, IDC_DEL127, @@ -854,60 +268,111 @@ enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue, 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_BOXT_TERMINAL1, - IDC_BOX_TERMINAL2, IDC_BOXT_TERMINAL2, - IDC_BOX_TERMINAL3, IDC_BOXT_TERMINAL3, + IDC_BOX_TERMINAL1, + IDC_BOX_TERMINAL2, IDC_WRAPMODE, IDC_DECOM, - IDC_DIMSTATIC, - IDC_ROWSSTATIC, - IDC_ROWSEDIT, - IDC_COLSSTATIC, - IDC_COLSEDIT, - IDC_LOCKSIZE, - IDC_FONTSTATIC, - IDC_CHOOSEFONT, IDC_LFHASCR, - IDC_BEEP, IDC_BCE, IDC_BLINKTEXT, - IDC_LDISCTERM, + 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_BELLOVL, + IDC_BELLOVLNSTATIC, + IDC_BELLOVLN, + IDC_BELLOVLTSTATIC, + IDC_BELLOVLT, + IDC_BELLOVLEXPLAIN, + IDC_BELLOVLSSTATIC, + IDC_BELLOVLS, + bellpanelend, + windowpanelstart, IDC_TITLE_WINDOW, - IDC_BOX_WINDOW1, IDC_BOXT_WINDOW1, - IDC_BOX_WINDOW2, IDC_BOXT_WINDOW2, - IDC_BOX_WINDOW3, IDC_BOXT_WINDOW3, - IDC_BOX_WINDOW4, - IDC_WINNAME, - IDC_BLINKCUR, + IDC_BOX_WINDOW1, + IDC_BOX_WINDOW2, + IDC_BOX_WINDOW3, + IDC_ROWSSTATIC, + IDC_ROWSEDIT, + IDC_COLSSTATIC, + IDC_COLSEDIT, + IDC_LOCKSIZE, IDC_SCROLLBAR, - IDC_WINTITLE, - IDC_WINEDIT, IDC_CLOSEWARN, IDC_SAVESTATIC, IDC_SAVEEDIT, IDC_ALTF4, IDC_ALTSPACE, + IDC_ALTONLY, IDC_SCROLLKEY, + IDC_SCROLLDISP, + IDC_ALWAYSONTOP, windowpanelend, + 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, + appearancepanelend, + connectionpanelstart, IDC_TITLE_CONNECTION, - IDC_BOX_CONNECTION1, IDC_BOXT_CONNECTION1, - IDC_BOX_CONNECTION2, IDC_BOXT_CONNECTION2, + IDC_BOX_CONNECTION1, + IDC_BOX_CONNECTION2, IDC_TTSTATIC, IDC_TTEDIT, IDC_LOGSTATIC, @@ -918,8 +383,8 @@ enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue, telnetpanelstart, IDC_TITLE_TELNET, - IDC_BOX_TELNET1, IDC_BOXT_TELNET1, - IDC_BOX_TELNET2, IDC_BOXT_TELNET2, + IDC_BOX_TELNET1, + IDC_BOX_TELNET2, IDC_TSSTATIC, IDC_TSEDIT, IDC_ENVSTATIC, @@ -935,16 +400,28 @@ enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue, IDC_EMRFC, 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_BOXT_SSH1, - IDC_BOX_SSH2, IDC_BOXT_SSH2, - IDC_BOX_SSH3, IDC_BOXT_SSH3, + IDC_BOX_SSH1, + IDC_BOX_SSH2, + IDC_BOX_SSH3, IDC_NOPTY, IDC_CIPHERSTATIC, IDC_CIPHER3DES, IDC_CIPHERBLOWF, IDC_CIPHERDES, + IDC_CIPHERAES, + IDC_BUGGYMAC, IDC_AUTHTIS, IDC_PKSTATIC, IDC_PKEDIT, @@ -955,12 +432,14 @@ enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue, IDC_AGENTFWD, IDC_CMDSTATIC, IDC_CMDEDIT, + IDC_COMPRESS, sshpanelend, selectionpanelstart, IDC_TITLE_SELECTION, - IDC_BOX_SELECTION1, IDC_BOXT_SELECTION1, - IDC_BOX_SELECTION2, IDC_BOXT_SELECTION2, + IDC_BOX_SELECTION1, + IDC_BOX_SELECTION2, + IDC_BOX_SELECTION3, IDC_MBSTATIC, IDC_MBWINDOWS, IDC_MBXTERM, @@ -969,16 +448,17 @@ enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue, IDC_CCSET, IDC_CCSTATIC2, IDC_CCEDIT, + IDC_RAWCNP, selectionpanelend, colourspanelstart, IDC_TITLE_COLOURS, - IDC_BOX_COLOURS1, IDC_BOXT_COLOURS1, - IDC_BOX_COLOURS2, IDC_BOXT_COLOURS2, + IDC_BOX_COLOURS1, + IDC_BOX_COLOURS2, IDC_BOLDCOLOUR, IDC_PALETTE, - IDC_STATIC, - IDC_LIST, + IDC_COLOURSTATIC, + IDC_COLOURLIST, IDC_RSTATIC, IDC_GSTATIC, IDC_BSTATIC, @@ -990,9 +470,9 @@ enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue, translationpanelstart, IDC_TITLE_TRANSLATION, - IDC_BOX_TRANSLATION1, IDC_BOXT_TRANSLATION1, - IDC_BOX_TRANSLATION2, IDC_BOXT_TRANSLATION2, - IDC_BOX_TRANSLATION3, IDC_BOXT_TRANSLATION3, + IDC_BOX_TRANSLATION1, + IDC_BOX_TRANSLATION2, + IDC_BOX_TRANSLATION3, IDC_XLATSTATIC, IDC_NOXLAT, IDC_KOI8WIN1251, @@ -1006,6 +486,14 @@ enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue, IDC_VTPOORMAN, translationpanelend, + tunnelspanelstart, + IDC_TITLE_TUNNELS, + IDC_BOX_TUNNELS, + IDC_X11_FORWARD, + IDC_X11_DISPSTATIC, + IDC_X11_DISPLAY, + tunnelspanelend, + controlendvalue }; @@ -1035,9 +523,8 @@ static void fmtfont (char *buf) { if (cfg.fontheight == 0) strcat (buf, "default height"); else - sprintf (buf+strlen(buf), "%d-%s", - (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight), - (cfg.fontheight < 0 ? "pixel" : "point")); + sprintf (buf+strlen(buf), "%d-point", + (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight)); } static void init_dlg_ctrls(HWND hwnd) { @@ -1046,22 +533,37 @@ static void init_dlg_ctrls(HWND hwnd) { SetDlgItemText (hwnd, IDC_HOST, cfg.host); SetDlgItemText (hwnd, IDC_SESSEDIT, savedsession); + { + 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 : IDC_PROTRAW ); + cfg.protocol==PROT_TELNET ? IDC_PROTTELNET : + cfg.protocol==PROT_RLOGIN ? IDC_PROTRLOGIN : IDC_PROTRAW ); SetDlgItemInt (hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE); 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_FUNCXTERM, + 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, @@ -1069,8 +571,19 @@ static void init_dlg_ctrls(HWND hwnd) { cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL); CheckDlgButton (hwnd, IDC_ALTF4, cfg.alt_f4); CheckDlgButton (hwnd, IDC_ALTSPACE, cfg.alt_space); - CheckDlgButton (hwnd, IDC_LDISCTERM, cfg.ldisc_term); + CheckDlgButton (hwnd, IDC_ALTONLY, cfg.alt_only); + CheckDlgButton (hwnd, IDC_COMPOSEKEY, cfg.compose_key); + CheckDlgButton (hwnd, IDC_CTRLALTKEYS, cfg.ctrlaltkeys); + 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_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); @@ -1080,21 +593,49 @@ static void init_dlg_ctrls(HWND hwnd) { SetDlgItemInt (hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE); fmtfont (fontstatic); SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic); - CheckDlgButton (hwnd, IDC_BEEP, cfg.beep); + 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); + 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); + 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_LOCKSIZE, cfg.locksize); - CheckDlgButton (hwnd, IDC_CLOSEEXIT, cfg.close_on_exit); + 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_LSTATRAW, + cfg.logtype == 0 ? IDC_LSTATOFF : + cfg.logtype == 1 ? IDC_LSTATASCII : + IDC_LSTATRAW); + CheckRadioButton(hwnd, IDC_LSTATXOVR, IDC_LSTATXASK, + cfg.logxfovr == LGXF_OVR ? IDC_LSTATXOVR : + cfg.logxfovr == LGXF_ASK ? IDC_LSTATXASK : + IDC_LSTATXAPN); { char *p = cfg.environmt; while (*p) { @@ -1109,10 +650,13 @@ static void init_dlg_ctrls(HWND hwnd) { 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_AGENTFWD, cfg.agentfwd); - CheckRadioButton (hwnd, IDC_CIPHER3DES, IDC_CIPHERDES, + CheckRadioButton (hwnd, IDC_CIPHER3DES, IDC_CIPHERAES, cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF : cfg.cipher == CIPHER_DES ? IDC_CIPHERDES : + cfg.cipher == CIPHER_AES ? IDC_CIPHERAES : IDC_CIPHER3DES); CheckRadioButton (hwnd, IDC_SSHPROT1, IDC_SSHPROT2, cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2); @@ -1122,6 +666,7 @@ static void init_dlg_ctrls(HWND hwnd) { CheckRadioButton (hwnd, IDC_MBWINDOWS, IDC_MBXTERM, cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS); + CheckDlgButton (hwnd, IDC_RAWCNP, cfg.rawcnp); { static int tabs[4] = {25, 61, 96, 128}; SendDlgItemMessage (hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4, @@ -1139,13 +684,17 @@ static void init_dlg_ctrls(HWND hwnd) { CheckDlgButton (hwnd, IDC_BOLDCOLOUR, cfg.bold_colour); CheckDlgButton (hwnd, IDC_PALETTE, cfg.try_palette); { - int i; + 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_LIST, LB_ADDSTRING, 0, + SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0, (LPARAM) colours[i]); } - SendDlgItemMessage (hwnd, IDC_LIST, LB_SETCURSEL, 0, 0); + 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); @@ -1161,16 +710,9 @@ static void init_dlg_ctrls(HWND hwnd) { cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI : cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY : IDC_VTPOORMAN); -} -static void hide(HWND hwnd, int hide, int minid, int maxid) { - int i; - for (i = minid; i < maxid; i++) { - HWND ctl = GetDlgItem(hwnd, i); - if (ctl) { - ShowWindow(ctl, hide ? SW_HIDE : SW_SHOW); - } - } + CheckDlgButton (hwnd, IDC_X11_FORWARD, cfg.x11_forward); + SetDlgItemText (hwnd, IDC_X11_DISPLAY, cfg.x11_display); } struct treeview_faff { @@ -1201,7 +743,459 @@ static HTREEITEM treeview_insert(struct treeview_faff *faff, } /* - * This _huge_ function is the configuration box. + * Create the panelfuls of controls in the configuration box. + */ +static void create_controls(HWND hwnd, int dlgtype, int panel) { + 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", + IDC_BOX_SESSION1); + multiedit(&cp, + "Host &Name", 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, 4, + "&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); + } + + if (panel == loggingpanelstart) { + /* The Logging panel. Accelerators used: [acgo] tplfwe */ + 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, NULL); + editbutton(&cp, "Log &file name:", + IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...", + IDC_LGFBUTTON); + 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 wt */ + 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); + 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.", + 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 sdkp w4ylt */ + 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); + checkbox(&cp, "Lock window size against resi&zing", IDC_LOCKSIZE); + 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, "Reset scrollback on &keypress", IDC_SCROLLKEY); + checkbox(&cp, "Reset scrollback on dis&play activity", + IDC_SCROLLDISP); + endbox(&cp); + beginbox(&cp, NULL, IDC_BOX_WINDOW3); + 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< alone", IDC_ALTONLY); + checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP); + 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, "Options controlling PuTTY's appearance", + 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); + endbox(&cp); + } + + if (panel == translationpanelstart) { + /* The Translation panel. Accelerators used: [acgo] xbep t s */ + struct ctlpos cp; + ctlposinit(&cp, hwnd, 80, 3, 13); + bartitle(&cp, "Options controlling character set translation", + IDC_TITLE_TRANSLATION); + beginbox(&cp, "Adjust how PuTTY displays line drawing characters", + IDC_BOX_TRANSLATION1); + 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, NULL); + endbox(&cp); + beginbox(&cp, "Enable character set translation on received data", + IDC_BOX_TRANSLATION2); + radiobig(&cp, + "Character set &translation:", IDC_XLATSTATIC, + "None", IDC_NOXLAT, + "KOI8 / Win-1251", IDC_KOI8WIN1251, + "ISO-8859-2 / Win-1250", IDC_88592WIN1250, + "ISO-8859-2 / CP852", IDC_88592CP852, NULL); + endbox(&cp); + beginbox(&cp, "Enable character set translation on input data", + IDC_BOX_TRANSLATION3); + checkbox(&cp, "CAP&S LOCK acts as cyrillic switch", + IDC_CAPSLOCKCYR); + endbox(&cp); + } + + if (panel == selectionpanelstart) { + /* The Selection panel. Accelerators used: [acgo] d wx hst */ + 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); + 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); + 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] tuk */ + 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); + } + 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 (panel == telnetpanelstart) { + /* The Telnet panel. Accelerators used: [acgo] svldr bf */ + 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); + 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] rmfkw pe123bds i */ + 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, "Authentication options", + IDC_BOX_SSH2); + checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication", + IDC_AUTHTIS); + checkbox(&cp, "Allow agent &forwarding", IDC_AGENTFWD); + editbutton(&cp, "Private &key file for authentication:", + IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...", IDC_PKBUTTON); + endbox(&cp); + beginbox(&cp, "Protocol options", + IDC_BOX_SSH3); + 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); + radioline(&cp, "Preferred encryption algorithm:", IDC_CIPHERSTATIC, 4, + "&3DES", IDC_CIPHER3DES, + "&Blowfish", IDC_CIPHERBLOWF, + "&DES", IDC_CIPHERDES, + "AE&S", IDC_CIPHERAES, + NULL); + checkbox(&cp, "&Imitate SSH 2 MAC bug in commercial <= v2.3.x", + IDC_BUGGYMAC); + endbox(&cp); + } + } + + if (panel == tunnelspanelstart) { + /* The Tunnels panel. Accelerators used: [acgo] ex */ + 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 options", + IDC_BOX_TUNNELS); + checkbox(&cp, "&Enable X11 forwarding", + IDC_X11_FORWARD); + multiedit(&cp, "&X display location", IDC_X11_DISPSTATIC, + IDC_X11_DISPLAY, 50, NULL); + endbox(&cp); + } + } +} + +/* + * This function is the configuration box. */ static int GenericMainDlgProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, @@ -1214,10 +1208,13 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg, CHOOSEFONT cf; LOGFONT lf; char fontstatic[256]; + char portname[32]; + struct servent * service; int i; switch (msg) { case WM_INITDIALOG: + readytogo = 0; SetWindowLong(hwnd, GWL_USERDATA, 0); /* * Centre the window. @@ -1252,7 +1249,7 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg, SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0)); r.left = 3; r.right = r.left + 75; - r.top = 13; r.bottom = r.top + 196; + r.top = 13; r.bottom = r.top + 206; MapDialogRect(hwnd, &r); treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "", WS_CHILD | WS_VISIBLE | @@ -1269,331 +1266,31 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg, } /* - * Create the various panelfuls of controls. + * Set up the tree view contents. */ - - /* The Session panel. Accelerators used: [acgo] nprthelsdx */ - { - 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", - IDC_BOX_SESSION1, IDC_BOXT_SESSION1); - multiedit(&cp, - "Host &Name", IDC_HOSTSTATIC, IDC_HOST, 75, - "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL); - if (backends[2].backend == NULL) { - /* this is PuTTYtel, so only two protocols available */ - radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3, - "&Raw", IDC_PROTRAW, - "&Telnet", IDC_PROTTELNET, NULL); - } else { - radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3, - "&Raw", IDC_PROTRAW, - "&Telnet", IDC_PROTTELNET, -#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, IDC_BOXT_SESSION2); - sesssaver(&cp, "Stor&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, 0); - checkbox(&cp, "Close Window on E&xit", IDC_CLOSEEXIT); - endbox(&cp); - - hsession = treeview_insert(&tvfaff, 0, "Session"); - } - - /* The Terminal panel. Accelerators used: [acgo] rmkh&dlbenu */ - { - struct ctlpos cp; - ctlposinit(&cp, hwnd, 80, 3, 13); - bartitle(&cp, "Options controlling the terminal emulation", - IDC_TITLE_TERMINAL); - beginbox(&cp, "Set the size of the terminal window", - IDC_BOX_TERMINAL1, IDC_BOXT_TERMINAL1); - multiedit(&cp, - "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50, - "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50, - NULL); - checkbox(&cp, "Loc&k window size against resizing", IDC_LOCKSIZE); - endbox(&cp); - beginbox(&cp, "Set the font used in the terminal window", - IDC_BOX_TERMINAL2, IDC_BOXT_TERMINAL2); - staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT); - endbox(&cp); - beginbox(&cp, "Set various terminal options", - IDC_BOX_TERMINAL3, IDC_BOXT_TERMINAL3); - 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, "&Beep enabled", IDC_BEEP); - checkbox(&cp, "Use background colour to &erase screen", IDC_BCE); - checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT); - checkbox(&cp, "&Use local terminal line discipline", IDC_LDISCTERM); - endbox(&cp); - - treeview_insert(&tvfaff, 0, "Terminal"); - } - - /* The Keyboard panel. Accelerators used: [acgo] h?srvlxvnpmie */ - { - 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, IDC_BOXT_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, 4, - "ESC[n&~", IDC_FUNCTILDE, - "&Linux", IDC_FUNCLINUX, - "&Xterm R6", IDC_FUNCXTERM, - "&VT400", IDC_FUNCVT400, NULL); - endbox(&cp); - beginbox(&cp, "Change the initial state of:", - IDC_BOX_KEYBOARD2, IDC_BOXT_KEYBOARD2); - radioline(&cp, "Initial state of cursor keys:", IDC_CURSTATIC, 2, - "&Normal", IDC_CURNORMAL, - "A&pplication", IDC_CURAPPLIC, NULL); - radioline(&cp, "Initial state of numeric keypad:", IDC_KPSTATIC, 3, - "Nor&mal", IDC_KPNORMAL, - "Appl&ication", IDC_KPAPPLIC, - "N&etHack", IDC_KPNH, NULL); - endbox(&cp); - - treeview_insert(&tvfaff, 1, "Keyboard"); - } - - /* The Window panel. Accelerators used: [acgo] tibsdkw4y */ - { - struct ctlpos cp; - ctlposinit(&cp, hwnd, 80, 3, 13); - bartitle(&cp, "Options controlling PuTTY's window", - IDC_TITLE_WINDOW); - beginbox(&cp, "Adjust the use of the window title", - IDC_BOX_WINDOW1, IDC_BOXT_WINDOW1); - if (dlgtype == 0) - multiedit(&cp, - "Initial 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 cursor", - IDC_BOX_WINDOW2, IDC_BOXT_WINDOW2); - checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR); - endbox(&cp); - beginbox(&cp, "Control the scrollback in the window", - IDC_BOX_WINDOW3, IDC_BOXT_WINDOW3); - staticedit(&cp, "Lines of &scrollback", - IDC_SAVESTATIC, IDC_SAVEEDIT, 50); - checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR); - checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY); - endbox(&cp); - beginbox(&cp, NULL, IDC_BOX_WINDOW4, 0); - 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); - endbox(&cp); - - treeview_insert(&tvfaff, 0, "Window"); - } - - /* The Translation panel. Accelerators used: [acgo] xbepnkis */ - { - struct ctlpos cp; - ctlposinit(&cp, hwnd, 80, 3, 13); - bartitle(&cp, "Options controlling character set translation", - IDC_TITLE_TRANSLATION); - beginbox(&cp, "Adjust how PuTTY displays line drawing characters", - IDC_BOX_TRANSLATION1, IDC_BOXT_TRANSLATION1); - 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, NULL); - endbox(&cp); - beginbox(&cp, "Enable character set translation on received data", - IDC_BOX_TRANSLATION2, IDC_BOXT_TRANSLATION2); - radiobig(&cp, - "Character set translation:", IDC_XLATSTATIC, - "&None", IDC_NOXLAT, - "&KOI8 / Win-1251", IDC_KOI8WIN1251, - "&ISO-8859-2 / Win-1250", IDC_88592WIN1250, - "&ISO-8859-2 / CP852", IDC_88592CP852, NULL); - endbox(&cp); - beginbox(&cp, "Enable character set translation on input data", - IDC_BOX_TRANSLATION3, IDC_BOXT_TRANSLATION3); - checkbox(&cp, "CAP&S LOCK acts as cyrillic switch", - IDC_CAPSLOCKCYR); - endbox(&cp); - - treeview_insert(&tvfaff, 1, "Translation"); - } - - /* The Selection panel. Accelerators used: [acgo] wxst */ - { - struct ctlpos cp; - ctlposinit(&cp, hwnd, 80, 3, 13); - bartitle(&cp, "Options controlling copy and paste", - IDC_TITLE_SELECTION); - beginbox(&cp, "Control which mouse button does which thing", - IDC_BOX_SELECTION1, IDC_BOXT_SELECTION1); - radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC, - "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS, - "&xterm (Right extends, Middle pastes)", IDC_MBXTERM, - NULL); - endbox(&cp); - beginbox(&cp, "Control the select-one-word-at-a-time mode", - IDC_BOX_SELECTION2, IDC_BOXT_SELECTION2); - charclass(&cp, "Character classes:", IDC_CCSTATIC, IDC_CCLIST, - "&Set", IDC_CCSET, IDC_CCEDIT, - "&to class", IDC_CCSTATIC2); - endbox(&cp); - - treeview_insert(&tvfaff, 1, "Selection"); - } - - /* 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, IDC_BOXT_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, IDC_BOXT_COLOURS2); - colouredit(&cp, "Select a colo&ur and then click to modify it:", - IDC_STATIC, IDC_LIST, - "&Modify...", IDC_CHANGE, - "Red:", IDC_RSTATIC, IDC_RVALUE, - "Green:", IDC_GSTATIC, IDC_GVALUE, - "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL); - endbox(&cp); - - treeview_insert(&tvfaff, 1, "Colours"); - } - - /* The Connection panel. Accelerators used: [acgo] tuk */ - { - 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, IDC_BOXT_CONNECTION1); - staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC, IDC_TTEDIT, 50); - staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC, IDC_LOGEDIT, 50); - endbox(&cp); + 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, "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"); + treeview_insert(&tvfaff, 2, "Tunnels"); } - beginbox(&cp, "Sending of null packets to keep session active", - IDC_BOX_CONNECTION2, IDC_BOXT_CONNECTION2); - staticedit(&cp, "Minutes between &keepalives (0 to turn off)", - IDC_PINGSTATIC, IDC_PINGEDIT, 25); - endbox(&cp); - - treeview_insert(&tvfaff, 0, "Connection"); } - /* The Telnet panel. Accelerators used: [acgo] svldrbf */ - { - 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, IDC_BOXT_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, IDC_BOXT_TELNET2); - radioline(&cp, "Handling of OLD_ENVIRON ambiguity:", IDC_EMSTATIC, 2, - "&BSD (commonplace)", IDC_EMBSD, - "R&FC 1408 (unusual)", IDC_EMRFC, NULL); - endbox(&cp); - - treeview_insert(&tvfaff, 1, "Telnet"); - } - } - - /* The SSH panel. Accelerators used: [acgo] rmakwp123bd */ - { - 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, IDC_BOXT_SSH1); - multiedit(&cp, - "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100, - NULL); - endbox(&cp); - beginbox(&cp, "Authentication options", - IDC_BOX_SSH2, IDC_BOXT_SSH2); - checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication", - IDC_AUTHTIS); - checkbox(&cp, "Allow &agent forwarding", IDC_AGENTFWD); - editbutton(&cp, "Private &key file for authentication:", - IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...", IDC_PKBUTTON); - endbox(&cp); - beginbox(&cp, "Protocol options", - IDC_BOX_SSH3, IDC_BOXT_SSH3); - checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY); - radioline(&cp, "Preferred SSH protocol version:", - IDC_SSHPROTSTATIC, 2, - "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL); - radioline(&cp, "Preferred encryption algorithm:", IDC_CIPHERSTATIC, 3, - "&3DES", IDC_CIPHER3DES, - "&Blowfish", IDC_CIPHERBLOWF, - "&DES", IDC_CIPHERDES, NULL); - endbox(&cp); - - treeview_insert(&tvfaff, 1, "SSH"); - } - } - - init_dlg_ctrls(hwnd); - for (i = 0; i < nsessions; i++) - SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING, - 0, (LPARAM) (sessions[i])); - - /* - * Hide all the controls to start with. - */ - hide(hwnd, TRUE, controlstartvalue, controlendvalue); - /* * Put the treeview selection on to the Session panel. This - * should also cause unhiding of the relevant controls. + * should also cause creation of the relevant controls. */ TreeView_SelectItem(treeview, hsession); @@ -1623,33 +1320,50 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg, ((LPNMHDR)lParam)->code == TVN_SELCHANGED) { HTREEITEM i = TreeView_GetSelection(((LPNMHDR)lParam)->hwndFrom); TVITEM item; + int j; char buffer[64]; item.hItem = i; item.pszText = buffer; item.cchTextMax = sizeof(buffer); item.mask = TVIF_TEXT; TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &item); - hide(hwnd, TRUE, controlstartvalue, controlendvalue); + for (j = controlstartvalue; j < controlendvalue; j++) { + HWND item = GetDlgItem(hwnd, j); + if (item) + DestroyWindow(item); + } if (!strcmp(buffer, "Session")) - hide(hwnd, FALSE, sessionpanelstart, sessionpanelend); + create_controls(hwnd, dlgtype, sessionpanelstart); + if (!strcmp(buffer, "Logging")) + create_controls(hwnd, dlgtype, loggingpanelstart); if (!strcmp(buffer, "Keyboard")) - hide(hwnd, FALSE, keyboardpanelstart, keyboardpanelend); + create_controls(hwnd, dlgtype, keyboardpanelstart); if (!strcmp(buffer, "Terminal")) - hide(hwnd, FALSE, terminalpanelstart, terminalpanelend); + create_controls(hwnd, dlgtype, terminalpanelstart); + if (!strcmp(buffer, "Bell")) + create_controls(hwnd, dlgtype, bellpanelstart); if (!strcmp(buffer, "Window")) - hide(hwnd, FALSE, windowpanelstart, windowpanelend); + create_controls(hwnd, dlgtype, windowpanelstart); + if (!strcmp(buffer, "Appearance")) + create_controls(hwnd, dlgtype, appearancepanelstart); + if (!strcmp(buffer, "Tunnels")) + create_controls(hwnd, dlgtype, tunnelspanelstart); if (!strcmp(buffer, "Connection")) - hide(hwnd, FALSE, connectionpanelstart, connectionpanelend); + create_controls(hwnd, dlgtype, connectionpanelstart); if (!strcmp(buffer, "Telnet")) - hide(hwnd, FALSE, telnetpanelstart, telnetpanelend); + create_controls(hwnd, dlgtype, telnetpanelstart); + if (!strcmp(buffer, "Rlogin")) + create_controls(hwnd, dlgtype, rloginpanelstart); if (!strcmp(buffer, "SSH")) - hide(hwnd, FALSE, sshpanelstart, sshpanelend); + create_controls(hwnd, dlgtype, sshpanelstart); if (!strcmp(buffer, "Selection")) - hide(hwnd, FALSE, selectionpanelstart, selectionpanelend); + create_controls(hwnd, dlgtype, selectionpanelstart); if (!strcmp(buffer, "Colours")) - hide(hwnd, FALSE, colourspanelstart, colourspanelend); + create_controls(hwnd, dlgtype, colourspanelstart); if (!strcmp(buffer, "Translation")) - hide(hwnd, FALSE, translationpanelstart, translationpanelend); + create_controls(hwnd, dlgtype, translationpanelstart); + + init_dlg_ctrls(hwnd); SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */ return 0; @@ -1670,16 +1384,19 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg, 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); - cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : PROT_RAW ; - if ((cfg.protocol == PROT_SSH && cfg.port == 23) || - (cfg.protocol == PROT_TELNET && cfg.port == 22)) { - cfg.port = i ? 22 : 23; + 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); } } @@ -1690,8 +1407,16 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg, sizeof(cfg.host)-1); break; case IDC_PORT: - if (HIWORD(wParam) == EN_CHANGE) - MyGetDlgItemInt (hwnd, IDC_PORT, &cfg.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) { @@ -1753,6 +1478,8 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg, init_dlg_ctrls(hwnd); if (!isdef) SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]); + else + SetDlgItemText(hwnd, IDC_SESSEDIT, ""); } if (LOWORD(wParam) == IDC_SESSLIST) { /* @@ -1803,21 +1530,22 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg, HIWORD(wParam) == BN_DOUBLECLICKED) cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC_HOMERXVT); break; - case IDC_FUNCXTERM: - if (HIWORD(wParam) == BN_CLICKED || - HIWORD(wParam) == BN_DOUBLECLICKED) - cfg.funky_type = 2; - break; - case IDC_FUNCVT400: - if (HIWORD(wParam) == BN_CLICKED || - HIWORD(wParam) == BN_DOUBLECLICKED) - cfg.funky_type = 3; - 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) - cfg.funky_type = IsDlgButtonChecked (hwnd, IDC_FUNCLINUX); + 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: @@ -1840,6 +1568,16 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg, 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) @@ -1850,16 +1588,61 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg, HIWORD(wParam) == BN_DOUBLECLICKED) cfg.alt_space = IsDlgButtonChecked (hwnd, IDC_ALTSPACE); break; - case IDC_LDISCTERM: + case IDC_ALTONLY: if (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == BN_DOUBLECLICKED) - cfg.ldisc_term = IsDlgButtonChecked (hwnd, IDC_LDISCTERM); + 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_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_WRAPMODE: if (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == BN_DOUBLECLICKED) @@ -1911,16 +1694,67 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg, cfg.font[sizeof(cfg.font)-1] = '\0'; cfg.fontisbold = (lf.lfWeight == FW_BOLD); cfg.fontcharset = lf.lfCharSet; - cfg.fontheight = lf.lfHeight; + cfg.fontheight = cf.iPointSize / 10; fmtfont (fontstatic); SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic); } break; - case IDC_BEEP: + 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_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.beep = IsDlgButtonChecked (hwnd, IDC_BEEP); + 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) @@ -1936,6 +1770,31 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg, 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_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) @@ -1956,11 +1815,16 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg, GetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle, sizeof(cfg.wintitle)-1); break; - case IDC_CLOSEEXIT: - if (HIWORD(wParam) == BN_CLICKED || - HIWORD(wParam) == BN_DOUBLECLICKED) - cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC_CLOSEEXIT); - 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) @@ -1971,9 +1835,57 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg, 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: + if (HIWORD(wParam) == BN_CLICKED || + HIWORD(wParam) == BN_DOUBLECLICKED) { + if (IsDlgButtonChecked (hwnd, IDC_LSTATOFF)) cfg.logtype = 0; + if (IsDlgButtonChecked (hwnd, IDC_LSTATASCII)) cfg.logtype = 1; + if (IsDlgButtonChecked (hwnd, IDC_LSTATRAW)) cfg.logtype = 2; + } + 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, IDC_TSEDIT, cfg.termspeed, + GetDlgItemText (hwnd, LOWORD(wParam), cfg.termspeed, sizeof(cfg.termspeed)-1); break; case IDC_LOGEDIT: @@ -1981,6 +1893,11 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg, 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); @@ -2059,6 +1976,16 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg, 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_AGENTFWD: if (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == BN_DOUBLECLICKED) @@ -2067,6 +1994,7 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg, case IDC_CIPHER3DES: case IDC_CIPHERBLOWF: case IDC_CIPHERDES: + case IDC_CIPHERAES: if (HIWORD(wParam) == BN_CLICKED || HIWORD(wParam) == BN_DOUBLECLICKED) { if (IsDlgButtonChecked (hwnd, IDC_CIPHER3DES)) @@ -2075,6 +2003,8 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg, cfg.cipher = CIPHER_BLOWFISH; else if (IsDlgButtonChecked (hwnd, IDC_CIPHERDES)) cfg.cipher = CIPHER_DES; + else if (IsDlgButtonChecked (hwnd, IDC_CIPHERAES)) + cfg.cipher = CIPHER_AES; } break; case IDC_SSHPROT1: @@ -2124,6 +2054,8 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg, SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile); } break; + case IDC_RAWCNP: + cfg.rawcnp = IsDlgButtonChecked (hwnd, IDC_RAWCNP); case IDC_MBWINDOWS: case IDC_MBXTERM: cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC_MBXTERM); @@ -2159,18 +2091,16 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg, HIWORD(wParam) == BN_DOUBLECLICKED) { int n, i; cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC_BOLDCOLOUR); - n = SendDlgItemMessage (hwnd, IDC_LIST, LB_GETCOUNT, 0, 0); - if (cfg.bold_colour && n!=22) { - for (i=0; i<22; i++) - if (!permcolour[i]) - SendDlgItemMessage (hwnd, IDC_LIST, - LB_INSERTSTRING, i, - (LPARAM) colours[i]); - } else if (!cfg.bold_colour && n!=12) { - for (i=22; i-- ;) - if (!permcolour[i]) - SendDlgItemMessage (hwnd, IDC_LIST, + 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]); } } break; @@ -2179,10 +2109,10 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg, HIWORD(wParam) == BN_DOUBLECLICKED) cfg.try_palette = IsDlgButtonChecked (hwnd, IDC_PALETTE); break; - case IDC_LIST: + case IDC_COLOURLIST: if (HIWORD(wParam) == LBN_DBLCLK || HIWORD(wParam) == LBN_SELCHANGE) { - int i = SendDlgItemMessage (hwnd, IDC_LIST, LB_GETCURSEL, + 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); @@ -2196,7 +2126,7 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg, HIWORD(wParam) == BN_DOUBLECLICKED) { static CHOOSECOLOR cc; static DWORD custom[16] = {0}; /* zero initialisers */ - int i = SendDlgItemMessage (hwnd, IDC_LIST, LB_GETCURSEL, + 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); @@ -2251,6 +2181,16 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg, IsDlgButtonChecked (hwnd, IDC_VTOEMONLY) ? VT_OEMONLY : 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_X11_DISPLAY: + if (HIWORD(wParam) == EN_CHANGE) + GetDlgItemText (hwnd, IDC_X11_DISPLAY, cfg.x11_display, + sizeof(cfg.x11_display)-1); + break; } return 0; case WM_CLOSE: @@ -2268,8 +2208,6 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg, static int CALLBACK MainDlgProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { - static HWND page = NULL; - if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) { } if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) { @@ -2284,10 +2222,24 @@ static int CALLBACK MainDlgProc (HWND hwnd, UINT msg, static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { - static HWND page; return GenericMainDlgProc (hwnd, msg, wParam, lParam, 1); } +void defuse_showwindow(void) { + /* + * Work around the fact that the app's first call to ShowWindow + * will ignore the default in favour of the shell-provided + * setting. + */ + { + HWND hwnd; + hwnd = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), + NULL, NullDlgProc); + ShowWindow(hwnd, SW_HIDE); + DestroyWindow(hwnd); + } +} + int do_config (void) { int ret; @@ -2307,27 +2259,33 @@ int do_reconfig (HWND hwnd) { ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc); if (!ret) cfg = backup_cfg; /* structure copy */ - else - force_normal(hwnd); return ret; } void logevent (char *string) { + char timebuf[40]; + time_t t; + if (nevents >= negsize) { negsize += 64; events = srealloc (events, negsize * sizeof(*events)); } - events[nevents] = smalloc(1+strlen(string)); - strcpy (events[nevents], string); - nevents++; + + time(&t); + strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S\t", localtime(&t)); + + events[nevents] = smalloc(strlen(timebuf)+strlen(string)+1); + strcpy(events[nevents], timebuf); + strcat(events[nevents], string); if (logbox) { int count; SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING, - 0, (LPARAM)string); + 0, (LPARAM)events[nevents]); count = SendDlgItemMessage (logbox, IDN_LIST, LB_GETCOUNT, 0, 0); SendDlgItemMessage (logbox, IDN_LIST, LB_SETTOPINDEX, count-1, 0); } + nevents++; } void showeventlog (HWND hwnd) { @@ -2336,14 +2294,11 @@ void showeventlog (HWND hwnd) { hwnd, LogProc); ShowWindow (logbox, SW_SHOWNORMAL); } + SetActiveWindow(logbox); } void showabout (HWND hwnd) { - if (!abtbox) { - abtbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), - hwnd, AboutProc); - ShowWindow (abtbox, SW_SHOWNORMAL); - } + DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),hwnd, AboutProc); } void verify_ssh_host_key(char *host, int port, char *keytype, @@ -2413,3 +2368,33 @@ void verify_ssh_host_key(char *host, int port, char *keytype, store_host_key(host, port, keytype, keystr); } } + +/* + * 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) { + static const char mbtitle[] = "PuTTY Log to File"; + static const char msgtemplate[] = + "The session log file \"%.*s\" already exists.\n" + "You can overwrite it with a new session log,\n" + "append your session log to the end of it,\n" + "or disable session logging for this session.\n" + "Hit Yes to wipe the file, No to append to it,\n" + "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); + + mbret = MessageBox(NULL, message, mbtitle, + MB_ICONQUESTION | MB_YESNOCANCEL); + if (mbret == IDYES) + return 2; + else if (mbret == IDNO) + return 1; + else + return 0; +}