19 #define MAIN_NPANELS 8
20 #define RECONF_NPANELS 5
22 static const char *const puttystr = PUTTY_REG_POS "\\Sessions";
24 static char **events = NULL;
25 static int nevents = 0, negsize = 0;
27 static HWND logbox = NULL, abtbox = NULL;
29 static char hex[16] = "0123456789ABCDEF";
31 static void mungestr(char *in, char *out) {
35 if (*in == ' ' || *in == '\\' || *in == '*' || *in == '?' ||
36 *in == '%' || *in < ' ' || *in > '~' || (*in == '.' && !candot)) {
38 *out++ = hex[((unsigned char)*in) >> 4];
39 *out++ = hex[((unsigned char)*in) & 15];
49 static void unmungestr(char *in, char *out) {
51 if (*in == '%' && in[1] && in[2]) {
54 i = in[1] - '0'; i -= (i > 9 ? 7 : 0);
55 j = in[2] - '0'; j -= (j > 9 ? 7 : 0);
66 static void wpps(HKEY key, LPCTSTR name, LPCTSTR value) {
67 RegSetValueEx(key, name, 0, REG_SZ, value, 1+strlen(value));
70 static void wppi(HKEY key, LPCTSTR name, int value) {
71 RegSetValueEx(key, name, 0, REG_DWORD,
72 (CONST BYTE *)&value, sizeof(value));
75 static void gpps(HKEY key, LPCTSTR name, LPCTSTR def,
76 LPTSTR val, int len) {
81 RegQueryValueEx(key, name, 0, &type, val, &size) != ERROR_SUCCESS ||
83 strncpy(val, def, len);
88 static void gppi(HKEY key, LPCTSTR name, int def, int *i) {
89 DWORD type, val, size;
93 RegQueryValueEx(key, name, 0, &type,
94 (BYTE *)&val, &size) != ERROR_SUCCESS ||
95 size != sizeof(val) || type != REG_DWORD)
101 static HINSTANCE hinst;
103 static int readytogo;
105 static void save_settings (char *section, int do_host) {
107 HKEY subkey1, sesskey;
110 p = malloc(3*strlen(section)+1);
111 mungestr(section, p);
113 if (RegCreateKey(HKEY_CURRENT_USER, puttystr, &subkey1)!=ERROR_SUCCESS ||
114 RegCreateKey(subkey1, p, &sesskey) != ERROR_SUCCESS) {
119 RegCloseKey(subkey1);
121 wppi (sesskey, "Present", 1);
123 wpps (sesskey, "HostName", cfg.host);
124 wppi (sesskey, "PortNumber", cfg.port);
126 for (i = 0; backends[i].name != NULL; i++)
127 if (backends[i].protocol == cfg.protocol) {
128 p = backends[i].name;
131 wpps (sesskey, "Protocol", p);
133 wppi (sesskey, "CloseOnExit", !!cfg.close_on_exit);
134 wppi (sesskey, "WarnOnClose", !!cfg.warn_on_close);
135 wpps (sesskey, "TerminalType", cfg.termtype);
136 wpps (sesskey, "TerminalSpeed", cfg.termspeed);
138 char buf[2*sizeof(cfg.environmt)], *p, *q;
144 if (c == '=' || c == ',' || c == '\\')
154 wpps (sesskey, "Environment", buf);
156 wpps (sesskey, "UserName", cfg.username);
157 wppi (sesskey, "NoPTY", cfg.nopty);
158 wppi (sesskey, "AgentFwd", cfg.agentfwd);
159 wpps (sesskey, "RemoteCmd", cfg.remote_cmd);
160 wpps (sesskey, "Cipher", cfg.cipher == CIPHER_BLOWFISH ? "blowfish" :
161 cfg.cipher == CIPHER_DES ? "des" : "3des");
162 wppi (sesskey, "AuthTIS", cfg.try_tis_auth);
163 wppi (sesskey, "SshProt", cfg.sshprot);
164 wpps (sesskey, "PublicKeyFile", cfg.keyfile);
165 wppi (sesskey, "RFCEnviron", cfg.rfc_environ);
166 wppi (sesskey, "BackspaceIsDelete", cfg.bksp_is_delete);
167 wppi (sesskey, "RXVTHomeEnd", cfg.rxvt_homeend);
168 wppi (sesskey, "LinuxFunctionKeys", cfg.funky_type);
169 wppi (sesskey, "ApplicationCursorKeys", cfg.app_cursor);
170 wppi (sesskey, "ApplicationKeypad", cfg.app_keypad);
171 wppi (sesskey, "NetHackKeypad", cfg.nethack_keypad);
172 wppi (sesskey, "AltF4", cfg.alt_f4);
173 wppi (sesskey, "AltSpace", cfg.alt_space);
174 wppi (sesskey, "LdiscTerm", cfg.ldisc_term);
175 wppi (sesskey, "BlinkCur", cfg.blink_cur);
176 wppi (sesskey, "Beep", cfg.beep);
177 wppi (sesskey, "ScrollbackLines", cfg.savelines);
178 wppi (sesskey, "DECOriginMode", cfg.dec_om);
179 wppi (sesskey, "AutoWrapMode", cfg.wrap_mode);
180 wppi (sesskey, "LFImpliesCR", cfg.lfhascr);
181 wppi (sesskey, "WinNameAlways", cfg.win_name_always);
182 wppi (sesskey, "TermWidth", cfg.width);
183 wppi (sesskey, "TermHeight", cfg.height);
184 wpps (sesskey, "Font", cfg.font);
185 wppi (sesskey, "FontIsBold", cfg.fontisbold);
186 wppi (sesskey, "FontCharSet", cfg.fontcharset);
187 wppi (sesskey, "FontHeight", cfg.fontheight);
188 wppi (sesskey, "FontVTMode", cfg.vtmode);
189 wppi (sesskey, "TryPalette", cfg.try_palette);
190 wppi (sesskey, "BoldAsColour", cfg.bold_colour);
191 for (i=0; i<22; i++) {
192 char buf[20], buf2[30];
193 sprintf(buf, "Colour%d", i);
194 sprintf(buf2, "%d,%d,%d", cfg.colours[i][0],
195 cfg.colours[i][1], cfg.colours[i][2]);
196 wpps (sesskey, buf, buf2);
198 wppi (sesskey, "MouseIsXterm", cfg.mouse_is_xterm);
199 for (i=0; i<256; i+=32) {
200 char buf[20], buf2[256];
202 sprintf(buf, "Wordness%d", i);
204 for (j=i; j<i+32; j++) {
205 sprintf(buf2+strlen(buf2), "%s%d",
206 (*buf2 ? "," : ""), cfg.wordness[j]);
208 wpps (sesskey, buf, buf2);
210 wppi (sesskey, "KoiWinXlat", cfg.xlat_enablekoiwin);
211 wppi (sesskey, "88592Xlat", cfg.xlat_88592w1250);
212 wppi (sesskey, "CapsLockCyr", cfg.xlat_capslockcyr);
213 wppi (sesskey, "ScrollBar", cfg.scrollbar);
214 wppi (sesskey, "ScrollOnKey", cfg.scroll_on_key);
215 wppi (sesskey, "LockSize", cfg.locksize);
216 wppi (sesskey, "BCE", cfg.bce);
217 wppi (sesskey, "BlinkText", cfg.blinktext);
219 RegCloseKey(sesskey);
222 static void del_session (char *section) {
226 if (RegOpenKey(HKEY_CURRENT_USER, puttystr, &subkey1) != ERROR_SUCCESS)
229 p = malloc(3*strlen(section)+1);
230 mungestr(section, p);
231 RegDeleteKey(subkey1, p);
234 RegCloseKey(subkey1);
237 static void load_settings (char *section, int do_host) {
239 HKEY subkey1, sesskey;
243 p = malloc(3*strlen(section)+1);
244 mungestr(section, p);
246 if (RegOpenKey(HKEY_CURRENT_USER, puttystr, &subkey1) != ERROR_SUCCESS) {
249 if (RegOpenKey(subkey1, p, &sesskey) != ERROR_SUCCESS) {
252 RegCloseKey(subkey1);
257 gpps (sesskey, "HostName", "", cfg.host, sizeof(cfg.host));
258 gppi (sesskey, "PortNumber", default_port, &cfg.port);
260 gpps (sesskey, "Protocol", "default", prot, 10);
261 cfg.protocol = default_protocol;
262 for (i = 0; backends[i].name != NULL; i++)
263 if (!strcmp(prot, backends[i].name)) {
264 cfg.protocol = backends[i].protocol;
268 gppi (sesskey, "CloseOnExit", 1, &cfg.close_on_exit);
269 gppi (sesskey, "WarnOnClose", 1, &cfg.warn_on_close);
270 gpps (sesskey, "TerminalType", "xterm", cfg.termtype,
271 sizeof(cfg.termtype));
272 gpps (sesskey, "TerminalSpeed", "38400,38400", cfg.termspeed,
273 sizeof(cfg.termspeed));
275 char buf[2*sizeof(cfg.environmt)], *p, *q;
276 gpps (sesskey, "Environment", "", buf, sizeof(buf));
280 while (*p && *p != ',') {
293 gpps (sesskey, "UserName", "", cfg.username, sizeof(cfg.username));
294 gppi (sesskey, "NoPTY", 0, &cfg.nopty);
295 gppi (sesskey, "AgentFwd", 0, &cfg.agentfwd);
296 gpps (sesskey, "RemoteCmd", "", cfg.remote_cmd, sizeof(cfg.remote_cmd));
299 gpps (sesskey, "Cipher", "3des", cipher, 10);
300 if (!strcmp(cipher, "blowfish"))
301 cfg.cipher = CIPHER_BLOWFISH;
302 else if (!strcmp(cipher, "des"))
303 cfg.cipher = CIPHER_DES;
305 cfg.cipher = CIPHER_3DES;
307 gppi (sesskey, "SshProt", 1, &cfg.sshprot);
308 gppi (sesskey, "AuthTIS", 0, &cfg.try_tis_auth);
309 gpps (sesskey, "PublicKeyFile", "", cfg.keyfile, sizeof(cfg.keyfile));
310 gppi (sesskey, "RFCEnviron", 0, &cfg.rfc_environ);
311 gppi (sesskey, "BackspaceIsDelete", 1, &cfg.bksp_is_delete);
312 gppi (sesskey, "RXVTHomeEnd", 0, &cfg.rxvt_homeend);
313 gppi (sesskey, "LinuxFunctionKeys", 0, &cfg.funky_type);
314 gppi (sesskey, "ApplicationCursorKeys", 0, &cfg.app_cursor);
315 gppi (sesskey, "ApplicationKeypad", 0, &cfg.app_keypad);
316 gppi (sesskey, "NetHackKeypad", 0, &cfg.nethack_keypad);
317 gppi (sesskey, "AltF4", 1, &cfg.alt_f4);
318 gppi (sesskey, "AltSpace", 0, &cfg.alt_space);
319 gppi (sesskey, "LdiscTerm", 0, &cfg.ldisc_term);
320 gppi (sesskey, "BlinkCur", 0, &cfg.blink_cur);
321 gppi (sesskey, "Beep", 1, &cfg.beep);
322 gppi (sesskey, "ScrollbackLines", 200, &cfg.savelines);
323 gppi (sesskey, "DECOriginMode", 0, &cfg.dec_om);
324 gppi (sesskey, "AutoWrapMode", 1, &cfg.wrap_mode);
325 gppi (sesskey, "LFImpliesCR", 0, &cfg.lfhascr);
326 gppi (sesskey, "WinNameAlways", 0, &cfg.win_name_always);
327 gppi (sesskey, "TermWidth", 80, &cfg.width);
328 gppi (sesskey, "TermHeight", 24, &cfg.height);
329 gpps (sesskey, "Font", "Courier", cfg.font, sizeof(cfg.font));
330 gppi (sesskey, "FontIsBold", 0, &cfg.fontisbold);
331 gppi (sesskey, "FontCharSet", ANSI_CHARSET, &cfg.fontcharset);
332 gppi (sesskey, "FontHeight", 10, &cfg.fontheight);
333 gppi (sesskey, "FontVTMode", VT_OEMANSI, (int *)&cfg.vtmode);
334 gppi (sesskey, "TryPalette", 0, &cfg.try_palette);
335 gppi (sesskey, "BoldAsColour", 1, &cfg.bold_colour);
336 for (i=0; i<22; i++) {
337 static char *defaults[] = {
338 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
339 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
340 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
341 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
342 "85,255,255", "187,187,187", "255,255,255"
344 char buf[20], buf2[30];
346 sprintf(buf, "Colour%d", i);
347 gpps (sesskey, buf, defaults[i], buf2, sizeof(buf2));
348 if(sscanf(buf2, "%d,%d,%d", &c0, &c1, &c2) == 3) {
349 cfg.colours[i][0] = c0;
350 cfg.colours[i][1] = c1;
351 cfg.colours[i][2] = c2;
354 gppi (sesskey, "MouseIsXterm", 0, &cfg.mouse_is_xterm);
355 for (i=0; i<256; i+=32) {
356 static char *defaults[] = {
357 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
358 "0,1,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1",
359 "1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,2",
360 "1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1",
361 "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1",
362 "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1",
363 "2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2",
364 "2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2"
366 char buf[20], buf2[256], *p;
368 sprintf(buf, "Wordness%d", i);
369 gpps (sesskey, buf, defaults[i/32], buf2, sizeof(buf2));
371 for (j=i; j<i+32; j++) {
373 while (*p && *p != ',') p++;
374 if (*p == ',') *p++ = '\0';
375 cfg.wordness[j] = atoi(q);
378 gppi (sesskey, "KoiWinXlat", 0, &cfg.xlat_enablekoiwin);
379 gppi (sesskey, "88592Xlat", 0, &cfg.xlat_88592w1250);
380 gppi (sesskey, "CapsLockCyr", 0, &cfg.xlat_capslockcyr);
381 gppi (sesskey, "ScrollBar", 1, &cfg.scrollbar);
382 gppi (sesskey, "ScrollOnKey", 0, &cfg.scroll_on_key);
383 gppi (sesskey, "LockSize", 0, &cfg.locksize);
384 gppi (sesskey, "BCE", 0, &cfg.bce);
385 gppi (sesskey, "BlinkText", 0, &cfg.blinktext);
387 RegCloseKey(sesskey);
390 static void force_normal(HWND hwnd)
392 static int recurse = 0;
399 wp.length = sizeof(wp);
400 if (GetWindowPlacement(hwnd, &wp))
402 wp.showCmd = SW_SHOWNORMAL;
403 SetWindowPlacement(hwnd, &wp);
408 static void MyGetDlgItemInt (HWND hwnd, int id, int *result) {
411 n = GetDlgItemInt (hwnd, id, &ok, FALSE);
416 static int CALLBACK LogProc (HWND hwnd, UINT msg,
417 WPARAM wParam, LPARAM lParam) {
422 for (i=0; i<nevents; i++)
423 SendDlgItemMessage (hwnd, IDN_LIST, LB_ADDSTRING,
424 0, (LPARAM)events[i]);
426 /* case WM_CTLCOLORDLG: */
427 /* return (int) GetStockObject (LTGRAY_BRUSH); */
429 switch (LOWORD(wParam)) {
432 DestroyWindow (hwnd);
438 DestroyWindow (hwnd);
444 static int CALLBACK LicenceProc (HWND hwnd, UINT msg,
445 WPARAM wParam, LPARAM lParam) {
450 switch (LOWORD(wParam)) {
453 DestroyWindow (hwnd);
459 DestroyWindow (hwnd);
465 static int CALLBACK AboutProc (HWND hwnd, UINT msg,
466 WPARAM wParam, LPARAM lParam) {
469 SetDlgItemText (hwnd, IDA_VERSION, ver);
471 /* case WM_CTLCOLORDLG: */
472 /* return (int) GetStockObject (LTGRAY_BRUSH); */
473 /* case WM_CTLCOLORSTATIC: */
474 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
475 /* return (int) GetStockObject (LTGRAY_BRUSH); */
477 switch (LOWORD(wParam)) {
480 DestroyWindow (hwnd);
483 EnableWindow(hwnd, 0);
484 DialogBox (hinst, MAKEINTRESOURCE(IDD_LICENCEBOX),
486 EnableWindow(hwnd, 1);
487 SetActiveWindow(hwnd);
493 DestroyWindow (hwnd);
499 static int GeneralPanelProc (HWND hwnd, UINT msg,
500 WPARAM wParam, LPARAM lParam) {
503 SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
505 /* case WM_CTLCOLORDLG: */
506 /* return (int) GetStockObject (LTGRAY_BRUSH); */
507 /* case WM_CTLCOLORSTATIC: */
508 /* case WM_CTLCOLORBTN: */
509 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
510 /* return (int) GetStockObject (LTGRAY_BRUSH); */
512 DestroyWindow (hwnd);
518 static char savedsession[2048];
520 static int CALLBACK ConnectionProc (HWND hwnd, UINT msg,
521 WPARAM wParam, LPARAM lParam) {
526 SetDlgItemText (hwnd, IDC0_HOST, cfg.host);
527 SetDlgItemText (hwnd, IDC0_SESSEDIT, savedsession);
528 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
529 for (i = 0; i < nsessions; i++)
530 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
531 0, (LPARAM) (sessions[i]));
532 CheckRadioButton (hwnd, IDC0_PROTRAW, IDC0_PROTSSH,
533 cfg.protocol==PROT_SSH ? IDC0_PROTSSH :
534 cfg.protocol==PROT_TELNET ? IDC0_PROTTELNET : IDC0_PROTRAW );
535 CheckDlgButton (hwnd, IDC0_CLOSEEXIT, cfg.close_on_exit);
536 CheckDlgButton (hwnd, IDC0_CLOSEWARN, cfg.warn_on_close);
540 * Button release should trigger WM_OK if there was a
541 * previous double click on the session list.
545 SendMessage (GetParent(hwnd), WM_COMMAND, IDOK, 0);
548 switch (LOWORD(wParam)) {
549 case IDC0_PROTTELNET:
552 if (HIWORD(wParam) == BN_CLICKED ||
553 HIWORD(wParam) == BN_DOUBLECLICKED) {
554 int i = IsDlgButtonChecked (hwnd, IDC0_PROTSSH);
555 int j = IsDlgButtonChecked (hwnd, IDC0_PROTTELNET);
556 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : PROT_RAW ;
557 if ((cfg.protocol == PROT_SSH && cfg.port == 23) ||
558 (cfg.protocol == PROT_TELNET && cfg.port == 22)) {
559 cfg.port = i ? 22 : 23;
560 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
565 if (HIWORD(wParam) == EN_CHANGE)
566 GetDlgItemText (hwnd, IDC0_HOST, cfg.host,
570 if (HIWORD(wParam) == EN_CHANGE)
571 MyGetDlgItemInt (hwnd, IDC0_PORT, &cfg.port);
574 if (HIWORD(wParam) == BN_CLICKED ||
575 HIWORD(wParam) == BN_DOUBLECLICKED)
576 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC0_CLOSEEXIT);
579 if (HIWORD(wParam) == BN_CLICKED ||
580 HIWORD(wParam) == BN_DOUBLECLICKED)
581 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC0_CLOSEWARN);
584 if (HIWORD(wParam) == EN_CHANGE) {
585 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
587 GetDlgItemText (hwnd, IDC0_SESSEDIT,
588 savedsession, sizeof(savedsession)-1);
589 savedsession[sizeof(savedsession)-1] = '\0';
593 if (HIWORD(wParam) == BN_CLICKED ||
594 HIWORD(wParam) == BN_DOUBLECLICKED) {
599 GetDlgItemText (hwnd, IDC0_SESSEDIT, str, sizeof(str)-1);
601 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
607 strcpy (str, sessions[n]);
609 save_settings (str, !!strcmp(str, "Default Settings"));
610 get_sesslist (FALSE);
612 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_RESETCONTENT,
614 for (i = 0; i < nsessions; i++)
615 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
616 0, (LPARAM) (sessions[i]));
617 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
623 if (LOWORD(wParam) == IDC0_SESSLOAD &&
624 HIWORD(wParam) != BN_CLICKED &&
625 HIWORD(wParam) != BN_DOUBLECLICKED)
627 if (LOWORD(wParam) == IDC0_SESSLIST &&
628 HIWORD(wParam) != LBN_DBLCLK)
631 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
637 load_settings (sessions[n],
638 !!strcmp(sessions[n], "Default Settings"));
639 SetDlgItemText (hwnd, IDC0_HOST, cfg.host);
640 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
641 CheckRadioButton (hwnd, IDC0_PROTRAW, IDC0_PROTSSH,
642 (cfg.protocol==PROT_SSH ? IDC0_PROTSSH :
643 cfg.protocol==PROT_TELNET ? IDC0_PROTTELNET : IDC0_PROTRAW));
644 CheckDlgButton (hwnd, IDC0_CLOSEEXIT, cfg.close_on_exit);
645 CheckDlgButton (hwnd, IDC0_CLOSEWARN, cfg.warn_on_close);
646 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
649 if (LOWORD(wParam) == IDC0_SESSLIST) {
651 * A double-click on a saved session should
652 * actually start the session, not just load it.
653 * Unless it's Default Settings or some other
654 * host-less set of saved settings.
663 if (HIWORD(wParam) == BN_CLICKED ||
664 HIWORD(wParam) == BN_DOUBLECLICKED) {
665 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
667 if (n == LB_ERR || n == 0) {
671 del_session(sessions[n]);
672 get_sesslist (FALSE);
674 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_RESETCONTENT,
676 for (i = 0; i < nsessions; i++)
677 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
678 0, (LPARAM) (sessions[i]));
679 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
684 return GeneralPanelProc (hwnd, msg, wParam, lParam);
687 static int CALLBACK KeyboardProc (HWND hwnd, UINT msg,
688 WPARAM wParam, LPARAM lParam) {
691 CheckRadioButton (hwnd, IDC1_DEL008, IDC1_DEL127,
692 cfg.bksp_is_delete ? IDC1_DEL127 : IDC1_DEL008);
693 CheckRadioButton (hwnd, IDC1_HOMETILDE, IDC1_HOMERXVT,
694 cfg.rxvt_homeend ? IDC1_HOMERXVT : IDC1_HOMETILDE);
695 CheckRadioButton (hwnd, IDC1_FUNCTILDE, IDC1_FUNCXTERM,
697 (cfg.funky_type==2 ? IDC1_FUNCXTERM
700 CheckRadioButton (hwnd, IDC1_CURNORMAL, IDC1_CURAPPLIC,
701 cfg.app_cursor ? IDC1_CURAPPLIC : IDC1_CURNORMAL);
702 CheckRadioButton (hwnd, IDC1_KPNORMAL, IDC1_KPNH,
703 cfg.nethack_keypad ? IDC1_KPNH :
704 cfg.app_keypad ? IDC1_KPAPPLIC : IDC1_KPNORMAL);
705 CheckDlgButton (hwnd, IDC1_ALTF4, cfg.alt_f4);
706 CheckDlgButton (hwnd, IDC1_ALTSPACE, cfg.alt_space);
707 CheckDlgButton (hwnd, IDC1_LDISCTERM, cfg.ldisc_term);
708 CheckDlgButton (hwnd, IDC1_SCROLLKEY, cfg.scroll_on_key);
711 if (HIWORD(wParam) == BN_CLICKED ||
712 HIWORD(wParam) == BN_DOUBLECLICKED)
713 switch (LOWORD(wParam)) {
716 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC1_DEL127);
720 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC1_HOMERXVT);
727 cfg.funky_type = IsDlgButtonChecked (hwnd, IDC1_FUNCLINUX);
731 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC1_KPAPPLIC);
732 cfg.nethack_keypad = FALSE;
735 cfg.app_keypad = FALSE;
736 cfg.nethack_keypad = TRUE;
740 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC1_CURAPPLIC);
743 if (HIWORD(wParam) == BN_CLICKED ||
744 HIWORD(wParam) == BN_DOUBLECLICKED)
745 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC1_ALTF4);
748 if (HIWORD(wParam) == BN_CLICKED ||
749 HIWORD(wParam) == BN_DOUBLECLICKED)
750 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC1_ALTSPACE);
753 if (HIWORD(wParam) == BN_CLICKED ||
754 HIWORD(wParam) == BN_DOUBLECLICKED)
755 cfg.ldisc_term = IsDlgButtonChecked (hwnd, IDC1_LDISCTERM);
758 if (HIWORD(wParam) == BN_CLICKED ||
759 HIWORD(wParam) == BN_DOUBLECLICKED)
760 cfg.scroll_on_key = IsDlgButtonChecked (hwnd, IDC1_SCROLLKEY);
764 return GeneralPanelProc (hwnd, msg, wParam, lParam);
767 static void fmtfont (char *buf) {
768 sprintf (buf, "Font: %s, ", cfg.font);
770 strcat(buf, "bold, ");
771 if (cfg.fontheight == 0)
772 strcat (buf, "default height");
774 sprintf (buf+strlen(buf), "%d-%s",
775 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight),
776 (cfg.fontheight < 0 ? "pixel" : "point"));
779 static int CALLBACK TerminalProc (HWND hwnd, UINT msg,
780 WPARAM wParam, LPARAM lParam) {
783 char fontstatic[256];
787 CheckDlgButton (hwnd, IDC2_WRAPMODE, cfg.wrap_mode);
788 CheckDlgButton (hwnd, IDC2_WINNAME, cfg.win_name_always);
789 CheckDlgButton (hwnd, IDC2_DECOM, cfg.dec_om);
790 CheckDlgButton (hwnd, IDC2_LFHASCR, cfg.lfhascr);
791 SetDlgItemInt (hwnd, IDC2_ROWSEDIT, cfg.height, FALSE);
792 SetDlgItemInt (hwnd, IDC2_COLSEDIT, cfg.width, FALSE);
793 SetDlgItemInt (hwnd, IDC2_SAVEEDIT, cfg.savelines, FALSE);
794 fmtfont (fontstatic);
795 SetDlgItemText (hwnd, IDC2_FONTSTATIC, fontstatic);
796 CheckDlgButton (hwnd, IDC1_BLINKCUR, cfg.blink_cur);
797 CheckDlgButton (hwnd, IDC1_BEEP, cfg.beep);
798 CheckDlgButton (hwnd, IDC2_SCROLLBAR, cfg.scrollbar);
799 CheckDlgButton (hwnd, IDC2_LOCKSIZE, cfg.locksize);
800 CheckDlgButton (hwnd, IDC2_BCE, cfg.bce);
801 CheckDlgButton (hwnd, IDC2_BLINKTEXT, cfg.blinktext);
804 switch (LOWORD(wParam)) {
806 if (HIWORD(wParam) == BN_CLICKED ||
807 HIWORD(wParam) == BN_DOUBLECLICKED)
808 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC2_WRAPMODE);
811 if (HIWORD(wParam) == BN_CLICKED ||
812 HIWORD(wParam) == BN_DOUBLECLICKED)
813 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDC2_WINNAME);
816 if (HIWORD(wParam) == BN_CLICKED ||
817 HIWORD(wParam) == BN_DOUBLECLICKED)
818 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC2_DECOM);
821 if (HIWORD(wParam) == BN_CLICKED ||
822 HIWORD(wParam) == BN_DOUBLECLICKED)
823 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC2_LFHASCR);
826 if (HIWORD(wParam) == EN_CHANGE)
827 MyGetDlgItemInt (hwnd, IDC2_ROWSEDIT, &cfg.height);
830 if (HIWORD(wParam) == EN_CHANGE)
831 MyGetDlgItemInt (hwnd, IDC2_COLSEDIT, &cfg.width);
834 if (HIWORD(wParam) == EN_CHANGE)
835 MyGetDlgItemInt (hwnd, IDC2_SAVEEDIT, &cfg.savelines);
837 case IDC2_CHOOSEFONT:
838 lf.lfHeight = cfg.fontheight;
839 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
840 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
841 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
842 lf.lfCharSet = cfg.fontcharset;
843 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
844 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
845 lf.lfQuality = DEFAULT_QUALITY;
846 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
847 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
848 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
850 cf.lStructSize = sizeof(cf);
853 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
854 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
856 if (ChooseFont (&cf)) {
857 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
858 cfg.font[sizeof(cfg.font)-1] = '\0';
859 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
860 cfg.fontcharset = lf.lfCharSet;
861 cfg.fontheight = lf.lfHeight;
862 fmtfont (fontstatic);
863 SetDlgItemText (hwnd, IDC2_FONTSTATIC, fontstatic);
867 if (HIWORD(wParam) == BN_CLICKED ||
868 HIWORD(wParam) == BN_DOUBLECLICKED)
869 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDC1_BLINKCUR);
872 if (HIWORD(wParam) == BN_CLICKED ||
873 HIWORD(wParam) == BN_DOUBLECLICKED)
874 cfg.beep = IsDlgButtonChecked (hwnd, IDC1_BEEP);
877 if (HIWORD(wParam) == BN_CLICKED ||
878 HIWORD(wParam) == BN_DOUBLECLICKED)
879 cfg.scrollbar = IsDlgButtonChecked (hwnd, IDC2_SCROLLBAR);
882 if (HIWORD(wParam) == BN_CLICKED ||
883 HIWORD(wParam) == BN_DOUBLECLICKED)
884 cfg.locksize = IsDlgButtonChecked (hwnd, IDC2_LOCKSIZE);
887 if (HIWORD(wParam) == BN_CLICKED ||
888 HIWORD(wParam) == BN_DOUBLECLICKED)
889 cfg.blinktext = IsDlgButtonChecked (hwnd, IDC2_BLINKTEXT);
892 if (HIWORD(wParam) == BN_CLICKED ||
893 HIWORD(wParam) == BN_DOUBLECLICKED)
894 cfg.bce = IsDlgButtonChecked (hwnd, IDC2_BCE);
899 return GeneralPanelProc (hwnd, msg, wParam, lParam);
902 static int CALLBACK TelnetProc (HWND hwnd, UINT msg,
903 WPARAM wParam, LPARAM lParam) {
908 SetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype);
909 SetDlgItemText (hwnd, IDC3_TSEDIT, cfg.termspeed);
910 SetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username);
912 char *p = cfg.environmt;
914 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_ADDSTRING, 0,
919 CheckRadioButton (hwnd, IDC3_EMBSD, IDC3_EMRFC,
920 cfg.rfc_environ ? IDC3_EMRFC : IDC3_EMBSD);
923 switch (LOWORD(wParam)) {
925 if (HIWORD(wParam) == EN_CHANGE)
926 GetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype,
927 sizeof(cfg.termtype)-1);
930 if (HIWORD(wParam) == EN_CHANGE)
931 GetDlgItemText (hwnd, IDC3_TSEDIT, cfg.termspeed,
932 sizeof(cfg.termspeed)-1);
935 if (HIWORD(wParam) == EN_CHANGE)
936 GetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username,
937 sizeof(cfg.username)-1);
941 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC3_EMRFC);
944 if (HIWORD(wParam) == BN_CLICKED ||
945 HIWORD(wParam) == BN_DOUBLECLICKED) {
946 char str[sizeof(cfg.environmt)];
948 GetDlgItemText (hwnd, IDC3_VAREDIT, str, sizeof(str)-1);
953 p = str + strlen(str);
955 GetDlgItemText (hwnd, IDC3_VALEDIT, p, sizeof(str)-1-(p-str));
965 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
967 p[strlen(str)+1] = '\0';
968 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_ADDSTRING,
970 SetDlgItemText (hwnd, IDC3_VAREDIT, "");
971 SetDlgItemText (hwnd, IDC3_VALEDIT, "");
973 MessageBox(hwnd, "Environment too big", "PuTTY Error",
974 MB_OK | MB_ICONERROR);
979 if (HIWORD(wParam) != BN_CLICKED &&
980 HIWORD(wParam) != BN_DOUBLECLICKED)
982 i = SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_GETCURSEL, 0, 0);
988 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_DELETESTRING,
1015 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1018 static int CALLBACK SshProc (HWND hwnd, UINT msg,
1019 WPARAM wParam, LPARAM lParam) {
1021 char filename[sizeof(cfg.keyfile)];
1025 SetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype);
1026 SetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username);
1027 CheckDlgButton (hwnd, IDC3_NOPTY, cfg.nopty);
1028 CheckDlgButton (hwnd, IDC3_AGENTFWD, cfg.agentfwd);
1029 CheckRadioButton (hwnd, IDC3_CIPHER3DES, IDC3_CIPHERDES,
1030 cfg.cipher == CIPHER_BLOWFISH ? IDC3_CIPHERBLOWF :
1031 cfg.cipher == CIPHER_DES ? IDC3_CIPHERDES :
1033 CheckRadioButton (hwnd, IDC3_SSHPROT1, IDC3_SSHPROT2,
1034 cfg.sshprot == 1 ? IDC3_SSHPROT1 : IDC3_SSHPROT2);
1035 CheckDlgButton (hwnd, IDC3_AUTHTIS, cfg.try_tis_auth);
1036 SetDlgItemText (hwnd, IDC3_PKEDIT, cfg.keyfile);
1039 switch (LOWORD(wParam)) {
1041 if (HIWORD(wParam) == EN_CHANGE)
1042 GetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype,
1043 sizeof(cfg.termtype)-1);
1046 if (HIWORD(wParam) == EN_CHANGE)
1047 GetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username,
1048 sizeof(cfg.username)-1);
1051 if (HIWORD(wParam) == BN_CLICKED ||
1052 HIWORD(wParam) == BN_DOUBLECLICKED)
1053 cfg.nopty = IsDlgButtonChecked (hwnd, IDC3_NOPTY);
1056 if (HIWORD(wParam) == BN_CLICKED ||
1057 HIWORD(wParam) == BN_DOUBLECLICKED)
1058 cfg.agentfwd = IsDlgButtonChecked (hwnd, IDC3_AGENTFWD);
1060 case IDC3_CIPHER3DES:
1061 case IDC3_CIPHERBLOWF:
1062 case IDC3_CIPHERDES:
1063 if (HIWORD(wParam) == BN_CLICKED ||
1064 HIWORD(wParam) == BN_DOUBLECLICKED) {
1065 if (IsDlgButtonChecked (hwnd, IDC3_CIPHER3DES))
1066 cfg.cipher = CIPHER_3DES;
1067 else if (IsDlgButtonChecked (hwnd, IDC3_CIPHERBLOWF))
1068 cfg.cipher = CIPHER_BLOWFISH;
1069 else if (IsDlgButtonChecked (hwnd, IDC3_CIPHERDES))
1070 cfg.cipher = CIPHER_DES;
1075 if (HIWORD(wParam) == BN_CLICKED ||
1076 HIWORD(wParam) == BN_DOUBLECLICKED) {
1077 if (IsDlgButtonChecked (hwnd, IDC3_SSHPROT1))
1079 else if (IsDlgButtonChecked (hwnd, IDC3_SSHPROT2))
1084 if (HIWORD(wParam) == BN_CLICKED ||
1085 HIWORD(wParam) == BN_DOUBLECLICKED)
1086 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC3_AUTHTIS);
1089 if (HIWORD(wParam) == EN_CHANGE)
1090 GetDlgItemText (hwnd, IDC3_PKEDIT, cfg.keyfile,
1091 sizeof(cfg.keyfile)-1);
1095 * FIXME: this crashes. Find out why.
1097 memset(&of, 0, sizeof(of));
1098 #ifdef OPENFILENAME_SIZE_VERSION_400
1099 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1101 of.lStructSize = sizeof(of);
1103 of.hwndOwner = hwnd;
1104 of.lpstrFilter = "All Files\0*\0\0\0";
1105 of.lpstrCustomFilter = NULL;
1106 of.nFilterIndex = 1;
1107 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1108 of.nMaxFile = sizeof(filename);
1109 of.lpstrFileTitle = NULL;
1110 of.lpstrInitialDir = NULL;
1111 of.lpstrTitle = "Select Public Key File";
1113 if (GetOpenFileName(&of)) {
1114 strcpy(cfg.keyfile, filename);
1115 SetDlgItemText (hwnd, IDC3_PKEDIT, cfg.keyfile);
1121 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1124 static int CALLBACK SelectionProc (HWND hwnd, UINT msg,
1125 WPARAM wParam, LPARAM lParam) {
1130 CheckRadioButton (hwnd, IDC4_MBWINDOWS, IDC4_MBXTERM,
1131 cfg.mouse_is_xterm ? IDC4_MBXTERM : IDC4_MBWINDOWS);
1133 static int tabs[4] = {25, 61, 96, 128};
1134 SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_SETTABSTOPS, 4,
1137 for (i=0; i<256; i++) {
1139 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1140 (i>=0x21 && i != 0x7F) ? i : ' ',
1142 SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_ADDSTRING, 0,
1147 switch (LOWORD(wParam)) {
1148 case IDC4_MBWINDOWS:
1150 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC4_MBXTERM);
1156 int n = GetDlgItemInt (hwnd, IDC4_CCEDIT, &ok, FALSE);
1161 for (i=0; i<256; i++)
1162 if (SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_GETSEL,
1165 cfg.wordness[i] = n;
1166 SendDlgItemMessage (hwnd, IDC4_CCLIST,
1167 LB_DELETESTRING, i, 0);
1168 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1169 (i>=0x21 && i != 0x7F) ? i : ' ',
1171 SendDlgItemMessage (hwnd, IDC4_CCLIST,
1181 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1184 static int CALLBACK ColourProc (HWND hwnd, UINT msg,
1185 WPARAM wParam, LPARAM lParam) {
1186 static const char *const colours[] = {
1187 "Default Foreground", "Default Bold Foreground",
1188 "Default Background", "Default Bold Background",
1189 "Cursor Text", "Cursor Colour",
1190 "ANSI Black", "ANSI Black Bold",
1191 "ANSI Red", "ANSI Red Bold",
1192 "ANSI Green", "ANSI Green Bold",
1193 "ANSI Yellow", "ANSI Yellow Bold",
1194 "ANSI Blue", "ANSI Blue Bold",
1195 "ANSI Magenta", "ANSI Magenta Bold",
1196 "ANSI Cyan", "ANSI Cyan Bold",
1197 "ANSI White", "ANSI White Bold"
1199 static const int permanent[] = {
1200 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
1201 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
1202 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
1206 CheckDlgButton (hwnd, IDC5_BOLDCOLOUR, cfg.bold_colour);
1207 CheckDlgButton (hwnd, IDC5_PALETTE, cfg.try_palette);
1210 for (i=0; i<22; i++)
1211 if (cfg.bold_colour || permanent[i])
1212 SendDlgItemMessage (hwnd, IDC5_LIST, LB_ADDSTRING, 0,
1213 (LPARAM) colours[i]);
1215 SendDlgItemMessage (hwnd, IDC5_LIST, LB_SETCURSEL, 0, 0);
1216 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[0][0], FALSE);
1217 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[0][1], FALSE);
1218 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[0][2], FALSE);
1221 switch (LOWORD(wParam)) {
1222 case IDC5_BOLDCOLOUR:
1223 if (HIWORD(wParam) == BN_CLICKED ||
1224 HIWORD(wParam) == BN_DOUBLECLICKED) {
1226 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC5_BOLDCOLOUR);
1227 n = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCOUNT, 0, 0);
1228 if (cfg.bold_colour && n!=22) {
1229 for (i=0; i<22; i++)
1231 SendDlgItemMessage (hwnd, IDC5_LIST,
1233 (LPARAM) colours[i]);
1234 } else if (!cfg.bold_colour && n!=12) {
1237 SendDlgItemMessage (hwnd, IDC5_LIST,
1238 LB_DELETESTRING, i, 0);
1243 if (HIWORD(wParam) == BN_CLICKED ||
1244 HIWORD(wParam) == BN_DOUBLECLICKED)
1245 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC5_PALETTE);
1248 if (HIWORD(wParam) == LBN_DBLCLK ||
1249 HIWORD(wParam) == LBN_SELCHANGE) {
1250 int i = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCURSEL,
1252 if (!cfg.bold_colour)
1253 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1254 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[i][0], FALSE);
1255 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[i][1], FALSE);
1256 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[i][2], FALSE);
1260 if (HIWORD(wParam) == BN_CLICKED ||
1261 HIWORD(wParam) == BN_DOUBLECLICKED) {
1262 static CHOOSECOLOR cc;
1263 static DWORD custom[16] = {0}; /* zero initialisers */
1264 int i = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCURSEL,
1266 if (!cfg.bold_colour)
1267 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1268 cc.lStructSize = sizeof(cc);
1269 cc.hwndOwner = hwnd;
1270 cc.hInstance = (HWND)hinst;
1271 cc.lpCustColors = custom;
1272 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1274 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1275 if (ChooseColor(&cc)) {
1277 (unsigned char) (cc.rgbResult & 0xFF);
1279 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1281 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1282 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[i][0],
1284 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[i][1],
1286 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[i][2],
1294 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1297 static int CALLBACK TranslationProc (HWND hwnd, UINT msg,
1298 WPARAM wParam, LPARAM lParam) {
1301 CheckRadioButton (hwnd, IDC6_NOXLAT, IDC6_88592WIN1250,
1302 cfg.xlat_88592w1250 ? IDC6_88592WIN1250 :
1303 cfg.xlat_enablekoiwin ? IDC6_KOI8WIN1251 :
1305 CheckDlgButton (hwnd, IDC6_CAPSLOCKCYR, cfg.xlat_capslockcyr);
1306 CheckRadioButton (hwnd, IDC2_VTXWINDOWS, IDC2_VTPOORMAN,
1307 cfg.vtmode == VT_XWINDOWS ? IDC2_VTXWINDOWS :
1308 cfg.vtmode == VT_OEMANSI ? IDC2_VTOEMANSI :
1309 cfg.vtmode == VT_OEMONLY ? IDC2_VTOEMONLY :
1312 switch (LOWORD(wParam)) {
1314 case IDC6_KOI8WIN1251:
1315 case IDC6_88592WIN1250:
1316 cfg.xlat_enablekoiwin =
1317 IsDlgButtonChecked (hwnd, IDC6_KOI8WIN1251);
1318 cfg.xlat_88592w1250 =
1319 IsDlgButtonChecked (hwnd, IDC6_88592WIN1250);
1321 case IDC6_CAPSLOCKCYR:
1322 if (HIWORD(wParam) == BN_CLICKED ||
1323 HIWORD(wParam) == BN_DOUBLECLICKED) {
1324 cfg.xlat_capslockcyr =
1325 IsDlgButtonChecked (hwnd, IDC6_CAPSLOCKCYR);
1328 case IDC2_VTXWINDOWS:
1329 case IDC2_VTOEMANSI:
1330 case IDC2_VTOEMONLY:
1331 case IDC2_VTPOORMAN:
1333 (IsDlgButtonChecked (hwnd, IDC2_VTXWINDOWS) ? VT_XWINDOWS :
1334 IsDlgButtonChecked (hwnd, IDC2_VTOEMANSI) ? VT_OEMANSI :
1335 IsDlgButtonChecked (hwnd, IDC2_VTOEMONLY) ? VT_OEMONLY :
1340 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1343 static DLGPROC panelproc[NPANELS] = {
1344 ConnectionProc, KeyboardProc, TerminalProc,
1345 TelnetProc, SshProc, SelectionProc, ColourProc, TranslationProc
1347 static char *panelids[NPANELS] = {
1348 MAKEINTRESOURCE(IDD_PANEL0),
1349 MAKEINTRESOURCE(IDD_PANEL1),
1350 MAKEINTRESOURCE(IDD_PANEL2),
1351 MAKEINTRESOURCE(IDD_PANEL3),
1352 MAKEINTRESOURCE(IDD_PANEL35),
1353 MAKEINTRESOURCE(IDD_PANEL4),
1354 MAKEINTRESOURCE(IDD_PANEL5),
1355 MAKEINTRESOURCE(IDD_PANEL6)
1358 static char *names[NPANELS] = {
1359 "Connection", "Keyboard", "Terminal", "Telnet",
1360 "SSH", "Selection", "Colours", "Translation"
1363 static int mainp[MAIN_NPANELS] = { 0, 1, 2, 3, 4, 5, 6, 7};
1364 static int reconfp[RECONF_NPANELS] = { 1, 2, 5, 6, 7};
1366 static int GenericMainDlgProc (HWND hwnd, UINT msg,
1367 WPARAM wParam, LPARAM lParam,
1368 int npanels, int *panelnums, HWND *page) {
1373 { /* centre the window */
1376 hw = GetDesktopWindow();
1377 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
1378 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
1379 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
1380 rd.right-rd.left, rd.bottom-rd.top, TRUE);
1383 { /* initialise the tab control */
1387 hw = GetDlgItem (hwnd, IDC_TAB);
1388 for (i=0; i<npanels; i++) {
1389 tab.mask = TCIF_TEXT;
1390 tab.pszText = names[panelnums[i]];
1391 TabCtrl_InsertItem (hw, i, &tab);
1393 /* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1394 hwnd, panelproc[panelnums[0]]);*/
1395 *page = CreateDialog (hinst, panelids[panelnums[0]],
1396 hwnd, panelproc[panelnums[0]]);
1397 SetWindowLong (*page, GWL_EXSTYLE,
1398 GetWindowLong (*page, GWL_EXSTYLE) |
1399 WS_EX_CONTROLPARENT);
1404 if (LOWORD(wParam) == IDC_TAB &&
1405 ((LPNMHDR)lParam)->code == TCN_SELCHANGE) {
1406 int i = TabCtrl_GetCurSel(((LPNMHDR)lParam)->hwndFrom);
1408 DestroyWindow (*page);
1409 /* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1410 hwnd, panelproc[panelnums[i]]);*/
1411 *page = CreateDialog (hinst, panelids[panelnums[i]],
1412 hwnd, panelproc[panelnums[i]]);
1413 SetWindowLong (*page, GWL_EXSTYLE,
1414 GetWindowLong (*page, GWL_EXSTYLE) |
1415 WS_EX_CONTROLPARENT);
1416 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1420 /* case WM_CTLCOLORDLG: */
1421 /* return (int) GetStockObject (LTGRAY_BRUSH); */
1423 switch (LOWORD(wParam)) {
1426 EndDialog (hwnd, 1);
1431 EndDialog (hwnd, 0);
1436 EndDialog (hwnd, 0);
1439 /* Grrr Explorer will maximize Dialogs! */
1441 if (wParam == SIZE_MAXIMIZED)
1448 static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
1449 WPARAM wParam, LPARAM lParam) {
1454 static HWND page = NULL;
1456 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
1459 * If the Connection panel is active and the Session List
1460 * box is selected, we treat a press of Open to have an
1461 * implicit press of Load preceding it.
1463 hw = GetDlgItem (hwnd, IDC_TAB);
1464 i = TabCtrl_GetCurSel(hw);
1465 if (panelproc[mainp[i]] == ConnectionProc &&
1466 page && implicit_load_ok) {
1467 SendMessage (page, WM_COMMAND,
1468 MAKELONG(IDC0_SESSLOAD, BN_CLICKED), 0);
1472 if (msg == WM_COMMAND && LOWORD(wParam) == IDC_ABOUT) {
1473 EnableWindow(hwnd, 0);
1474 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1475 GetParent(hwnd), AboutProc);
1476 EnableWindow(hwnd, 1);
1477 SetActiveWindow(hwnd);
1479 return GenericMainDlgProc (hwnd, msg, wParam, lParam,
1480 MAIN_NPANELS, mainp, &page);
1483 static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
1484 WPARAM wParam, LPARAM lParam) {
1486 return GenericMainDlgProc (hwnd, msg, wParam, lParam,
1487 RECONF_NPANELS, reconfp, &page);
1490 void get_sesslist(int allocate) {
1491 static char *buffer;
1492 int buflen, bufsize, i, ret;
1493 char otherbuf[2048];
1498 if (RegCreateKey(HKEY_CURRENT_USER,
1499 puttystr, &subkey1) != ERROR_SUCCESS)
1502 buflen = bufsize = 0;
1506 ret = RegEnumKey(subkey1, i++, otherbuf, sizeof(otherbuf));
1507 if (ret == ERROR_SUCCESS) {
1508 bufsize = buflen + 2048;
1509 buffer = srealloc(buffer, bufsize);
1510 unmungestr(otherbuf, buffer+buflen);
1511 buflen += strlen(buffer+buflen)+1;
1513 } while (ret == ERROR_SUCCESS);
1514 buffer = srealloc(buffer, buflen+1);
1515 buffer[buflen] = '\0';
1518 nsessions = 1; /* "Default Settings" counts as one */
1520 if (strcmp(p, "Default Settings"))
1526 sessions = smalloc(nsessions * sizeof(char *));
1527 sessions[0] = "Default Settings";
1531 if (strcmp(p, "Default Settings"))
1542 int do_config (void) {
1546 savedsession[0] = '\0';
1547 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
1548 get_sesslist(FALSE);
1553 int do_reconfig (HWND hwnd) {
1557 backup_cfg = cfg; /* structure copy */
1558 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
1560 cfg = backup_cfg; /* structure copy */
1567 void do_defaults (char *session) {
1569 load_settings (session, TRUE);
1571 load_settings ("Default Settings", FALSE);
1574 void logevent (char *string) {
1575 if (nevents >= negsize) {
1577 events = srealloc (events, negsize * sizeof(*events));
1579 events[nevents] = smalloc(1+strlen(string));
1580 strcpy (events[nevents], string);
1584 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
1586 count = SendDlgItemMessage (logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
1587 SendDlgItemMessage (logbox, IDN_LIST, LB_SETCURSEL, count-1, 0);
1591 void showeventlog (HWND hwnd) {
1593 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
1595 ShowWindow (logbox, SW_SHOWNORMAL);
1599 void showabout (HWND hwnd) {
1601 abtbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1603 ShowWindow (abtbox, SW_SHOWNORMAL);
1607 void verify_ssh_host_key(char *host, char *keystr) {
1608 char *otherstr, *mungedhost;
1612 len = 1 + strlen(keystr);
1615 * Now read a saved key in from the registry and see what it
1618 otherstr = smalloc(len);
1619 mungedhost = smalloc(3*strlen(host)+1);
1620 if (!otherstr || !mungedhost)
1621 fatalbox("Out of memory");
1623 mungestr(host, mungedhost);
1625 if (RegCreateKey(HKEY_CURRENT_USER, PUTTY_REG_POS "\\SshHostKeys",
1626 &rkey) != ERROR_SUCCESS) {
1627 if (MessageBox(NULL, "PuTTY was unable to open the host key cache\n"
1628 "in the registry. There is thus no way to tell\n"
1629 "if the remote host is what you think it is.\n"
1630 "Connect anyway?", "PuTTY Problem",
1631 MB_ICONWARNING | MB_YESNO) == IDNO)
1634 DWORD readlen = len;
1638 ret = RegQueryValueEx(rkey, mungedhost, NULL,
1639 &type, otherstr, &readlen);
1641 if (ret == ERROR_MORE_DATA ||
1642 (ret == ERROR_SUCCESS && type == REG_SZ &&
1643 strcmp(otherstr, keystr))) {
1644 if (MessageBox(NULL,
1645 "This host's host key is different from the\n"
1646 "one cached in the registry! Someone may be\n"
1647 "impersonating this host for malicious reasons;\n"
1648 "alternatively, the host key may have changed\n"
1649 "due to sloppy system administration.\n"
1650 "Replace key in registry and connect?",
1651 "PuTTY: Security Warning",
1652 MB_ICONWARNING | MB_YESNO) == IDNO)
1654 RegSetValueEx(rkey, mungedhost, 0, REG_SZ, keystr,
1656 } else if (ret != ERROR_SUCCESS || type != REG_SZ) {
1657 if (MessageBox(NULL,
1658 "This host's host key is not cached in the\n"
1659 "registry. Do you want to add it to the cache\n"
1660 "and carry on connecting?",
1662 MB_ICONWARNING | MB_YESNO) == IDNO)
1664 RegSetValueEx(rkey, mungedhost, 0, REG_SZ, keystr,