#include <winsock.h>
#include <stdio.h>
#include <stdlib.h>
+#include <ctype.h>
#define PUTTY_DO_GLOBALS /* actually _define_ globals */
#include "putty.h"
#include "win_res.h"
-#define IDM_SHOWLOG 501
-#define IDM_NEWSESS 502
-#define IDM_DUPSESS 503
-#define IDM_RECONF 504
-#define IDM_CLRSB 505
-#define IDM_RESET 506
-#define IDM_TEL_AYT 507
-#define IDM_TEL_BRK 508
-#define IDM_TEL_SYNCH 509
-#define IDM_TEL_EC 510
-#define IDM_TEL_EL 511
-#define IDM_TEL_GA 512
-#define IDM_TEL_NOP 513
-#define IDM_TEL_ABORT 514
-#define IDM_TEL_AO 515
-#define IDM_TEL_IP 516
-#define IDM_TEL_SUSP 517
-#define IDM_TEL_EOR 518
-#define IDM_TEL_EOF 519
-#define IDM_ABOUT 520
+#define IDM_SHOWLOG 0x0010
+#define IDM_NEWSESS 0x0020
+#define IDM_DUPSESS 0x0030
+#define IDM_RECONF 0x0040
+#define IDM_CLRSB 0x0050
+#define IDM_RESET 0x0060
+#define IDM_TEL_AYT 0x0070
+#define IDM_TEL_BRK 0x0080
+#define IDM_TEL_SYNCH 0x0090
+#define IDM_TEL_EC 0x00a0
+#define IDM_TEL_EL 0x00b0
+#define IDM_TEL_GA 0x00c0
+#define IDM_TEL_NOP 0x00d0
+#define IDM_TEL_ABORT 0x00e0
+#define IDM_TEL_AO 0x00f0
+#define IDM_TEL_IP 0x0100
+#define IDM_TEL_SUSP 0x0110
+#define IDM_TEL_EOR 0x0120
+#define IDM_TEL_EOF 0x0130
+#define IDM_ABOUT 0x0140
+#define IDM_SAVEDSESS 0x0150
+
+#define IDM_SAVED_MIN 0x1000
+#define IDM_SAVED_MAX 0x2000
#define WM_IGNORE_SIZE (WM_USER + 2)
#define WM_IGNORE_CLIP (WM_USER + 3)
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",
{
char *p;
+ default_protocol = DEFAULT_PROTOCOL;
+ default_port = DEFAULT_PORT;
+
do_defaults(NULL);
p = cmdline;
while (*p && isspace(*p)) p++;
/*
+ * Process command line options first. Yes, this can be
+ * done better, and it will be as soon as I have the
+ * energy...
+ */
+ while (*p == '-') {
+ char *q = p + strcspn(p, " \t");
+ p++;
+ if (q == p + 3 &&
+ tolower(p[0]) == 's' &&
+ tolower(p[1]) == 's' &&
+ 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");
+ }
+
+ /*
* An initial @ means to activate a saved session.
*/
if (*p == '@') {
*/
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 : &telnet_backend);
+ back = (cfg.protocol == PROT_SSH ? &ssh_backend :
+ cfg.protocol == PROT_TELNET ? &telnet_backend :
+ &raw_backend);
+
+ ldisc = (cfg.ldisc_term ? &ldisc_term : &ldisc_simple);
if (!prev) {
wndclass.style = 0;
wndclass.hInstance = inst;
wndclass.hIcon = LoadIcon (inst,
MAKEINTRESOURCE(IDI_MAINICON));
- wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
+ wndclass.hCursor = LoadCursor (NULL, IDC_IBEAM);
wndclass.hbrBackground = GetStockObject (BLACK_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = appname;
return 0;
}
window_name = icon_name = NULL;
- sprintf(msg, "PuTTY: %s", realhost);
+ sprintf(msg, "%s - PuTTY", realhost);
set_title (msg);
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.
*/
*/
{
HMENU m = GetSystemMenu (hwnd, FALSE);
- HMENU p;
+ HMENU p,s;
+ int i;
AppendMenu (m, MF_SEPARATOR, 0, 0);
if (cfg.protocol == PROT_TELNET) {
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_RECONF, "Change Settings");
+ AppendMenu (m, MF_ENABLED, IDM_SHOWLOG, "&Event Log");
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_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, "Sa&ved Sessions");
+ AppendMenu (m, MF_ENABLED, IDM_RECONF, "Chan&ge Settings");
AppendMenu (m, MF_SEPARATOR, 0, 0);
- AppendMenu (m, MF_ENABLED, IDM_ABOUT, "About PuTTY");
+ 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");
}
/*
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);
}
static void click (Mouse_Button b, int x, int y) {
- if (lastbtn == b && GetMessageTime() - lasttime < dbltime) {
+ int thistime = GetMessageTime();
+
+ if (lastbtn == b && thistime - lasttime < dbltime) {
lastact = (lastact == MA_CLICK ? MA_2CLK :
lastact == MA_2CLK ? MA_3CLK :
lastact == MA_3CLK ? MA_CLICK : MA_NOTHING);
}
if (lastact != MA_NOTHING)
term_mouse (b, lastact, x, y);
- lasttime = GetMessageTime();
+ lasttime = thistime;
}
static int WINAPI WndProc (HWND hwnd, UINT message,
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) {
+ switch (wParam & ~0xF) { /* low 4 bits reserved to Windows */
case IDM_SHOWLOG:
- shownegot(hwnd);
+ showeventlog(hwnd);
break;
case IDM_NEWSESS:
case IDM_DUPSESS:
+ case IDM_SAVEDSESS:
{
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) {
+ 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;
case IDM_ABOUT:
showabout (hwnd);
break;
+ default:
+ if (wParam >= IDM_SAVED_MIN && wParam <= IDM_SAVED_MAX) {
+ SendMessage(hwnd, WM_SYSCOMMAND, IDM_SAVEDSESS, wParam);
+ }
}
break;
#define X_POS(l) ((int)(short)LOWORD(l))
#define Y_POS(l) ((int)(short)HIWORD(l))
+#define TO_CHR_X(x) (((x)<0 ? (x)-font_width+1 : (x)) / font_width)
+#define TO_CHR_Y(y) (((y)<0 ? (y)-font_height+1: (y)) / font_height)
+
case WM_LBUTTONDOWN:
+ click (MB_SELECT, TO_CHR_X(X_POS(lParam)),
+ TO_CHR_Y(Y_POS(lParam)));
SetCapture(hwnd);
- click (MB_SELECT, X_POS(lParam) / font_width,
- Y_POS(lParam) / font_height);
return 0;
case WM_LBUTTONUP:
- term_mouse (MB_SELECT, MA_RELEASE, X_POS(lParam) / font_width,
- Y_POS(lParam) / font_height);
+ term_mouse (MB_SELECT, MA_RELEASE, TO_CHR_X(X_POS(lParam)),
+ TO_CHR_Y(Y_POS(lParam)));
ReleaseCapture();
return 0;
case WM_MBUTTONDOWN:
SetCapture(hwnd);
click (cfg.mouse_is_xterm ? MB_PASTE : MB_EXTEND,
- X_POS(lParam) / font_width,
- Y_POS(lParam) / font_height);
+ TO_CHR_X(X_POS(lParam)),
+ TO_CHR_Y(Y_POS(lParam)));
return 0;
case WM_MBUTTONUP:
term_mouse (cfg.mouse_is_xterm ? MB_PASTE : MB_EXTEND,
- MA_RELEASE, X_POS(lParam) / font_width,
- Y_POS(lParam) / font_height);
- return 0;
+ MA_RELEASE, TO_CHR_X(X_POS(lParam)),
+ TO_CHR_Y(Y_POS(lParam)));
ReleaseCapture();
+ return 0;
case WM_RBUTTONDOWN:
SetCapture(hwnd);
click (cfg.mouse_is_xterm ? MB_EXTEND : MB_PASTE,
- X_POS(lParam) / font_width,
- Y_POS(lParam) / font_height);
+ TO_CHR_X(X_POS(lParam)),
+ TO_CHR_Y(Y_POS(lParam)));
return 0;
case WM_RBUTTONUP:
term_mouse (cfg.mouse_is_xterm ? MB_EXTEND : MB_PASTE,
- MA_RELEASE, X_POS(lParam) / font_width,
- Y_POS(lParam) / font_height);
+ MA_RELEASE, TO_CHR_X(X_POS(lParam)),
+ TO_CHR_Y(Y_POS(lParam)));
ReleaseCapture();
return 0;
case WM_MOUSEMOVE:
b = cfg.mouse_is_xterm ? MB_PASTE : MB_EXTEND;
else
b = cfg.mouse_is_xterm ? MB_EXTEND : MB_PASTE;
- term_mouse (b, MA_DRAG, X_POS(lParam) / font_width,
- Y_POS(lParam) / font_height);
+ term_mouse (b, MA_DRAG, TO_CHR_X(X_POS(lParam)),
+ TO_CHR_Y(Y_POS(lParam)));
}
- lastbtn = MB_NOTHING;
- lastact = MA_NOTHING;
- lasttime = GetMessageTime();
return 0;
case WM_IGNORE_CLIP:
ignore_clip = wParam; /* don't panic on DESTROYCLIPBOARD */
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) {
if (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED)
SetWindowText (hwnd, window_name);
if (!ignore_size) {
- int width, height, w, h, ew, eh;
+ int width, height, w, h;
+#if 0 /* we have fixed this using WM_SIZING now */
+ int ew, eh;
+#endif
width = LOWORD(lParam);
height = HIWORD(lParam);
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:
+ case WM_SYSKEYUP:
+ /*
+ * We handle KEYUP ourselves in order to distinghish left
+ * and right Alt or Control keys, which Windows won't do
+ * right if left to itself. See also the special processing
+ * at the top of TranslateKey.
+ */
+ {
+ BYTE keystate[256];
+ int ret = GetKeyboardState(keystate);
+ if (ret && wParam == VK_MENU) {
+ if (lParam & 0x1000000) keystate[VK_RMENU] = 0;
+ else keystate[VK_LMENU] = 0;
+ SetKeyboardState (keystate);
+ }
+ if (ret && wParam == VK_CONTROL) {
+ if (lParam & 0x1000000) keystate[VK_RCONTROL] = 0;
+ else keystate[VK_LCONTROL] = 0;
+ SetKeyboardState (keystate);
+ }
+ }
+ /*
+ * We don't return here, in order to allow Windows to do
+ * its own KEYUP processing as well.
+ */
+ break;
case WM_CHAR:
case WM_SYSCHAR:
/*
* 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;
}
TextOut (hdc, x-1, y, text, len);
}
if (und_mode == UND_LINE && (attr & ATTR_UNDER)) {
- SelectObject (hdc, CreatePen(PS_SOLID, 0, fg));
+ HPEN oldpen;
+ oldpen = SelectObject (hdc, CreatePen(PS_SOLID, 0, fg));
MoveToEx (hdc, x, y+descent, NULL);
LineTo (hdc, x+len*font_width, y+descent);
+ oldpen = SelectObject (hdc, oldpen);
+ DeleteObject (oldpen);
}
if (attr & ATTR_PASCURS) {
POINT pts[5];
+ HPEN oldpen;
pts[0].x = pts[1].x = pts[4].x = x;
pts[2].x = pts[3].x = x+font_width-1;
pts[0].y = pts[3].y = pts[4].y = y;
pts[1].y = pts[2].y = y+font_height-1;
- SelectObject (hdc, CreatePen(PS_SOLID, 0, colours[23]));
+ oldpen = SelectObject (hdc, CreatePen(PS_SOLID, 0, colours[23]));
Polyline (hdc, pts, 5);
+ oldpen = SelectObject (hdc, oldpen);
+ DeleteObject (oldpen);
}
}
unsigned char *p = output;
BYTE keystate[256];
int ret, code;
+ int cancel_alt = FALSE;
/*
- * Prepend ESC if ALT was pressed at the time.
+ * Get hold of the keyboard state, because we'll need it a few
+ * times shortly.
*/
- if (lParam & 0x20000000)
+ 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.
+ */
+ if (wParam == VK_MENU) {
+ if (lParam & 0x1000000) keystate[VK_RMENU] = 0x80;
+ else keystate[VK_LMENU] = 0x80;
+ SetKeyboardState (keystate);
+ return 0;
+ }
+ if (wParam == VK_CONTROL) {
+ if (lParam & 0x1000000) keystate[VK_RCONTROL] = 0x80;
+ else keystate[VK_LCONTROL] = 0x80;
+ SetKeyboardState (keystate);
+ return 0;
+ }
+
+ /*
+ * Prepend ESC, and cancel ALT, if ALT was pressed at the time
+ * and it wasn't AltGr.
+ */
+ if (lParam & 0x20000000 && (keystate[VK_LMENU] & 0x80)) {
*p++ = 0x1B;
+ cancel_alt = TRUE;
+ }
/*
- * Get hold of the keyboard state, because we'll need it a few
- * times shortly.
+ * NetHack keypad mode. This may conflict with Shift-PgUp/PgDn,
+ * so we do it first.
*/
- ret = GetKeyboardState(keystate);
+ 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
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
}
/*
- * Before doing Windows charmap translation, remove ALT from
- * the keymap, since its sole effect should be to prepend ESC,
- * which we've already done. Note that removal of ALT has to
- * happen _after_ the above call to SetKeyboardState, or dire
- * things will befall.
+ * Before doing Windows charmap translation, remove LeftALT
+ * from the keymap, since its sole effect should be to prepend
+ * ESC, which we've already done. Note that removal of LeftALT
+ * has to happen _after_ the above call to SetKeyboardState, or
+ * dire things will befall.
*/
- keystate[VK_MENU] = keystate[VK_LMENU] = keystate[VK_RMENU] = 0;
+ if (cancel_alt) {
+ keystate[VK_MENU] = keystate[VK_RMENU];
+ keystate[VK_LMENU] = 0;
+ }
/*
* Attempt the Windows char-map translation.
*/
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;
}
}
si.nMax = total - 1;
si.nPage = page;
si.nPos = start;
- SetScrollInfo (hwnd, SB_VERT, &si, TRUE);
+ if (hwnd)
+ SetScrollInfo (hwnd, SB_VERT, &si, TRUE);
}
-Context get_ctx() {
+Context get_ctx(void) {
HDC hdc;
if (hwnd) {
hdc = GetDC (hwnd);
*/
void optimised_move (int to, int from, int lines) {
RECT r;
- int min, max, d;
+ int min, max;
min = (to < from ? to : from);
max = to + from - min;
- d = max - min;
r.left = 0; r.right = cols * font_width;
r.top = min * font_height; r.bottom = (max+lines) * font_height;