#include <winsock.h>
#include <stdio.h>
#include <stdlib.h>
+#include <ctype.h>
#define PUTTY_DO_GLOBALS /* actually _define_ globals */
#include "putty.h"
MSG msg;
int guess_width, guess_height;
+ putty_inst = inst;
+
winsock_ver = MAKEWORD(1, 1);
if (WSAStartup(winsock_ver, &wsadata)) {
MessageBox(NULL, "Unable to initialise WinSock", "WinSock Error",
tolower(p[2]) == 'h') {
default_protocol = cfg.protocol = PROT_SSH;
default_port = cfg.port = 22;
+ } else if (q == p + 3 &&
+ tolower(p[0]) == 'l' &&
+ tolower(p[1]) == 'o' &&
+ tolower(p[2]) == 'g') {
+ logfile = "putty.log";
}
p = q + strspn(q, " \t");
}
*/
HANDLE filemap;
Config *cp;
- if (sscanf(p+1, "%x", &filemap) == 1 &&
+ if (sscanf(p+1, "%p", &filemap) == 1 &&
(cp = MapViewOfFile(filemap, FILE_MAP_READ,
0, 0, sizeof(Config))) != NULL) {
cfg = *cp;
}
back = (cfg.protocol == PROT_SSH ? &ssh_backend :
- cfg.protocol == PROT_TELNET ? &telnet_backend : &raw_backend );
+ cfg.protocol == PROT_TELNET ? &telnet_backend :
+ &raw_backend);
+
+ ldisc = (cfg.ldisc_term ? &ldisc_term : &ldisc_simple);
if (!prev) {
wndclass.style = 0;
set_icon (msg);
}
+ session_closed = FALSE;
+
/*
* Set up the input and output buffers.
*/
inbuf_reap = inbuf_head = 0;
outbuf_reap = outbuf_head = 0;
+ /*
+ * Choose unscroll method
+ */
+ unscroll_event = US_DISP;
+
/*
* Prepare the mouse handler.
*/
AppendMenu (p, MF_ENABLED, IDM_TEL_EOR, "End Of Record");
AppendMenu (p, MF_ENABLED, IDM_TEL_EOF, "End Of File");
AppendMenu (m, MF_POPUP | MF_ENABLED, (UINT) p, "Telnet Command");
- AppendMenu (m, MF_ENABLED, IDM_SHOWLOG, "Show Negotiation");
AppendMenu (m, MF_SEPARATOR, 0, 0);
}
- AppendMenu (m, MF_ENABLED, IDM_NEWSESS, "New Session");
- AppendMenu (m, MF_ENABLED, IDM_DUPSESS, "Duplicate Session");
+ AppendMenu (m, MF_ENABLED, IDM_SHOWLOG, "&Event Log");
+ AppendMenu (m, MF_SEPARATOR, 0, 0);
+ AppendMenu (m, MF_ENABLED, IDM_NEWSESS, "Ne&w Session");
+ AppendMenu (m, MF_ENABLED, IDM_DUPSESS, "&Duplicate Session");
s = CreateMenu();
get_sesslist(TRUE);
for (i = 1 ; i < ((nsessions < 256) ? nsessions : 256) ; i++)
AppendMenu (s, MF_ENABLED, IDM_SAVED_MIN + (16 * i) , sessions[i]);
- AppendMenu (m, MF_POPUP | MF_ENABLED, (UINT) s, "Saved Sessions");
- AppendMenu (m, MF_ENABLED, IDM_RECONF, "Change Settings");
+ AppendMenu (m, MF_POPUP | MF_ENABLED, (UINT) s, "Sa&ved Sessions");
+ AppendMenu (m, MF_ENABLED, IDM_RECONF, "Chan&ge Settings");
AppendMenu (m, MF_SEPARATOR, 0, 0);
- AppendMenu (m, MF_ENABLED, IDM_CLRSB, "Clear Scrollback");
- AppendMenu (m, MF_ENABLED, IDM_RESET, "Reset Terminal");
+ AppendMenu (m, MF_ENABLED, IDM_CLRSB, "C&lear Scrollback");
+ AppendMenu (m, MF_ENABLED, IDM_RESET, "Rese&t Terminal");
AppendMenu (m, MF_SEPARATOR, 0, 0);
- AppendMenu (m, MF_ENABLED, IDM_ABOUT, "About PuTTY");
+ AppendMenu (m, MF_ENABLED, IDM_ABOUT, "&About PuTTY");
}
/*
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, \
FIXED_PITCH | FF_DONTCARE, cfg.font)
if (cfg.vtmode != VT_OEMONLY) {
- f(FONT_NORMAL, ANSI_CHARSET, fw_dontcare, FALSE);
- f(FONT_UNDERLINE, ANSI_CHARSET, fw_dontcare, TRUE);
+ f(FONT_NORMAL, cfg.fontcharset, fw_dontcare, FALSE);
+ f(FONT_UNDERLINE, cfg.fontcharset, fw_dontcare, TRUE);
}
if (cfg.vtmode == VT_OEMANSI || cfg.vtmode == VT_OEMONLY) {
f(FONT_OEM, OEM_CHARSET, fw_dontcare, FALSE);
}
if (bold_mode == BOLD_FONT) {
if (cfg.vtmode != VT_OEMONLY) {
- f(FONT_BOLD, ANSI_CHARSET, fw_bold, FALSE);
- f(FONT_BOLDUND, ANSI_CHARSET, fw_bold, TRUE);
+ f(FONT_BOLD, cfg.fontcharset, fw_bold, FALSE);
+ f(FONT_BOLDUND, cfg.fontcharset, fw_bold, TRUE);
}
if (cfg.vtmode == VT_OEMANSI || cfg.vtmode == VT_OEMONLY) {
f(FONT_OEMBOLD, OEM_CHARSET, fw_bold, FALSE);
switch (message) {
case WM_CREATE:
break;
+ case WM_CLOSE:
+ if (!cfg.warn_on_close || session_closed ||
+ MessageBox(hwnd, "Are you sure you want to close this session?",
+ "PuTTY Exit Confirmation",
+ MB_ICONWARNING | MB_OKCANCEL) == IDOK)
+ DestroyWindow(hwnd);
+ return 0;
case WM_DESTROY:
PostQuitMessage (0);
return 0;
case WM_SYSCOMMAND:
switch (wParam & ~0xF) { /* low 4 bits reserved to Windows */
case IDM_SHOWLOG:
- shownegot(hwnd);
+ showeventlog(hwnd);
break;
case IDM_NEWSESS:
case IDM_DUPSESS:
{
char b[2048];
char c[30], *cl;
+ int freecl = FALSE;
STARTUPINFO si;
PROCESS_INFORMATION pi;
HANDLE filemap = NULL;
UnmapViewOfFile(p);
}
}
- sprintf(c, "putty &%08x", filemap);
+ sprintf(c, "putty &%p", filemap);
cl = c;
} else if (wParam == IDM_SAVEDSESS) {
- sprintf(c, "putty @%s",
- sessions[(lParam - IDM_SAVED_MIN) / 16]);
- cl = c;
+ char *session = sessions[(lParam - IDM_SAVED_MIN) / 16];
+ cl = malloc(16 + strlen(session)); /* 8, but play safe */
+ if (!cl)
+ cl = NULL; /* not a very important failure mode */
+ else {
+ sprintf(cl, "putty @%s", session);
+ freecl = TRUE;
+ }
} else
cl = NULL;
if (filemap)
CloseHandle(filemap);
+ if (freecl)
+ free(cl);
}
break;
case IDM_RECONF:
und_mode = UND_FONT;
init_fonts();
sfree(logpal);
+ ldisc = (cfg.ldisc_term ? &ldisc_term : &ldisc_simple);
if (pal)
DeleteObject(pal);
logpal = NULL;
if (cfg.close_on_exit)
PostQuitMessage(0);
else {
+ session_closed = TRUE;
MessageBox(hwnd, "Connection closed by remote host",
"PuTTY", MB_OK | MB_ICONINFORMATION);
SetWindowText (hwnd, "PuTTY (inactive)");
case WM_IGNORE_SIZE:
ignore_size = TRUE; /* don't panic on next WM_SIZE msg */
break;
+ case WM_ENTERSIZEMOVE:
+ EnableSizeTip(1);
+ break;
+ case WM_EXITSIZEMOVE:
+ EnableSizeTip(0);
+ break;
case WM_SIZING:
{
int width, height, w, h, ew, eh;
height = r->bottom - r->top - extra_height;
w = (width + font_width/2) / font_width; if (w < 1) w = 1;
h = (height + font_height/2) / font_height; if (h < 1) h = 1;
+ UpdateSizeTip(hwnd, w, h);
ew = width - w * font_width;
eh = height - h * font_height;
if (ew != 0) {
int len;
len = TranslateKey (wParam, lParam, buf);
- back->send (buf, len);
+ if (len == -1)
+ return DefWindowProc (hwnd, message, wParam, lParam);
+ ldisc->send (buf, len);
}
return 0;
case WM_KEYUP:
* we're ready to cope.
*/
{
- char c = wParam;
- back->send (&c, 1);
+ char c = xlat_kbd2tty((unsigned char)wParam);
+ ldisc->send (&c, 1);
}
return 0;
}
ret = GetKeyboardState(keystate);
/*
+ * Record that we pressed key so the scroll window can be reset, but
+ * be careful to avoid Shift-UP/Down
+ */
+ if( wParam != VK_SHIFT && wParam != VK_PRIOR && wParam != VK_NEXT ) {
+ seen_key_event = 1;
+ }
+
+ /*
* Windows does not always want to distinguish left and right
* Alt or Control keys. Thus we keep track of them ourselves.
* See also the WM_KEYUP handler.
}
/*
+ * NetHack keypad mode. This may conflict with Shift-PgUp/PgDn,
+ * so we do it first.
+ */
+ if (cfg.nethack_keypad) {
+ int shift = keystate[VK_SHIFT] & 0x80;
+ /*
+ * NB the shifted versions only work with numlock off.
+ */
+ switch ( (lParam >> 16) & 0x1FF ) {
+ case 0x047: *p++ = shift ? 'Y' : 'y'; return p - output;
+ case 0x048: *p++ = shift ? 'K' : 'k'; return p - output;
+ case 0x049: *p++ = shift ? 'U' : 'u'; return p - output;
+ case 0x04B: *p++ = shift ? 'H' : 'h'; return p - output;
+ case 0x04C: *p++ = '.'; return p - output;
+ case 0x04D: *p++ = shift ? 'L' : 'l'; return p - output;
+ case 0x04F: *p++ = shift ? 'B' : 'b'; return p - output;
+ case 0x050: *p++ = shift ? 'J' : 'j'; return p - output;
+ case 0x051: *p++ = shift ? 'N' : 'n'; return p - output;
+ case 0x053: *p++ = '.'; return p - output;
+ }
+ }
+
+ /*
* Shift-PgUp, Shift-PgDn, and Alt-F4 all produce window
* events: we'll deal with those now.
*/
SendMessage (hwnd, WM_VSCROLL, SB_PAGEDOWN, 0);
return 0;
}
- if ((lParam & 0x20000000) && wParam == VK_F4) {
- SendMessage (hwnd, WM_DESTROY, 0, 0);
- return 0;
+ if ((lParam & 0x20000000) && wParam == VK_F4 && cfg.alt_f4) {
+ return -1;
+ }
+ if ((lParam & 0x20000000) && wParam == VK_SPACE && cfg.alt_space) {
+ SendMessage (hwnd, WM_SYSCOMMAND, SC_KEYMENU, 0);
+ return -1;
}
/*
return p - output;
}
- /*
- * If we're in applications keypad mode, we have to process it
- * before char-map translation, because it will pre-empt lots
- * of stuff, even if NumLock is off.
- */
if (app_keypad_keys) {
+ /*
+ * If we're in applications keypad mode, we have to process it
+ * before char-map translation, because it will pre-empt lots
+ * of stuff, even if NumLock is off.
+ */
if (ret) {
/*
* Hack to ensure NumLock doesn't interfere with
*/
if (ret) {
WORD chr;
- int r = ToAscii (wParam, (lParam >> 16) & 0xFF,
- keystate, &chr, 0);
+ int r;
+ BOOL capsOn=keystate[VK_CAPITAL] !=0;
+
+ /* helg: clear CAPS LOCK state if caps lock switches to cyrillic */
+ if(cfg.xlat_capslockcyr)
+ keystate[VK_CAPITAL] = 0;
+
+ r = ToAscii (wParam, (lParam >> 16) & 0xFF,
+ keystate, &chr, 0);
+
+ if(capsOn)
+ chr = xlat_latkbd2win((unsigned char)(chr & 0xFF));
if (r == 1) {
- *p++ = chr & 0xFF;
+ *p++ = xlat_kbd2tty((unsigned char)(chr & 0xFF));
return p - output;
}
}