Remove /DWIN32S_COMPAT by detecting presence of GetSystemPowerStatus at
[u/mdw/putty] / windlg.c
CommitLineData
374330e2 1#include <windows.h>
2#include <commctrl.h>
3#include <commdlg.h>
4d331a77 4#ifndef AUTO_WINSOCK
5#ifdef WINSOCK_TWO
6#include <winsock2.h>
7#else
374330e2 8#include <winsock.h>
4d331a77 9#endif
10#endif
374330e2 11#include <stdio.h>
12#include <stdlib.h>
13
374330e2 14#include "ssh.h"
bea1ef5f 15#include "putty.h"
374330e2 16#include "win_res.h"
d5859615 17#include "storage.h"
374330e2 18
9ca5da42 19#define NPANELS 9
20#define MAIN_NPANELS 9
21#define RECONF_NPANELS 6
374330e2 22
c5e9c988 23static char **events = NULL;
24static int nevents = 0, negsize = 0;
25
374330e2 26static HWND logbox = NULL, abtbox = NULL;
27
d1622aed 28static void gpps(void *handle, char *name, char *def, char *val, int len) {
29 if (!read_setting_s(handle, name, val, len)) {
374330e2 30 strncpy(val, def, len);
31 val[len-1] = '\0';
32 }
33}
34
d1622aed 35static void gppi(void *handle, char *name, int def, int *i) {
36 *i = read_setting_i(handle, name, def);
374330e2 37}
38
374330e2 39static HINSTANCE hinst;
40
1cd246bb 41static int readytogo;
42
374330e2 43static void save_settings (char *section, int do_host) {
44 int i;
374330e2 45 char *p;
d1622aed 46 void *sesskey;
374330e2 47
d1622aed 48 sesskey = open_settings_w(section);
49 if (!sesskey)
50 return;
374330e2 51
d1622aed 52 write_setting_i (sesskey, "Present", 1);
374330e2 53 if (do_host) {
d1622aed 54 write_setting_s (sesskey, "HostName", cfg.host);
55 write_setting_i (sesskey, "PortNumber", cfg.port);
89ee5268 56 p = "raw";
a721b9eb 57 for (i = 0; backends[i].name != NULL; i++)
89ee5268 58 if (backends[i].protocol == cfg.protocol) {
59 p = backends[i].name;
60 break;
61 }
d1622aed 62 write_setting_s (sesskey, "Protocol", p);
374330e2 63 }
d1622aed 64 write_setting_i (sesskey, "CloseOnExit", !!cfg.close_on_exit);
65 write_setting_i (sesskey, "WarnOnClose", !!cfg.warn_on_close);
66 write_setting_s (sesskey, "TerminalType", cfg.termtype);
67 write_setting_s (sesskey, "TerminalSpeed", cfg.termspeed);
374330e2 68 {
37508af4 69 char buf[2*sizeof(cfg.environmt)], *p, *q;
374330e2 70 p = buf;
37508af4 71 q = cfg.environmt;
374330e2 72 while (*q) {
73 while (*q) {
74 int c = *q++;
75 if (c == '=' || c == ',' || c == '\\')
76 *p++ = '\\';
77 if (c == '\t')
78 c = '=';
79 *p++ = c;
80 }
81 *p++ = ',';
82 q++;
83 }
84 *p = '\0';
d1622aed 85 write_setting_s (sesskey, "Environment", buf);
374330e2 86 }
d1622aed 87 write_setting_s (sesskey, "UserName", cfg.username);
88 write_setting_i (sesskey, "NoPTY", cfg.nopty);
89 write_setting_i (sesskey, "AgentFwd", cfg.agentfwd);
90 write_setting_s (sesskey, "RemoteCmd", cfg.remote_cmd);
91 write_setting_s (sesskey, "Cipher", cfg.cipher == CIPHER_BLOWFISH ? "blowfish" :
9697bfd2 92 cfg.cipher == CIPHER_DES ? "des" : "3des");
d1622aed 93 write_setting_i (sesskey, "AuthTIS", cfg.try_tis_auth);
94 write_setting_i (sesskey, "SshProt", cfg.sshprot);
95 write_setting_s (sesskey, "PublicKeyFile", cfg.keyfile);
4c73ca1f 96 write_setting_s (sesskey, "RemoteCommand", cfg.remote_cmd);
d1622aed 97 write_setting_i (sesskey, "RFCEnviron", cfg.rfc_environ);
98 write_setting_i (sesskey, "BackspaceIsDelete", cfg.bksp_is_delete);
99 write_setting_i (sesskey, "RXVTHomeEnd", cfg.rxvt_homeend);
100 write_setting_i (sesskey, "LinuxFunctionKeys", cfg.funky_type);
101 write_setting_i (sesskey, "ApplicationCursorKeys", cfg.app_cursor);
102 write_setting_i (sesskey, "ApplicationKeypad", cfg.app_keypad);
103 write_setting_i (sesskey, "NetHackKeypad", cfg.nethack_keypad);
104 write_setting_i (sesskey, "AltF4", cfg.alt_f4);
105 write_setting_i (sesskey, "AltSpace", cfg.alt_space);
106 write_setting_i (sesskey, "LdiscTerm", cfg.ldisc_term);
107 write_setting_i (sesskey, "BlinkCur", cfg.blink_cur);
108 write_setting_i (sesskey, "Beep", cfg.beep);
109 write_setting_i (sesskey, "ScrollbackLines", cfg.savelines);
110 write_setting_i (sesskey, "DECOriginMode", cfg.dec_om);
111 write_setting_i (sesskey, "AutoWrapMode", cfg.wrap_mode);
112 write_setting_i (sesskey, "LFImpliesCR", cfg.lfhascr);
113 write_setting_i (sesskey, "WinNameAlways", cfg.win_name_always);
9ca5da42 114 write_setting_s (sesskey, "WinTitle", cfg.wintitle);
d1622aed 115 write_setting_i (sesskey, "TermWidth", cfg.width);
116 write_setting_i (sesskey, "TermHeight", cfg.height);
117 write_setting_s (sesskey, "Font", cfg.font);
118 write_setting_i (sesskey, "FontIsBold", cfg.fontisbold);
119 write_setting_i (sesskey, "FontCharSet", cfg.fontcharset);
120 write_setting_i (sesskey, "FontHeight", cfg.fontheight);
121 write_setting_i (sesskey, "FontVTMode", cfg.vtmode);
122 write_setting_i (sesskey, "TryPalette", cfg.try_palette);
123 write_setting_i (sesskey, "BoldAsColour", cfg.bold_colour);
374330e2 124 for (i=0; i<22; i++) {
125 char buf[20], buf2[30];
126 sprintf(buf, "Colour%d", i);
127 sprintf(buf2, "%d,%d,%d", cfg.colours[i][0],
128 cfg.colours[i][1], cfg.colours[i][2]);
d1622aed 129 write_setting_s (sesskey, buf, buf2);
374330e2 130 }
d1622aed 131 write_setting_i (sesskey, "MouseIsXterm", cfg.mouse_is_xterm);
374330e2 132 for (i=0; i<256; i+=32) {
133 char buf[20], buf2[256];
134 int j;
135 sprintf(buf, "Wordness%d", i);
136 *buf2 = '\0';
137 for (j=i; j<i+32; j++) {
138 sprintf(buf2+strlen(buf2), "%s%d",
139 (*buf2 ? "," : ""), cfg.wordness[j]);
140 }
d1622aed 141 write_setting_s (sesskey, buf, buf2);
374330e2 142 }
d1622aed 143 write_setting_i (sesskey, "KoiWinXlat", cfg.xlat_enablekoiwin);
144 write_setting_i (sesskey, "88592Xlat", cfg.xlat_88592w1250);
145 write_setting_i (sesskey, "CapsLockCyr", cfg.xlat_capslockcyr);
146 write_setting_i (sesskey, "ScrollBar", cfg.scrollbar);
147 write_setting_i (sesskey, "ScrollOnKey", cfg.scroll_on_key);
148 write_setting_i (sesskey, "LockSize", cfg.locksize);
149 write_setting_i (sesskey, "BCE", cfg.bce);
150 write_setting_i (sesskey, "BlinkText", cfg.blinktext);
151
152 close_settings_w(sesskey);
374330e2 153}
154
155static void load_settings (char *section, int do_host) {
156 int i;
e277c42d 157 char prot[10];
d1622aed 158 void *sesskey;
374330e2 159
d1622aed 160 sesskey = open_settings_r(section);
374330e2 161
e277c42d 162 gpps (sesskey, "HostName", "", cfg.host, sizeof(cfg.host));
163 gppi (sesskey, "PortNumber", default_port, &cfg.port);
89ee5268 164
e277c42d 165 gpps (sesskey, "Protocol", "default", prot, 10);
89ee5268 166 cfg.protocol = default_protocol;
a721b9eb 167 for (i = 0; backends[i].name != NULL; i++)
89ee5268 168 if (!strcmp(prot, backends[i].name)) {
169 cfg.protocol = backends[i].protocol;
170 break;
171 }
e277c42d 172
374330e2 173 gppi (sesskey, "CloseOnExit", 1, &cfg.close_on_exit);
9ef49106 174 gppi (sesskey, "WarnOnClose", 1, &cfg.warn_on_close);
374330e2 175 gpps (sesskey, "TerminalType", "xterm", cfg.termtype,
176 sizeof(cfg.termtype));
177 gpps (sesskey, "TerminalSpeed", "38400,38400", cfg.termspeed,
178 sizeof(cfg.termspeed));
179 {
37508af4 180 char buf[2*sizeof(cfg.environmt)], *p, *q;
374330e2 181 gpps (sesskey, "Environment", "", buf, sizeof(buf));
182 p = buf;
29b611b7 183 q = cfg.environmt;
374330e2 184 while (*p) {
185 while (*p && *p != ',') {
186 int c = *p++;
187 if (c == '=')
188 c = '\t';
189 if (c == '\\')
190 c = *p++;
29b611b7 191 *q++ = c;
374330e2 192 }
193 if (*p == ',') p++;
194 *q++ = '\0';
195 }
196 *q = '\0';
197 }
198 gpps (sesskey, "UserName", "", cfg.username, sizeof(cfg.username));
fef97f43 199 gppi (sesskey, "NoPTY", 0, &cfg.nopty);
979310f1 200 gppi (sesskey, "AgentFwd", 0, &cfg.agentfwd);
6abbf9e3 201 gpps (sesskey, "RemoteCmd", "", cfg.remote_cmd, sizeof(cfg.remote_cmd));
bea1ef5f 202 {
203 char cipher[10];
204 gpps (sesskey, "Cipher", "3des", cipher, 10);
205 if (!strcmp(cipher, "blowfish"))
206 cfg.cipher = CIPHER_BLOWFISH;
9697bfd2 207 else if (!strcmp(cipher, "des"))
208 cfg.cipher = CIPHER_DES;
bea1ef5f 209 else
210 cfg.cipher = CIPHER_3DES;
211 }
adf799dd 212 gppi (sesskey, "SshProt", 1, &cfg.sshprot);
ccbfb941 213 gppi (sesskey, "AuthTIS", 0, &cfg.try_tis_auth);
7cca0d81 214 gpps (sesskey, "PublicKeyFile", "", cfg.keyfile, sizeof(cfg.keyfile));
4c73ca1f 215 gpps (sesskey, "RemoteCommand", "", cfg.remote_cmd,
216 sizeof(cfg.remote_cmd));
374330e2 217 gppi (sesskey, "RFCEnviron", 0, &cfg.rfc_environ);
218 gppi (sesskey, "BackspaceIsDelete", 1, &cfg.bksp_is_delete);
219 gppi (sesskey, "RXVTHomeEnd", 0, &cfg.rxvt_homeend);
c9def1b8 220 gppi (sesskey, "LinuxFunctionKeys", 0, &cfg.funky_type);
374330e2 221 gppi (sesskey, "ApplicationCursorKeys", 0, &cfg.app_cursor);
222 gppi (sesskey, "ApplicationKeypad", 0, &cfg.app_keypad);
c5e9c988 223 gppi (sesskey, "NetHackKeypad", 0, &cfg.nethack_keypad);
224 gppi (sesskey, "AltF4", 1, &cfg.alt_f4);
225 gppi (sesskey, "AltSpace", 0, &cfg.alt_space);
5bc238bb 226 gppi (sesskey, "LdiscTerm", 0, &cfg.ldisc_term);
217dceef 227 gppi (sesskey, "BlinkCur", 0, &cfg.blink_cur);
2a25a1b4 228 gppi (sesskey, "Beep", 1, &cfg.beep);
374330e2 229 gppi (sesskey, "ScrollbackLines", 200, &cfg.savelines);
230 gppi (sesskey, "DECOriginMode", 0, &cfg.dec_om);
231 gppi (sesskey, "AutoWrapMode", 1, &cfg.wrap_mode);
fef97f43 232 gppi (sesskey, "LFImpliesCR", 0, &cfg.lfhascr);
374330e2 233 gppi (sesskey, "WinNameAlways", 0, &cfg.win_name_always);
9ca5da42 234 gpps (sesskey, "WinTitle", "", cfg.wintitle, sizeof(cfg.wintitle));
374330e2 235 gppi (sesskey, "TermWidth", 80, &cfg.width);
236 gppi (sesskey, "TermHeight", 24, &cfg.height);
237 gpps (sesskey, "Font", "Courier", cfg.font, sizeof(cfg.font));
238 gppi (sesskey, "FontIsBold", 0, &cfg.fontisbold);
14963b8f 239 gppi (sesskey, "FontCharSet", ANSI_CHARSET, &cfg.fontcharset);
374330e2 240 gppi (sesskey, "FontHeight", 10, &cfg.fontheight);
2a7bfc6e 241 gppi (sesskey, "FontVTMode", VT_OEMANSI, (int *)&cfg.vtmode);
374330e2 242 gppi (sesskey, "TryPalette", 0, &cfg.try_palette);
243 gppi (sesskey, "BoldAsColour", 1, &cfg.bold_colour);
244 for (i=0; i<22; i++) {
245 static char *defaults[] = {
246 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
247 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
248 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
249 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
250 "85,255,255", "187,187,187", "255,255,255"
251 };
252 char buf[20], buf2[30];
1d470ad2 253 int c0, c1, c2;
374330e2 254 sprintf(buf, "Colour%d", i);
255 gpps (sesskey, buf, defaults[i], buf2, sizeof(buf2));
1d470ad2 256 if(sscanf(buf2, "%d,%d,%d", &c0, &c1, &c2) == 3) {
257 cfg.colours[i][0] = c0;
258 cfg.colours[i][1] = c1;
259 cfg.colours[i][2] = c2;
260 }
374330e2 261 }
262 gppi (sesskey, "MouseIsXterm", 0, &cfg.mouse_is_xterm);
263 for (i=0; i<256; i+=32) {
264 static char *defaults[] = {
265 "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",
266 "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",
267 "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",
268 "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",
269 "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",
270 "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",
271 "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",
272 "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"
273 };
274 char buf[20], buf2[256], *p;
275 int j;
276 sprintf(buf, "Wordness%d", i);
277 gpps (sesskey, buf, defaults[i/32], buf2, sizeof(buf2));
278 p = buf2;
279 for (j=i; j<i+32; j++) {
280 char *q = p;
281 while (*p && *p != ',') p++;
282 if (*p == ',') *p++ = '\0';
283 cfg.wordness[j] = atoi(q);
284 }
285 }
14963b8f 286 gppi (sesskey, "KoiWinXlat", 0, &cfg.xlat_enablekoiwin);
d3d16feb 287 gppi (sesskey, "88592Xlat", 0, &cfg.xlat_88592w1250);
14963b8f 288 gppi (sesskey, "CapsLockCyr", 0, &cfg.xlat_capslockcyr);
c9def1b8 289 gppi (sesskey, "ScrollBar", 1, &cfg.scrollbar);
290 gppi (sesskey, "ScrollOnKey", 0, &cfg.scroll_on_key);
291 gppi (sesskey, "LockSize", 0, &cfg.locksize);
292 gppi (sesskey, "BCE", 0, &cfg.bce);
293 gppi (sesskey, "BlinkText", 0, &cfg.blinktext);
14963b8f 294
d1622aed 295 close_settings_r(sesskey);
374330e2 296}
297
c9def1b8 298static void force_normal(HWND hwnd)
299{
300static int recurse = 0;
301
302 WINDOWPLACEMENT wp;
303
304 if(recurse) return;
305 recurse = 1;
306
307 wp.length = sizeof(wp);
308 if (GetWindowPlacement(hwnd, &wp))
309 {
310 wp.showCmd = SW_SHOWNORMAL;
311 SetWindowPlacement(hwnd, &wp);
312 }
313 recurse = 0;
314}
315
374330e2 316static void MyGetDlgItemInt (HWND hwnd, int id, int *result) {
317 BOOL ok;
318 int n;
319 n = GetDlgItemInt (hwnd, id, &ok, FALSE);
320 if (ok)
321 *result = n;
322}
323
324static int CALLBACK LogProc (HWND hwnd, UINT msg,
325 WPARAM wParam, LPARAM lParam) {
326 int i;
327
328 switch (msg) {
329 case WM_INITDIALOG:
c5e9c988 330 for (i=0; i<nevents; i++)
374330e2 331 SendDlgItemMessage (hwnd, IDN_LIST, LB_ADDSTRING,
c5e9c988 332 0, (LPARAM)events[i]);
374330e2 333 return 1;
334/* case WM_CTLCOLORDLG: */
335/* return (int) GetStockObject (LTGRAY_BRUSH); */
336 case WM_COMMAND:
337 switch (LOWORD(wParam)) {
338 case IDOK:
339 logbox = NULL;
340 DestroyWindow (hwnd);
341 return 0;
989b10e9 342 case IDN_COPY:
343 if (HIWORD(wParam) == BN_CLICKED ||
344 HIWORD(wParam) == BN_DOUBLECLICKED) {
345 int selcount;
346 int *selitems;
347 selcount = SendDlgItemMessage(hwnd, IDN_LIST,
348 LB_GETSELCOUNT, 0, 0);
349 selitems = malloc(selcount * sizeof(int));
350 if (selitems) {
351 int count = SendDlgItemMessage(hwnd, IDN_LIST,
352 LB_GETSELITEMS,
353 selcount, (LPARAM)selitems);
354 int i;
355 int size;
356 char *clipdata;
357 static unsigned char sel_nl[] = SEL_NL;
358
359 size = 0;
360 for (i = 0; i < count; i++)
361 size += strlen(events[selitems[i]]) + sizeof(sel_nl);
362
363 clipdata = malloc(size);
364 if (clipdata) {
365 char *p = clipdata;
366 for (i = 0; i < count; i++) {
367 char *q = events[selitems[i]];
368 int qlen = strlen(q);
369 memcpy(p, q, qlen);
370 p += qlen;
371 memcpy(p, sel_nl, sizeof(sel_nl));
372 p += sizeof(sel_nl);
373 }
374 write_clip(clipdata, size);
375 term_deselect();
376 free(clipdata);
377 }
378 free(selitems);
379 }
380 }
381 return 0;
374330e2 382 }
383 return 0;
384 case WM_CLOSE:
385 logbox = NULL;
386 DestroyWindow (hwnd);
387 return 0;
388 }
389 return 0;
390}
391
d57835ab 392static int CALLBACK LicenceProc (HWND hwnd, UINT msg,
393 WPARAM wParam, LPARAM lParam) {
394 switch (msg) {
395 case WM_INITDIALOG:
396 return 1;
397 case WM_COMMAND:
398 switch (LOWORD(wParam)) {
399 case IDOK:
97749503 400 EndDialog(hwnd, 1);
d57835ab 401 return 0;
402 }
403 return 0;
404 case WM_CLOSE:
97749503 405 EndDialog(hwnd, 1);
d57835ab 406 return 0;
407 }
408 return 0;
409}
410
374330e2 411static int CALLBACK AboutProc (HWND hwnd, UINT msg,
412 WPARAM wParam, LPARAM lParam) {
413 switch (msg) {
414 case WM_INITDIALOG:
067a15ea 415 SetDlgItemText (hwnd, IDA_VERSION, ver);
374330e2 416 return 1;
417/* case WM_CTLCOLORDLG: */
418/* return (int) GetStockObject (LTGRAY_BRUSH); */
419/* case WM_CTLCOLORSTATIC: */
420/* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
421/* return (int) GetStockObject (LTGRAY_BRUSH); */
422 case WM_COMMAND:
423 switch (LOWORD(wParam)) {
424 case IDOK:
425 abtbox = NULL;
426 DestroyWindow (hwnd);
427 return 0;
428 case IDA_LICENCE:
429 EnableWindow(hwnd, 0);
430 DialogBox (hinst, MAKEINTRESOURCE(IDD_LICENCEBOX),
d57835ab 431 NULL, LicenceProc);
374330e2 432 EnableWindow(hwnd, 1);
9a70ac47 433 SetActiveWindow(hwnd);
374330e2 434 return 0;
435 }
436 return 0;
437 case WM_CLOSE:
438 abtbox = NULL;
439 DestroyWindow (hwnd);
440 return 0;
441 }
442 return 0;
443}
444
445static int GeneralPanelProc (HWND hwnd, UINT msg,
446 WPARAM wParam, LPARAM lParam) {
447 switch (msg) {
448 case WM_INITDIALOG:
449 SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
450 return 1;
451/* case WM_CTLCOLORDLG: */
452/* return (int) GetStockObject (LTGRAY_BRUSH); */
453/* case WM_CTLCOLORSTATIC: */
454/* case WM_CTLCOLORBTN: */
455/* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
456/* return (int) GetStockObject (LTGRAY_BRUSH); */
457 case WM_CLOSE:
458 DestroyWindow (hwnd);
459 return 1;
460 }
461 return 0;
462}
463
6584031a 464static char savedsession[2048];
465
374330e2 466static int CALLBACK ConnectionProc (HWND hwnd, UINT msg,
467 WPARAM wParam, LPARAM lParam) {
468 int i;
469
470 switch (msg) {
471 case WM_INITDIALOG:
472 SetDlgItemText (hwnd, IDC0_HOST, cfg.host);
6584031a 473 SetDlgItemText (hwnd, IDC0_SESSEDIT, savedsession);
374330e2 474 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
475 for (i = 0; i < nsessions; i++)
476 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
477 0, (LPARAM) (sessions[i]));
5e1a8e27 478 CheckRadioButton (hwnd, IDC0_PROTRAW, IDC0_PROTSSH,
479 cfg.protocol==PROT_SSH ? IDC0_PROTSSH :
480 cfg.protocol==PROT_TELNET ? IDC0_PROTTELNET : IDC0_PROTRAW );
374330e2 481 CheckDlgButton (hwnd, IDC0_CLOSEEXIT, cfg.close_on_exit);
9ef49106 482 CheckDlgButton (hwnd, IDC0_CLOSEWARN, cfg.warn_on_close);
374330e2 483 break;
1cd246bb 484 case WM_LBUTTONUP:
485 /*
486 * Button release should trigger WM_OK if there was a
487 * previous double click on the session list.
488 */
489 ReleaseCapture();
490 if (readytogo)
491 SendMessage (GetParent(hwnd), WM_COMMAND, IDOK, 0);
492 break;
374330e2 493 case WM_COMMAND:
494 switch (LOWORD(wParam)) {
495 case IDC0_PROTTELNET:
496 case IDC0_PROTSSH:
5e1a8e27 497 case IDC0_PROTRAW:
374330e2 498 if (HIWORD(wParam) == BN_CLICKED ||
499 HIWORD(wParam) == BN_DOUBLECLICKED) {
500 int i = IsDlgButtonChecked (hwnd, IDC0_PROTSSH);
5e1a8e27 501 int j = IsDlgButtonChecked (hwnd, IDC0_PROTTELNET);
502 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : PROT_RAW ;
374330e2 503 if ((cfg.protocol == PROT_SSH && cfg.port == 23) ||
504 (cfg.protocol == PROT_TELNET && cfg.port == 22)) {
505 cfg.port = i ? 22 : 23;
506 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
507 }
508 }
509 break;
510 case IDC0_HOST:
511 if (HIWORD(wParam) == EN_CHANGE)
512 GetDlgItemText (hwnd, IDC0_HOST, cfg.host,
513 sizeof(cfg.host)-1);
514 break;
515 case IDC0_PORT:
516 if (HIWORD(wParam) == EN_CHANGE)
517 MyGetDlgItemInt (hwnd, IDC0_PORT, &cfg.port);
518 break;
519 case IDC0_CLOSEEXIT:
520 if (HIWORD(wParam) == BN_CLICKED ||
521 HIWORD(wParam) == BN_DOUBLECLICKED)
522 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC0_CLOSEEXIT);
523 break;
9ef49106 524 case IDC0_CLOSEWARN:
525 if (HIWORD(wParam) == BN_CLICKED ||
526 HIWORD(wParam) == BN_DOUBLECLICKED)
527 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC0_CLOSEWARN);
528 break;
374330e2 529 case IDC0_SESSEDIT:
6584031a 530 if (HIWORD(wParam) == EN_CHANGE) {
374330e2 531 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
532 (WPARAM) -1, 0);
6584031a 533 GetDlgItemText (hwnd, IDC0_SESSEDIT,
534 savedsession, sizeof(savedsession)-1);
535 savedsession[sizeof(savedsession)-1] = '\0';
536 }
374330e2 537 break;
538 case IDC0_SESSSAVE:
539 if (HIWORD(wParam) == BN_CLICKED ||
540 HIWORD(wParam) == BN_DOUBLECLICKED) {
541 /*
542 * Save a session
543 */
544 char str[2048];
545 GetDlgItemText (hwnd, IDC0_SESSEDIT, str, sizeof(str)-1);
546 if (!*str) {
547 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
548 LB_GETCURSEL, 0, 0);
549 if (n == LB_ERR) {
550 MessageBeep(0);
551 break;
552 }
553 strcpy (str, sessions[n]);
554 }
555 save_settings (str, !!strcmp(str, "Default Settings"));
556 get_sesslist (FALSE);
557 get_sesslist (TRUE);
558 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_RESETCONTENT,
559 0, 0);
560 for (i = 0; i < nsessions; i++)
561 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
562 0, (LPARAM) (sessions[i]));
563 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
564 (WPARAM) -1, 0);
565 }
566 break;
567 case IDC0_SESSLIST:
568 case IDC0_SESSLOAD:
569 if (LOWORD(wParam) == IDC0_SESSLOAD &&
570 HIWORD(wParam) != BN_CLICKED &&
571 HIWORD(wParam) != BN_DOUBLECLICKED)
572 break;
573 if (LOWORD(wParam) == IDC0_SESSLIST &&
574 HIWORD(wParam) != LBN_DBLCLK)
575 break;
576 {
577 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
578 LB_GETCURSEL, 0, 0);
579 if (n == LB_ERR) {
580 MessageBeep(0);
581 break;
582 }
583 load_settings (sessions[n],
584 !!strcmp(sessions[n], "Default Settings"));
585 SetDlgItemText (hwnd, IDC0_HOST, cfg.host);
586 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
5e1a8e27 587 CheckRadioButton (hwnd, IDC0_PROTRAW, IDC0_PROTSSH,
374330e2 588 (cfg.protocol==PROT_SSH ? IDC0_PROTSSH :
5e1a8e27 589 cfg.protocol==PROT_TELNET ? IDC0_PROTTELNET : IDC0_PROTRAW));
374330e2 590 CheckDlgButton (hwnd, IDC0_CLOSEEXIT, cfg.close_on_exit);
9ef49106 591 CheckDlgButton (hwnd, IDC0_CLOSEWARN, cfg.warn_on_close);
374330e2 592 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
593 (WPARAM) -1, 0);
594 }
595 if (LOWORD(wParam) == IDC0_SESSLIST) {
596 /*
597 * A double-click on a saved session should
598 * actually start the session, not just load it.
599 * Unless it's Default Settings or some other
600 * host-less set of saved settings.
601 */
1cd246bb 602 if (*cfg.host) {
603 readytogo = TRUE;
604 SetCapture(hwnd);
605 }
374330e2 606 }
607 break;
608 case IDC0_SESSDEL:
609 if (HIWORD(wParam) == BN_CLICKED ||
610 HIWORD(wParam) == BN_DOUBLECLICKED) {
611 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
612 LB_GETCURSEL, 0, 0);
613 if (n == LB_ERR || n == 0) {
614 MessageBeep(0);
615 break;
616 }
d1622aed 617 del_settings(sessions[n]);
374330e2 618 get_sesslist (FALSE);
619 get_sesslist (TRUE);
620 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_RESETCONTENT,
621 0, 0);
622 for (i = 0; i < nsessions; i++)
623 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
624 0, (LPARAM) (sessions[i]));
625 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
626 (WPARAM) -1, 0);
627 }
628 }
629 }
630 return GeneralPanelProc (hwnd, msg, wParam, lParam);
631}
632
633static int CALLBACK KeyboardProc (HWND hwnd, UINT msg,
634 WPARAM wParam, LPARAM lParam) {
635 switch (msg) {
636 case WM_INITDIALOG:
637 CheckRadioButton (hwnd, IDC1_DEL008, IDC1_DEL127,
638 cfg.bksp_is_delete ? IDC1_DEL127 : IDC1_DEL008);
639 CheckRadioButton (hwnd, IDC1_HOMETILDE, IDC1_HOMERXVT,
640 cfg.rxvt_homeend ? IDC1_HOMERXVT : IDC1_HOMETILDE);
c9def1b8 641 CheckRadioButton (hwnd, IDC1_FUNCTILDE, IDC1_FUNCXTERM,
642 cfg.funky_type ?
643 (cfg.funky_type==2 ? IDC1_FUNCXTERM
644 : IDC1_FUNCLINUX )
645 : IDC1_FUNCTILDE);
374330e2 646 CheckRadioButton (hwnd, IDC1_CURNORMAL, IDC1_CURAPPLIC,
647 cfg.app_cursor ? IDC1_CURAPPLIC : IDC1_CURNORMAL);
c5e9c988 648 CheckRadioButton (hwnd, IDC1_KPNORMAL, IDC1_KPNH,
649 cfg.nethack_keypad ? IDC1_KPNH :
374330e2 650 cfg.app_keypad ? IDC1_KPAPPLIC : IDC1_KPNORMAL);
c5e9c988 651 CheckDlgButton (hwnd, IDC1_ALTF4, cfg.alt_f4);
652 CheckDlgButton (hwnd, IDC1_ALTSPACE, cfg.alt_space);
5bc238bb 653 CheckDlgButton (hwnd, IDC1_LDISCTERM, cfg.ldisc_term);
c9def1b8 654 CheckDlgButton (hwnd, IDC1_SCROLLKEY, cfg.scroll_on_key);
374330e2 655 break;
656 case WM_COMMAND:
657 if (HIWORD(wParam) == BN_CLICKED ||
658 HIWORD(wParam) == BN_DOUBLECLICKED)
659 switch (LOWORD(wParam)) {
660 case IDC1_DEL008:
661 case IDC1_DEL127:
662 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC1_DEL127);
663 break;
664 case IDC1_HOMETILDE:
665 case IDC1_HOMERXVT:
666 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC1_HOMERXVT);
667 break;
c9def1b8 668 case IDC1_FUNCXTERM:
669 cfg.funky_type = 2;
670 break;
374330e2 671 case IDC1_FUNCTILDE:
672 case IDC1_FUNCLINUX:
c9def1b8 673 cfg.funky_type = IsDlgButtonChecked (hwnd, IDC1_FUNCLINUX);
374330e2 674 break;
675 case IDC1_KPNORMAL:
676 case IDC1_KPAPPLIC:
677 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC1_KPAPPLIC);
c5e9c988 678 cfg.nethack_keypad = FALSE;
679 break;
680 case IDC1_KPNH:
681 cfg.app_keypad = FALSE;
682 cfg.nethack_keypad = TRUE;
374330e2 683 break;
684 case IDC1_CURNORMAL:
685 case IDC1_CURAPPLIC:
686 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC1_CURAPPLIC);
687 break;
c5e9c988 688 case IDC1_ALTF4:
689 if (HIWORD(wParam) == BN_CLICKED ||
690 HIWORD(wParam) == BN_DOUBLECLICKED)
691 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC1_ALTF4);
692 break;
693 case IDC1_ALTSPACE:
694 if (HIWORD(wParam) == BN_CLICKED ||
695 HIWORD(wParam) == BN_DOUBLECLICKED)
696 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC1_ALTSPACE);
697 break;
5bc238bb 698 case IDC1_LDISCTERM:
699 if (HIWORD(wParam) == BN_CLICKED ||
700 HIWORD(wParam) == BN_DOUBLECLICKED)
701 cfg.ldisc_term = IsDlgButtonChecked (hwnd, IDC1_LDISCTERM);
702 break;
c9def1b8 703 case IDC1_SCROLLKEY:
217dceef 704 if (HIWORD(wParam) == BN_CLICKED ||
705 HIWORD(wParam) == BN_DOUBLECLICKED)
c9def1b8 706 cfg.scroll_on_key = IsDlgButtonChecked (hwnd, IDC1_SCROLLKEY);
217dceef 707 break;
374330e2 708 }
709 }
710 return GeneralPanelProc (hwnd, msg, wParam, lParam);
711}
712
713static void fmtfont (char *buf) {
714 sprintf (buf, "Font: %s, ", cfg.font);
715 if (cfg.fontisbold)
716 strcat(buf, "bold, ");
717 if (cfg.fontheight == 0)
718 strcat (buf, "default height");
719 else
720 sprintf (buf+strlen(buf), "%d-%s",
721 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight),
722 (cfg.fontheight < 0 ? "pixel" : "point"));
723}
724
725static int CALLBACK TerminalProc (HWND hwnd, UINT msg,
726 WPARAM wParam, LPARAM lParam) {
727 CHOOSEFONT cf;
728 LOGFONT lf;
729 char fontstatic[256];
730
731 switch (msg) {
732 case WM_INITDIALOG:
733 CheckDlgButton (hwnd, IDC2_WRAPMODE, cfg.wrap_mode);
374330e2 734 CheckDlgButton (hwnd, IDC2_DECOM, cfg.dec_om);
fef97f43 735 CheckDlgButton (hwnd, IDC2_LFHASCR, cfg.lfhascr);
374330e2 736 SetDlgItemInt (hwnd, IDC2_ROWSEDIT, cfg.height, FALSE);
737 SetDlgItemInt (hwnd, IDC2_COLSEDIT, cfg.width, FALSE);
738 SetDlgItemInt (hwnd, IDC2_SAVEEDIT, cfg.savelines, FALSE);
739 fmtfont (fontstatic);
740 SetDlgItemText (hwnd, IDC2_FONTSTATIC, fontstatic);
c9def1b8 741 CheckDlgButton (hwnd, IDC1_BEEP, cfg.beep);
c9def1b8 742 CheckDlgButton (hwnd, IDC2_BCE, cfg.bce);
743 CheckDlgButton (hwnd, IDC2_BLINKTEXT, cfg.blinktext);
374330e2 744 break;
745 case WM_COMMAND:
746 switch (LOWORD(wParam)) {
747 case IDC2_WRAPMODE:
748 if (HIWORD(wParam) == BN_CLICKED ||
749 HIWORD(wParam) == BN_DOUBLECLICKED)
750 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC2_WRAPMODE);
751 break;
374330e2 752 case IDC2_DECOM:
753 if (HIWORD(wParam) == BN_CLICKED ||
754 HIWORD(wParam) == BN_DOUBLECLICKED)
755 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC2_DECOM);
756 break;
fef97f43 757 case IDC2_LFHASCR:
758 if (HIWORD(wParam) == BN_CLICKED ||
759 HIWORD(wParam) == BN_DOUBLECLICKED)
760 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC2_LFHASCR);
761 break;
374330e2 762 case IDC2_ROWSEDIT:
763 if (HIWORD(wParam) == EN_CHANGE)
764 MyGetDlgItemInt (hwnd, IDC2_ROWSEDIT, &cfg.height);
765 break;
766 case IDC2_COLSEDIT:
767 if (HIWORD(wParam) == EN_CHANGE)
768 MyGetDlgItemInt (hwnd, IDC2_COLSEDIT, &cfg.width);
769 break;
770 case IDC2_SAVEEDIT:
771 if (HIWORD(wParam) == EN_CHANGE)
772 MyGetDlgItemInt (hwnd, IDC2_SAVEEDIT, &cfg.savelines);
773 break;
774 case IDC2_CHOOSEFONT:
775 lf.lfHeight = cfg.fontheight;
776 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
777 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
778 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
14963b8f 779 lf.lfCharSet = cfg.fontcharset;
374330e2 780 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
781 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
782 lf.lfQuality = DEFAULT_QUALITY;
783 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
784 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
785 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
786
787 cf.lStructSize = sizeof(cf);
788 cf.hwndOwner = hwnd;
789 cf.lpLogFont = &lf;
790 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
791 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
792
793 if (ChooseFont (&cf)) {
794 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
795 cfg.font[sizeof(cfg.font)-1] = '\0';
796 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
14963b8f 797 cfg.fontcharset = lf.lfCharSet;
374330e2 798 cfg.fontheight = lf.lfHeight;
799 fmtfont (fontstatic);
800 SetDlgItemText (hwnd, IDC2_FONTSTATIC, fontstatic);
801 }
802 break;
c9def1b8 803 case IDC1_BEEP:
804 if (HIWORD(wParam) == BN_CLICKED ||
805 HIWORD(wParam) == BN_DOUBLECLICKED)
806 cfg.beep = IsDlgButtonChecked (hwnd, IDC1_BEEP);
807 break;
c9def1b8 808 case IDC2_BLINKTEXT:
809 if (HIWORD(wParam) == BN_CLICKED ||
810 HIWORD(wParam) == BN_DOUBLECLICKED)
811 cfg.blinktext = IsDlgButtonChecked (hwnd, IDC2_BLINKTEXT);
812 break;
813 case IDC2_BCE:
814 if (HIWORD(wParam) == BN_CLICKED ||
815 HIWORD(wParam) == BN_DOUBLECLICKED)
816 cfg.bce = IsDlgButtonChecked (hwnd, IDC2_BCE);
817 break;
374330e2 818 }
819 break;
820 }
821 return GeneralPanelProc (hwnd, msg, wParam, lParam);
822}
823
9ca5da42 824static int CALLBACK WindowProc (HWND hwnd, UINT msg,
825 WPARAM wParam, LPARAM lParam) {
826 switch (msg) {
827 case WM_INITDIALOG:
828 SetDlgItemText (hwnd, IDCW_WINEDIT, cfg.wintitle);
829 CheckDlgButton (hwnd, IDCW_WINNAME, cfg.win_name_always);
830 CheckDlgButton (hwnd, IDCW_BLINKCUR, cfg.blink_cur);
831 CheckDlgButton (hwnd, IDCW_SCROLLBAR, cfg.scrollbar);
832 CheckDlgButton (hwnd, IDCW_LOCKSIZE, cfg.locksize);
833 break;
834 case WM_COMMAND:
835 switch (LOWORD(wParam)) {
836 case IDCW_WINNAME:
837 if (HIWORD(wParam) == BN_CLICKED ||
838 HIWORD(wParam) == BN_DOUBLECLICKED)
839 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDCW_WINNAME);
840 break;
841 case IDCW_BLINKCUR:
842 if (HIWORD(wParam) == BN_CLICKED ||
843 HIWORD(wParam) == BN_DOUBLECLICKED)
844 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDCW_BLINKCUR);
845 break;
846 case IDCW_SCROLLBAR:
847 if (HIWORD(wParam) == BN_CLICKED ||
848 HIWORD(wParam) == BN_DOUBLECLICKED)
849 cfg.scrollbar = IsDlgButtonChecked (hwnd, IDCW_SCROLLBAR);
850 break;
851 case IDCW_LOCKSIZE:
852 if (HIWORD(wParam) == BN_CLICKED ||
853 HIWORD(wParam) == BN_DOUBLECLICKED)
854 cfg.locksize = IsDlgButtonChecked (hwnd, IDCW_LOCKSIZE);
855 break;
856 case IDCW_WINEDIT:
857 if (HIWORD(wParam) == EN_CHANGE)
858 GetDlgItemText (hwnd, IDCW_WINEDIT, cfg.wintitle,
859 sizeof(cfg.wintitle)-1);
860 break;
861 }
862 break;
863 }
864 return GeneralPanelProc (hwnd, msg, wParam, lParam);
865}
866
374330e2 867static int CALLBACK TelnetProc (HWND hwnd, UINT msg,
868 WPARAM wParam, LPARAM lParam) {
869 int i;
870
871 switch (msg) {
872 case WM_INITDIALOG:
873 SetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype);
874 SetDlgItemText (hwnd, IDC3_TSEDIT, cfg.termspeed);
875 SetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username);
876 {
37508af4 877 char *p = cfg.environmt;
374330e2 878 while (*p) {
879 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_ADDSTRING, 0,
880 (LPARAM) p);
881 p += strlen(p)+1;
882 }
883 }
884 CheckRadioButton (hwnd, IDC3_EMBSD, IDC3_EMRFC,
885 cfg.rfc_environ ? IDC3_EMRFC : IDC3_EMBSD);
886 break;
887 case WM_COMMAND:
888 switch (LOWORD(wParam)) {
889 case IDC3_TTEDIT:
890 if (HIWORD(wParam) == EN_CHANGE)
891 GetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype,
892 sizeof(cfg.termtype)-1);
893 break;
894 case IDC3_TSEDIT:
895 if (HIWORD(wParam) == EN_CHANGE)
896 GetDlgItemText (hwnd, IDC3_TSEDIT, cfg.termspeed,
897 sizeof(cfg.termspeed)-1);
898 break;
899 case IDC3_LOGEDIT:
900 if (HIWORD(wParam) == EN_CHANGE)
901 GetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username,
902 sizeof(cfg.username)-1);
903 break;
904 case IDC3_EMBSD:
905 case IDC3_EMRFC:
906 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC3_EMRFC);
907 break;
908 case IDC3_ENVADD:
909 if (HIWORD(wParam) == BN_CLICKED ||
910 HIWORD(wParam) == BN_DOUBLECLICKED) {
37508af4 911 char str[sizeof(cfg.environmt)];
374330e2 912 char *p;
913 GetDlgItemText (hwnd, IDC3_VAREDIT, str, sizeof(str)-1);
914 if (!*str) {
915 MessageBeep(0);
916 break;
917 }
918 p = str + strlen(str);
919 *p++ = '\t';
920 GetDlgItemText (hwnd, IDC3_VALEDIT, p, sizeof(str)-1-(p-str));
921 if (!*p) {
922 MessageBeep(0);
923 break;
924 }
37508af4 925 p = cfg.environmt;
374330e2 926 while (*p) {
927 while (*p) p++;
928 p++;
929 }
37508af4 930 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
374330e2 931 strcpy (p, str);
932 p[strlen(str)+1] = '\0';
933 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_ADDSTRING,
934 0, (LPARAM)str);
935 SetDlgItemText (hwnd, IDC3_VAREDIT, "");
936 SetDlgItemText (hwnd, IDC3_VALEDIT, "");
937 } else {
938 MessageBox(hwnd, "Environment too big", "PuTTY Error",
939 MB_OK | MB_ICONERROR);
940 }
941 }
942 break;
943 case IDC3_ENVREMOVE:
944 if (HIWORD(wParam) != BN_CLICKED &&
945 HIWORD(wParam) != BN_DOUBLECLICKED)
946 break;
947 i = SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_GETCURSEL, 0, 0);
948 if (i == LB_ERR)
949 MessageBeep (0);
950 else {
951 char *p, *q;
952
953 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_DELETESTRING,
954 i, 0);
37508af4 955 p = cfg.environmt;
374330e2 956 while (i > 0) {
957 if (!*p)
958 goto disaster;
959 while (*p) p++;
960 p++;
961 i--;
962 }
963 q = p;
964 if (!*p)
965 goto disaster;
966 while (*p) p++;
967 p++;
968 while (*p) {
969 while (*p)
970 *q++ = *p++;
971 *q++ = *p++;
972 }
973 *q = '\0';
974 disaster:;
975 }
976 break;
977 }
978 break;
979 }
980 return GeneralPanelProc (hwnd, msg, wParam, lParam);
981}
982
983static int CALLBACK SshProc (HWND hwnd, UINT msg,
984 WPARAM wParam, LPARAM lParam) {
7cca0d81 985 OPENFILENAME of;
986 char filename[sizeof(cfg.keyfile)];
987
374330e2 988 switch (msg) {
989 case WM_INITDIALOG:
990 SetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype);
991 SetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username);
fef97f43 992 CheckDlgButton (hwnd, IDC3_NOPTY, cfg.nopty);
979310f1 993 CheckDlgButton (hwnd, IDC3_AGENTFWD, cfg.agentfwd);
9697bfd2 994 CheckRadioButton (hwnd, IDC3_CIPHER3DES, IDC3_CIPHERDES,
bea1ef5f 995 cfg.cipher == CIPHER_BLOWFISH ? IDC3_CIPHERBLOWF :
9697bfd2 996 cfg.cipher == CIPHER_DES ? IDC3_CIPHERDES :
bea1ef5f 997 IDC3_CIPHER3DES);
adf799dd 998 CheckRadioButton (hwnd, IDC3_SSHPROT1, IDC3_SSHPROT2,
999 cfg.sshprot == 1 ? IDC3_SSHPROT1 : IDC3_SSHPROT2);
ccbfb941 1000 CheckDlgButton (hwnd, IDC3_AUTHTIS, cfg.try_tis_auth);
7cca0d81 1001 SetDlgItemText (hwnd, IDC3_PKEDIT, cfg.keyfile);
4c73ca1f 1002 SetDlgItemText (hwnd, IDC3_CMDEDIT, cfg.remote_cmd);
374330e2 1003 break;
1004 case WM_COMMAND:
1005 switch (LOWORD(wParam)) {
1006 case IDC3_TTEDIT:
1007 if (HIWORD(wParam) == EN_CHANGE)
1008 GetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype,
1009 sizeof(cfg.termtype)-1);
1010 break;
1011 case IDC3_LOGEDIT:
1012 if (HIWORD(wParam) == EN_CHANGE)
1013 GetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username,
1014 sizeof(cfg.username)-1);
1015 break;
fef97f43 1016 case IDC3_NOPTY:
1017 if (HIWORD(wParam) == BN_CLICKED ||
1018 HIWORD(wParam) == BN_DOUBLECLICKED)
1019 cfg.nopty = IsDlgButtonChecked (hwnd, IDC3_NOPTY);
1020 break;
979310f1 1021 case IDC3_AGENTFWD:
1022 if (HIWORD(wParam) == BN_CLICKED ||
1023 HIWORD(wParam) == BN_DOUBLECLICKED)
1024 cfg.agentfwd = IsDlgButtonChecked (hwnd, IDC3_AGENTFWD);
1025 break;
bea1ef5f 1026 case IDC3_CIPHER3DES:
1027 case IDC3_CIPHERBLOWF:
9697bfd2 1028 case IDC3_CIPHERDES:
bea1ef5f 1029 if (HIWORD(wParam) == BN_CLICKED ||
1030 HIWORD(wParam) == BN_DOUBLECLICKED) {
1031 if (IsDlgButtonChecked (hwnd, IDC3_CIPHER3DES))
1032 cfg.cipher = CIPHER_3DES;
1033 else if (IsDlgButtonChecked (hwnd, IDC3_CIPHERBLOWF))
1034 cfg.cipher = CIPHER_BLOWFISH;
9697bfd2 1035 else if (IsDlgButtonChecked (hwnd, IDC3_CIPHERDES))
1036 cfg.cipher = CIPHER_DES;
bea1ef5f 1037 }
1038 break;
adf799dd 1039 case IDC3_SSHPROT1:
1040 case IDC3_SSHPROT2:
1041 if (HIWORD(wParam) == BN_CLICKED ||
1042 HIWORD(wParam) == BN_DOUBLECLICKED) {
1043 if (IsDlgButtonChecked (hwnd, IDC3_SSHPROT1))
1044 cfg.sshprot = 1;
1045 else if (IsDlgButtonChecked (hwnd, IDC3_SSHPROT2))
1046 cfg.sshprot = 2;
1047 }
1048 break;
ccbfb941 1049 case IDC3_AUTHTIS:
1050 if (HIWORD(wParam) == BN_CLICKED ||
1051 HIWORD(wParam) == BN_DOUBLECLICKED)
1052 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC3_AUTHTIS);
1053 break;
7cca0d81 1054 case IDC3_PKEDIT:
1055 if (HIWORD(wParam) == EN_CHANGE)
1056 GetDlgItemText (hwnd, IDC3_PKEDIT, cfg.keyfile,
1057 sizeof(cfg.keyfile)-1);
1058 break;
4c73ca1f 1059 case IDC3_CMDEDIT:
1060 if (HIWORD(wParam) == EN_CHANGE)
1061 GetDlgItemText (hwnd, IDC3_CMDEDIT, cfg.remote_cmd,
1062 sizeof(cfg.remote_cmd)-1);
1063 break;
7cca0d81 1064 case IDC3_PKBUTTON:
1065 /*
1066 * FIXME: this crashes. Find out why.
1067 */
1068 memset(&of, 0, sizeof(of));
1069#ifdef OPENFILENAME_SIZE_VERSION_400
1070 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1071#else
1072 of.lStructSize = sizeof(of);
1073#endif
1074 of.hwndOwner = hwnd;
1075 of.lpstrFilter = "All Files\0*\0\0\0";
1076 of.lpstrCustomFilter = NULL;
1077 of.nFilterIndex = 1;
1078 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1079 of.nMaxFile = sizeof(filename);
1080 of.lpstrFileTitle = NULL;
1081 of.lpstrInitialDir = NULL;
1082 of.lpstrTitle = "Select Public Key File";
1083 of.Flags = 0;
1084 if (GetOpenFileName(&of)) {
1085 strcpy(cfg.keyfile, filename);
1086 SetDlgItemText (hwnd, IDC3_PKEDIT, cfg.keyfile);
1087 }
1088 break;
374330e2 1089 }
1090 break;
1091 }
1092 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1093}
1094
1095static int CALLBACK SelectionProc (HWND hwnd, UINT msg,
1096 WPARAM wParam, LPARAM lParam) {
1097 int i;
1098
1099 switch (msg) {
1100 case WM_INITDIALOG:
1101 CheckRadioButton (hwnd, IDC4_MBWINDOWS, IDC4_MBXTERM,
1102 cfg.mouse_is_xterm ? IDC4_MBXTERM : IDC4_MBWINDOWS);
1103 {
1104 static int tabs[4] = {25, 61, 96, 128};
1105 SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_SETTABSTOPS, 4,
1106 (LPARAM) tabs);
1107 }
1108 for (i=0; i<256; i++) {
1109 char str[100];
1110 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1111 (i>=0x21 && i != 0x7F) ? i : ' ',
1112 cfg.wordness[i]);
1113 SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_ADDSTRING, 0,
1114 (LPARAM) str);
1115 }
1116 break;
1117 case WM_COMMAND:
1118 switch (LOWORD(wParam)) {
1119 case IDC4_MBWINDOWS:
1120 case IDC4_MBXTERM:
1121 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC4_MBXTERM);
1122 break;
1123 case IDC4_CCSET:
1124 {
1125 BOOL ok;
1126 int i;
1127 int n = GetDlgItemInt (hwnd, IDC4_CCEDIT, &ok, FALSE);
1128
1129 if (!ok)
1130 MessageBeep (0);
1131 else {
1132 for (i=0; i<256; i++)
1133 if (SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_GETSEL,
1134 i, 0)) {
1135 char str[100];
1136 cfg.wordness[i] = n;
1137 SendDlgItemMessage (hwnd, IDC4_CCLIST,
1138 LB_DELETESTRING, i, 0);
1139 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1140 (i>=0x21 && i != 0x7F) ? i : ' ',
1141 cfg.wordness[i]);
1142 SendDlgItemMessage (hwnd, IDC4_CCLIST,
1143 LB_INSERTSTRING, i,
1144 (LPARAM)str);
1145 }
1146 }
1147 }
1148 break;
1149 }
1150 break;
1151 }
1152 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1153}
1154
1155static int CALLBACK ColourProc (HWND hwnd, UINT msg,
1156 WPARAM wParam, LPARAM lParam) {
1157 static const char *const colours[] = {
1158 "Default Foreground", "Default Bold Foreground",
1159 "Default Background", "Default Bold Background",
1160 "Cursor Text", "Cursor Colour",
1161 "ANSI Black", "ANSI Black Bold",
1162 "ANSI Red", "ANSI Red Bold",
1163 "ANSI Green", "ANSI Green Bold",
1164 "ANSI Yellow", "ANSI Yellow Bold",
1165 "ANSI Blue", "ANSI Blue Bold",
1166 "ANSI Magenta", "ANSI Magenta Bold",
1167 "ANSI Cyan", "ANSI Cyan Bold",
1168 "ANSI White", "ANSI White Bold"
1169 };
1170 static const int permanent[] = {
1171 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
1172 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
1173 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
1174 };
1175 switch (msg) {
1176 case WM_INITDIALOG:
1177 CheckDlgButton (hwnd, IDC5_BOLDCOLOUR, cfg.bold_colour);
1178 CheckDlgButton (hwnd, IDC5_PALETTE, cfg.try_palette);
1179 {
1180 int i;
1181 for (i=0; i<22; i++)
1182 if (cfg.bold_colour || permanent[i])
1183 SendDlgItemMessage (hwnd, IDC5_LIST, LB_ADDSTRING, 0,
1184 (LPARAM) colours[i]);
1185 }
1186 SendDlgItemMessage (hwnd, IDC5_LIST, LB_SETCURSEL, 0, 0);
1187 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[0][0], FALSE);
1188 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[0][1], FALSE);
1189 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[0][2], FALSE);
1190 break;
1191 case WM_COMMAND:
1192 switch (LOWORD(wParam)) {
1193 case IDC5_BOLDCOLOUR:
1194 if (HIWORD(wParam) == BN_CLICKED ||
1195 HIWORD(wParam) == BN_DOUBLECLICKED) {
1196 int n, i;
1197 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC5_BOLDCOLOUR);
1198 n = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCOUNT, 0, 0);
1199 if (cfg.bold_colour && n!=22) {
1200 for (i=0; i<22; i++)
1201 if (!permanent[i])
1202 SendDlgItemMessage (hwnd, IDC5_LIST,
1203 LB_INSERTSTRING, i,
1204 (LPARAM) colours[i]);
1205 } else if (!cfg.bold_colour && n!=12) {
1206 for (i=22; i-- ;)
1207 if (!permanent[i])
1208 SendDlgItemMessage (hwnd, IDC5_LIST,
1209 LB_DELETESTRING, i, 0);
1210 }
1211 }
1212 break;
1213 case IDC5_PALETTE:
1214 if (HIWORD(wParam) == BN_CLICKED ||
1215 HIWORD(wParam) == BN_DOUBLECLICKED)
1216 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC5_PALETTE);
1217 break;
1218 case IDC5_LIST:
1219 if (HIWORD(wParam) == LBN_DBLCLK ||
1220 HIWORD(wParam) == LBN_SELCHANGE) {
1221 int i = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCURSEL,
1222 0, 0);
1223 if (!cfg.bold_colour)
1224 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1225 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[i][0], FALSE);
1226 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[i][1], FALSE);
1227 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[i][2], FALSE);
1228 }
1229 break;
1230 case IDC5_CHANGE:
1231 if (HIWORD(wParam) == BN_CLICKED ||
1232 HIWORD(wParam) == BN_DOUBLECLICKED) {
1233 static CHOOSECOLOR cc;
1234 static DWORD custom[16] = {0}; /* zero initialisers */
1235 int i = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCURSEL,
1236 0, 0);
1237 if (!cfg.bold_colour)
1238 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1239 cc.lStructSize = sizeof(cc);
1240 cc.hwndOwner = hwnd;
1d470ad2 1241 cc.hInstance = (HWND)hinst;
374330e2 1242 cc.lpCustColors = custom;
1243 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1244 cfg.colours[i][2]);
1245 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1246 if (ChooseColor(&cc)) {
1247 cfg.colours[i][0] =
1248 (unsigned char) (cc.rgbResult & 0xFF);
1249 cfg.colours[i][1] =
1250 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1251 cfg.colours[i][2] =
1252 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1253 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[i][0],
1254 FALSE);
1255 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[i][1],
1256 FALSE);
1257 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[i][2],
1258 FALSE);
1259 }
1260 }
1261 break;
1262 }
1263 break;
1264 }
1265 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1266}
1267
c9def1b8 1268static int CALLBACK TranslationProc (HWND hwnd, UINT msg,
14963b8f 1269 WPARAM wParam, LPARAM lParam) {
1270 switch (msg) {
1271 case WM_INITDIALOG:
d3d16feb 1272 CheckRadioButton (hwnd, IDC6_NOXLAT, IDC6_88592WIN1250,
1273 cfg.xlat_88592w1250 ? IDC6_88592WIN1250 :
1274 cfg.xlat_enablekoiwin ? IDC6_KOI8WIN1251 :
1275 IDC6_NOXLAT);
14963b8f 1276 CheckDlgButton (hwnd, IDC6_CAPSLOCKCYR, cfg.xlat_capslockcyr);
c9def1b8 1277 CheckRadioButton (hwnd, IDC2_VTXWINDOWS, IDC2_VTPOORMAN,
1278 cfg.vtmode == VT_XWINDOWS ? IDC2_VTXWINDOWS :
1279 cfg.vtmode == VT_OEMANSI ? IDC2_VTOEMANSI :
1280 cfg.vtmode == VT_OEMONLY ? IDC2_VTOEMONLY :
1281 IDC2_VTPOORMAN);
14963b8f 1282 case WM_COMMAND:
1283 switch (LOWORD(wParam)) {
d3d16feb 1284 case IDC6_NOXLAT:
1285 case IDC6_KOI8WIN1251:
1286 case IDC6_88592WIN1250:
1287 cfg.xlat_enablekoiwin =
1288 IsDlgButtonChecked (hwnd, IDC6_KOI8WIN1251);
1289 cfg.xlat_88592w1250 =
1290 IsDlgButtonChecked (hwnd, IDC6_88592WIN1250);
14963b8f 1291 break;
1292 case IDC6_CAPSLOCKCYR:
1293 if (HIWORD(wParam) == BN_CLICKED ||
1294 HIWORD(wParam) == BN_DOUBLECLICKED) {
1295 cfg.xlat_capslockcyr =
1296 IsDlgButtonChecked (hwnd, IDC6_CAPSLOCKCYR);
1297 }
1298 break;
c9def1b8 1299 case IDC2_VTXWINDOWS:
1300 case IDC2_VTOEMANSI:
1301 case IDC2_VTOEMONLY:
1302 case IDC2_VTPOORMAN:
1303 cfg.vtmode =
1304 (IsDlgButtonChecked (hwnd, IDC2_VTXWINDOWS) ? VT_XWINDOWS :
1305 IsDlgButtonChecked (hwnd, IDC2_VTOEMANSI) ? VT_OEMANSI :
1306 IsDlgButtonChecked (hwnd, IDC2_VTOEMONLY) ? VT_OEMONLY :
1307 VT_POORMAN);
1308 break;
14963b8f 1309 }
1310 }
1311 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1312}
1313
374330e2 1314static DLGPROC panelproc[NPANELS] = {
9ca5da42 1315 ConnectionProc, KeyboardProc, TerminalProc, WindowProc,
c9def1b8 1316 TelnetProc, SshProc, SelectionProc, ColourProc, TranslationProc
374330e2 1317};
1318static char *panelids[NPANELS] = {
1319 MAKEINTRESOURCE(IDD_PANEL0),
1320 MAKEINTRESOURCE(IDD_PANEL1),
1321 MAKEINTRESOURCE(IDD_PANEL2),
9ca5da42 1322 MAKEINTRESOURCE(IDD_PANELW),
374330e2 1323 MAKEINTRESOURCE(IDD_PANEL3),
1324 MAKEINTRESOURCE(IDD_PANEL35),
1325 MAKEINTRESOURCE(IDD_PANEL4),
14963b8f 1326 MAKEINTRESOURCE(IDD_PANEL5),
1327 MAKEINTRESOURCE(IDD_PANEL6)
374330e2 1328};
14963b8f 1329
374330e2 1330static char *names[NPANELS] = {
9ca5da42 1331 "Connection", "Keyboard", "Terminal", "Window", "Telnet",
c9def1b8 1332 "SSH", "Selection", "Colours", "Translation"
374330e2 1333};
1334
9ca5da42 1335static int mainp[MAIN_NPANELS] = { 0, 1, 2, 3, 4, 5, 6, 7, 8};
1336static int reconfp[RECONF_NPANELS] = { 1, 2, 3, 6, 7, 8};
374330e2 1337
1338static int GenericMainDlgProc (HWND hwnd, UINT msg,
1339 WPARAM wParam, LPARAM lParam,
1340 int npanels, int *panelnums, HWND *page) {
1341 HWND hw;
1342
1343 switch (msg) {
1344 case WM_INITDIALOG:
1345 { /* centre the window */
1346 RECT rs, rd;
1347
1348 hw = GetDesktopWindow();
1349 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
1350 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
1351 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
1352 rd.right-rd.left, rd.bottom-rd.top, TRUE);
1353 }
1354 *page = NULL;
1355 { /* initialise the tab control */
1356 TC_ITEMHEADER tab;
1357 int i;
1358
1359 hw = GetDlgItem (hwnd, IDC_TAB);
1360 for (i=0; i<npanels; i++) {
1361 tab.mask = TCIF_TEXT;
1362 tab.pszText = names[panelnums[i]];
1363 TabCtrl_InsertItem (hw, i, &tab);
1364 }
1365/* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1366 hwnd, panelproc[panelnums[0]]);*/
1367 *page = CreateDialog (hinst, panelids[panelnums[0]],
1368 hwnd, panelproc[panelnums[0]]);
1369 SetWindowLong (*page, GWL_EXSTYLE,
1370 GetWindowLong (*page, GWL_EXSTYLE) |
1371 WS_EX_CONTROLPARENT);
1372 }
1373 SetFocus (*page);
1374 return 0;
1375 case WM_NOTIFY:
1376 if (LOWORD(wParam) == IDC_TAB &&
1377 ((LPNMHDR)lParam)->code == TCN_SELCHANGE) {
1378 int i = TabCtrl_GetCurSel(((LPNMHDR)lParam)->hwndFrom);
1379 if (*page)
1380 DestroyWindow (*page);
1381/* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1382 hwnd, panelproc[panelnums[i]]);*/
1383 *page = CreateDialog (hinst, panelids[panelnums[i]],
1384 hwnd, panelproc[panelnums[i]]);
1385 SetWindowLong (*page, GWL_EXSTYLE,
1386 GetWindowLong (*page, GWL_EXSTYLE) |
1387 WS_EX_CONTROLPARENT);
1388 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1389 return 0;
1390 }
1391 break;
1392/* case WM_CTLCOLORDLG: */
1393/* return (int) GetStockObject (LTGRAY_BRUSH); */
1394 case WM_COMMAND:
1395 switch (LOWORD(wParam)) {
1396 case IDOK:
1397 if (*cfg.host)
1398 EndDialog (hwnd, 1);
1399 else
1400 MessageBeep (0);
1401 return 0;
1402 case IDCANCEL:
1403 EndDialog (hwnd, 0);
1404 return 0;
1405 }
1406 return 0;
1407 case WM_CLOSE:
1408 EndDialog (hwnd, 0);
1409 return 0;
c9def1b8 1410
1411 /* Grrr Explorer will maximize Dialogs! */
1412 case WM_SIZE:
1413 if (wParam == SIZE_MAXIMIZED)
1414 force_normal(hwnd);
1415 return 0;
374330e2 1416 }
1417 return 0;
1418}
1419
1420static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
1421 WPARAM wParam, LPARAM lParam) {
1422#if 0
1423 HWND hw;
1424 int i;
1425#endif
1426 static HWND page = NULL;
1427
1428 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
1429#if 0
1430 /*
1431 * If the Connection panel is active and the Session List
1432 * box is selected, we treat a press of Open to have an
1433 * implicit press of Load preceding it.
1434 */
1435 hw = GetDlgItem (hwnd, IDC_TAB);
1436 i = TabCtrl_GetCurSel(hw);
1437 if (panelproc[mainp[i]] == ConnectionProc &&
1438 page && implicit_load_ok) {
1439 SendMessage (page, WM_COMMAND,
1440 MAKELONG(IDC0_SESSLOAD, BN_CLICKED), 0);
1441 }
1442#endif
1443 }
1444 if (msg == WM_COMMAND && LOWORD(wParam) == IDC_ABOUT) {
1445 EnableWindow(hwnd, 0);
1446 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1447 GetParent(hwnd), AboutProc);
1448 EnableWindow(hwnd, 1);
9a70ac47 1449 SetActiveWindow(hwnd);
374330e2 1450 }
1451 return GenericMainDlgProc (hwnd, msg, wParam, lParam,
1452 MAIN_NPANELS, mainp, &page);
1453}
1454
1455static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
1456 WPARAM wParam, LPARAM lParam) {
1457 static HWND page;
1458 return GenericMainDlgProc (hwnd, msg, wParam, lParam,
1459 RECONF_NPANELS, reconfp, &page);
1460}
1461
0a4aa984 1462void get_sesslist(int allocate) {
d1622aed 1463 static char otherbuf[2048];
374330e2 1464 static char *buffer;
d1622aed 1465 int buflen, bufsize, i;
1466 char *p, *ret;
1467 void *handle;
374330e2 1468
1469 if (allocate) {
d1622aed 1470
1471 if ((handle = enum_settings_start()) == NULL)
374330e2 1472 return;
1473
1474 buflen = bufsize = 0;
1475 buffer = NULL;
374330e2 1476 do {
d1622aed 1477 ret = enum_settings_next(handle, otherbuf, sizeof(otherbuf));
1478 if (ret) {
1479 int len = strlen(otherbuf)+1;
1480 if (bufsize < buflen+len) {
1481 bufsize = buflen + len + 2048;
1482 buffer = srealloc(buffer, bufsize);
1483 }
1484 strcpy(buffer+buflen, otherbuf);
374330e2 1485 buflen += strlen(buffer+buflen)+1;
1486 }
d1622aed 1487 } while (ret);
1488 enum_settings_finish(handle);
374330e2 1489 buffer = srealloc(buffer, buflen+1);
1490 buffer[buflen] = '\0';
1491
1492 p = buffer;
1493 nsessions = 1; /* "Default Settings" counts as one */
1494 while (*p) {
1495 if (strcmp(p, "Default Settings"))
1496 nsessions++;
1497 while (*p) p++;
1498 p++;
1499 }
1500
1501 sessions = smalloc(nsessions * sizeof(char *));
1502 sessions[0] = "Default Settings";
1503 p = buffer;
1504 i = 1;
1505 while (*p) {
1506 if (strcmp(p, "Default Settings"))
1507 sessions[i++] = p;
1508 while (*p) p++;
1509 p++;
1510 }
1511 } else {
1512 sfree (buffer);
1513 sfree (sessions);
1514 }
1515}
1516
1517int do_config (void) {
1518 int ret;
1519
1520 get_sesslist(TRUE);
6584031a 1521 savedsession[0] = '\0';
374330e2 1522 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
1523 get_sesslist(FALSE);
1524
1525 return ret;
1526}
1527
1528int do_reconfig (HWND hwnd) {
1529 Config backup_cfg;
1530 int ret;
1531
1532 backup_cfg = cfg; /* structure copy */
1533 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
1534 if (!ret)
1535 cfg = backup_cfg; /* structure copy */
c9def1b8 1536 else
1537 force_normal(hwnd);
1538
374330e2 1539 return ret;
1540}
1541
1542void do_defaults (char *session) {
1543 if (session)
1544 load_settings (session, TRUE);
1545 else
1546 load_settings ("Default Settings", FALSE);
1547}
1548
c5e9c988 1549void logevent (char *string) {
1550 if (nevents >= negsize) {
374330e2 1551 negsize += 64;
c5e9c988 1552 events = srealloc (events, negsize * sizeof(*events));
374330e2 1553 }
c5e9c988 1554 events[nevents] = smalloc(1+strlen(string));
1555 strcpy (events[nevents], string);
1556 nevents++;
9ad90448 1557 if (logbox) {
1558 int count;
374330e2 1559 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
1560 0, (LPARAM)string);
9ad90448 1561 count = SendDlgItemMessage (logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
989b10e9 1562 SendDlgItemMessage (logbox, IDN_LIST, LB_SETTOPINDEX, count-1, 0);
9ad90448 1563 }
374330e2 1564}
1565
c5e9c988 1566void showeventlog (HWND hwnd) {
374330e2 1567 if (!logbox) {
1568 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
1569 hwnd, LogProc);
1570 ShowWindow (logbox, SW_SHOWNORMAL);
1571 }
1572}
1573
1574void showabout (HWND hwnd) {
1575 if (!abtbox) {
1576 abtbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1577 hwnd, AboutProc);
1578 ShowWindow (abtbox, SW_SHOWNORMAL);
1579 }
1580}
1581
d4857987 1582void verify_ssh_host_key(char *host, int port, char *keytype,
d5859615 1583 char *keystr, char *fingerprint) {
1584 int ret;
374330e2 1585
d5859615 1586 static const char absentmsg[] =
1587 "The server's host key is not cached in the registry. You\n"
1588 "have no guarantee that the server is the computer you\n"
1589 "think it is.\n"
1590 "The server's key fingerprint is:\n"
1591 "%s\n"
1592 "If you trust this host, hit Yes to add the key to\n"
1593 "PuTTY's cache and carry on connecting.\n"
1594 "If you do not trust this host, hit No to abandon the\n"
1595 "connection.\n";
1596
1597 static const char wrongmsg[] =
1598 "WARNING - POTENTIAL SECURITY BREACH!\n"
1599 "\n"
1600 "The server's host key does not match the one PuTTY has\n"
1601 "cached in the registry. This means that either the\n"
1602 "server administrator has changed the host key, or you\n"
1603 "have actually connected to another computer pretending\n"
1604 "to be the server.\n"
1605 "The new key fingerprint is:\n"
1606 "%s\n"
1607 "If you were expecting this change and trust the new key,\n"
1608 "hit Yes to update PuTTY's cache and continue connecting.\n"
1609 "If you want to carry on connecting but without updating\n"
1610 "the cache, hit No.\n"
1611 "If you want to abandon the connection completely, hit\n"
1612 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
1613 "choice.\n";
1614
1615 static const char mbtitle[] = "PuTTY Security Alert";
de3df031 1616
d5859615 1617
1618 char message[160+ /* sensible fingerprint max size */
1619 (sizeof(absentmsg) > sizeof(wrongmsg) ?
1620 sizeof(absentmsg) : sizeof(wrongmsg))];
de3df031 1621
1622 /*
d5859615 1623 * Verify the key against the registry.
de3df031 1624 */
d4857987 1625 ret = verify_host_key(host, port, keytype, keystr);
d5859615 1626
1627 if (ret == 0) /* success - key matched OK */
1628 return;
1629 if (ret == 2) { /* key was different */
1630 int mbret;
1631 sprintf(message, wrongmsg, fingerprint);
1632 mbret = MessageBox(NULL, message, mbtitle,
1633 MB_ICONWARNING | MB_YESNOCANCEL);
1634 if (mbret == IDYES)
d4857987 1635 store_host_key(host, port, keytype, keystr);
d5859615 1636 if (mbret == IDCANCEL)
1637 exit(0);
de3df031 1638 }
d5859615 1639 if (ret == 1) { /* key was absent */
1640 int mbret;
1641 sprintf(message, absentmsg, fingerprint);
1642 mbret = MessageBox(NULL, message, mbtitle,
1643 MB_ICONWARNING | MB_YESNO);
1644 if (mbret == IDNO)
1645 exit(0);
d4857987 1646 store_host_key(host, port, keytype, keystr);
de3df031 1647 }
de3df031 1648}