mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
Added local-editing line discipline to make raw backend usable
[originally from svn r287]
This commit is contained in:
parent
b51c18f24c
commit
429b6f4a83
11
Makefile
11
Makefile
@ -13,7 +13,8 @@ CFLAGS = /nologo /W3 /YX /O2 /Yd /D_WINDOWS /DDEBUG /ML /Fd
|
||||
.c.obj:
|
||||
cl $(COMPAT) $(FWHACK) $(CFLAGS) /c $*.c
|
||||
|
||||
PUTTYOBJS = window.obj windlg.obj terminal.obj telnet.obj raw.obj xlat.obj
|
||||
POBJS1 = window.obj windlg.obj terminal.obj telnet.obj raw.obj
|
||||
POBJS2 = xlat.obj ldisc.obj
|
||||
OBJS1 = misc.obj noise.obj
|
||||
OBJS2 = ssh.obj sshcrc.obj sshdes.obj sshmd5.obj sshrsa.obj sshrand.obj
|
||||
OBJS3 = sshsha.obj sshblowf.obj version.obj sizetip.obj
|
||||
@ -26,15 +27,16 @@ SCPOBJS3 = sshrsa.obj sshrand.obj sshsha.obj sshblowf.obj version.obj
|
||||
|
||||
all: putty.exe pscp.exe
|
||||
|
||||
putty.exe: $(PUTTYOBJS) $(OBJS1) $(OBJS2) $(OBJS3) $(RESRC) link.rsp
|
||||
putty.exe: $(POBJS1) $(POBJS2) $(OBJS1) $(OBJS2) $(OBJS3) $(RESRC) link.rsp
|
||||
link /debug -out:putty.exe @link.rsp
|
||||
|
||||
puttyd.exe: $(PUTTYOBJS) $(OBJS1) $(OBJS2) $(OBJS3) $(RESRC) link.rsp
|
||||
puttyd.exe: $(POBJS1) $(POBJS2) $(OBJS1) $(OBJS2) $(OBJS3) $(RESRC) link.rsp
|
||||
link /debug -out:puttyd.exe @link.rsp
|
||||
|
||||
link.rsp: makefile
|
||||
echo /nologo /subsystem:windows > link.rsp
|
||||
echo $(PUTTYOBJS) >> link.rsp
|
||||
echo $(POBJS1) >> link.rsp
|
||||
echo $(POBJS2) >> link.rsp
|
||||
echo $(OBJS1) >> link.rsp
|
||||
echo $(OBJS2) >> link.rsp
|
||||
echo $(OBJS3) >> link.rsp
|
||||
@ -49,6 +51,7 @@ sizetip.obj: sizetip.c putty.h
|
||||
telnet.obj: telnet.c putty.h
|
||||
raw.obj: raw.c putty.h
|
||||
xlat.obj: xlat.c putty.h
|
||||
ldisc.obj: ldisc.c putty.h
|
||||
misc.obj: misc.c putty.h
|
||||
noise.obj: noise.c putty.h ssh.h
|
||||
ssh.obj: ssh.c ssh.h putty.h
|
||||
|
137
ldisc.c
Normal file
137
ldisc.c
Normal file
@ -0,0 +1,137 @@
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "putty.h"
|
||||
|
||||
/*
|
||||
* ldisc.c: PuTTY line disciplines
|
||||
*/
|
||||
|
||||
static void c_write (char *buf, int len) {
|
||||
while (len--) {
|
||||
int new_head = (inbuf_head + 1) & INBUF_MASK;
|
||||
int c = (unsigned char) *buf;
|
||||
if (new_head != inbuf_reap) {
|
||||
inbuf[inbuf_head] = *buf++;
|
||||
inbuf_head = new_head;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char *term_buf = NULL;
|
||||
static int term_buflen = 0, term_bufsiz = 0, term_quotenext = 0;
|
||||
|
||||
static int plen(unsigned char c) {
|
||||
if ((c >= 32 && c <= 126) ||
|
||||
(c >= 160))
|
||||
return 1;
|
||||
else if (c < 128)
|
||||
return 2; /* ^x for some x */
|
||||
else
|
||||
return 4; /* <XY> for hex XY */
|
||||
}
|
||||
|
||||
static void pwrite(unsigned char c) {
|
||||
if ((c >= 32 && c <= 126) ||
|
||||
(c >= 160)) {
|
||||
char cc = (char)c;
|
||||
c_write(&cc, 1);
|
||||
} else if (c < 128) {
|
||||
char cc[2];
|
||||
cc[1] = (c == 127 ? '?' : c + 0x40);
|
||||
cc[0] = '^';
|
||||
c_write(cc, 2);
|
||||
} else {
|
||||
char cc[5];
|
||||
sprintf(cc, "<%02X>", c);
|
||||
c_write(cc, 4);
|
||||
}
|
||||
}
|
||||
|
||||
static void bsb(int n) {
|
||||
while (n--)
|
||||
c_write("\010 \010", 3);
|
||||
}
|
||||
|
||||
static void term_send(char *buf, int len) {
|
||||
while (len--) {
|
||||
char c;
|
||||
c = *buf++;
|
||||
switch (term_quotenext ? ' ' : c) {
|
||||
/*
|
||||
* ^h/^?: delete one char and output one BSB
|
||||
* ^w: delete, and output BSBs, to return to last space/nonspace
|
||||
* boundary
|
||||
* ^u: delete, and output BSBs, to return to BOL
|
||||
* ^r: echo "^R\n" and redraw line
|
||||
* ^v: quote next char
|
||||
* ^d: if at BOL, end of file and close connection, else send line
|
||||
* and reset to BOL
|
||||
* ^m/^j: send line-plus-\r\n and reset to BOL
|
||||
*/
|
||||
case 8: case 127: /* backspace/delete */
|
||||
if (term_buflen > 0) {
|
||||
bsb(plen(term_buf[term_buflen-1]));
|
||||
term_buflen--;
|
||||
}
|
||||
break;
|
||||
case 23: /* ^W delete word */
|
||||
while (term_buflen > 0) {
|
||||
bsb(plen(term_buf[term_buflen-1]));
|
||||
term_buflen--;
|
||||
if (term_buflen > 0 &&
|
||||
isspace(term_buf[term_buflen-1]) &&
|
||||
!isspace(term_buf[term_buflen]))
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 21: /* ^U delete line */
|
||||
while (term_buflen > 0) {
|
||||
bsb(plen(term_buf[term_buflen-1]));
|
||||
term_buflen--;
|
||||
}
|
||||
break;
|
||||
case 18: /* ^R redraw line */
|
||||
c_write("^R\r\n", 4);
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < term_buflen; i++)
|
||||
pwrite(term_buf[i]);
|
||||
}
|
||||
break;
|
||||
case 22: /* ^V quote next char */
|
||||
term_quotenext = TRUE;
|
||||
break;
|
||||
case 4: /* ^D logout or send */
|
||||
if (term_buflen == 0) {
|
||||
/* FIXME: eof */;
|
||||
} else {
|
||||
back->send(term_buf, term_buflen);
|
||||
term_buflen = 0;
|
||||
}
|
||||
break;
|
||||
case 13: case 10: /* ^M/^J send with newline */
|
||||
back->send(term_buf, term_buflen);
|
||||
back->send("\r\n", 2);
|
||||
c_write("\r\n", 2);
|
||||
term_buflen = 0;
|
||||
break;
|
||||
default: /* get to this label from ^V handler */
|
||||
if (term_buflen >= term_bufsiz) {
|
||||
term_bufsiz = term_buflen + 256;
|
||||
term_buf = saferealloc(term_buf, term_bufsiz);
|
||||
}
|
||||
term_buf[term_buflen++] = c;
|
||||
pwrite(c);
|
||||
term_quotenext = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void simple_send(char *buf, int len) {
|
||||
back->send(buf, len);
|
||||
}
|
||||
|
||||
Ldisc ldisc_term = { term_send };
|
||||
Ldisc ldisc_simple = { simple_send };
|
13
putty.h
13
putty.h
@ -91,6 +91,12 @@ typedef struct {
|
||||
|
||||
GLOBAL Backend *back;
|
||||
|
||||
typedef struct {
|
||||
void (*send) (char *buf, int len);
|
||||
} Ldisc;
|
||||
|
||||
GLOBAL Ldisc *ldisc;
|
||||
|
||||
typedef struct {
|
||||
/* Basic options */
|
||||
char host[512];
|
||||
@ -117,6 +123,7 @@ typedef struct {
|
||||
int nethack_keypad;
|
||||
int alt_f4; /* is it special? */
|
||||
int alt_space; /* is it special? */
|
||||
int ldisc_term;
|
||||
/* Terminal options */
|
||||
int savelines;
|
||||
int dec_om;
|
||||
@ -232,6 +239,12 @@ extern Backend telnet_backend;
|
||||
|
||||
extern Backend ssh_backend;
|
||||
|
||||
/*
|
||||
* Exports from ldisc.c.
|
||||
*/
|
||||
|
||||
extern Ldisc ldisc_term, ldisc_simple;
|
||||
|
||||
/*
|
||||
* Exports from sshrand.c.
|
||||
*/
|
||||
|
14
terminal.c
14
terminal.c
@ -577,7 +577,7 @@ void term_out(void) {
|
||||
do_toplevel:
|
||||
switch (c) {
|
||||
case '\005': /* terminal type query */
|
||||
back->send ("\033[?1;2c", 7);
|
||||
ldisc->send ("\033[?1;2c", 7);
|
||||
break;
|
||||
case '\007':
|
||||
beep();
|
||||
@ -766,7 +766,7 @@ void term_out(void) {
|
||||
must_update = TRUE;
|
||||
break;
|
||||
case 'Z': /* terminal type query */
|
||||
back->send ("\033[?6c", 5);
|
||||
ldisc->send ("\033[?6c", 5);
|
||||
break;
|
||||
case 'c': /* restore power-on settings */
|
||||
power_on();
|
||||
@ -902,13 +902,13 @@ void term_out(void) {
|
||||
must_update = TRUE;
|
||||
break;
|
||||
case 'c': /* terminal type query */
|
||||
back->send ("\033[?6c", 5);
|
||||
ldisc->send ("\033[?6c", 5);
|
||||
break;
|
||||
case 'n': /* cursor position query */
|
||||
if (esc_args[0] == 6) {
|
||||
char buf[32];
|
||||
sprintf (buf, "\033[%d;%dR", curs_y + 1, curs_x + 1);
|
||||
back->send (buf, strlen(buf));
|
||||
ldisc->send (buf, strlen(buf));
|
||||
}
|
||||
break;
|
||||
case 'h': /* toggle a mode to high */
|
||||
@ -1031,7 +1031,7 @@ void term_out(void) {
|
||||
if (i == 0 || i == 1) {
|
||||
strcpy (buf, "\033[2;1;1;112;112;1;0x");
|
||||
buf[2] += i;
|
||||
back->send (buf, 20);
|
||||
ldisc->send (buf, 20);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1443,13 +1443,13 @@ void term_mouse (Mouse_Button b, Mouse_Action a, int x, int y) {
|
||||
for(i=0;i<p-q;i++)
|
||||
{
|
||||
c=xlat_kbd2tty(q[i]);
|
||||
back->send(&c,1);
|
||||
ldisc->send(&c,1);
|
||||
}
|
||||
}
|
||||
|
||||
if (p <= data+len-sizeof(sel_nl) &&
|
||||
!memcmp(p, sel_nl, sizeof(sel_nl))) {
|
||||
back->send ("\r", 1);
|
||||
ldisc->send ("\r", 1);
|
||||
p += sizeof(sel_nl);
|
||||
}
|
||||
q = p;
|
||||
|
@ -63,6 +63,7 @@
|
||||
#define IDC1_CURAPPLIC 1016
|
||||
#define IDC1_ALTF4 1017
|
||||
#define IDC1_ALTSPACE 1018
|
||||
#define IDC1_LDISCTERM 1019
|
||||
|
||||
#define IDC2_WRAPMODE 1001
|
||||
#define IDC2_DECOM 1002
|
||||
|
@ -105,6 +105,8 @@ BEGIN
|
||||
IDC1_ALTF4, 3, 113, 162, 10
|
||||
AUTOCHECKBOX "ALT-Space is special (S&ystem menu)",
|
||||
IDC1_ALTSPACE, 3, 123, 162, 10
|
||||
AUTOCHECKBOX "&Use local terminal line discipline",
|
||||
IDC1_LDISCTERM, 3, 133, 162, 10
|
||||
END
|
||||
|
||||
IDD_PANEL2 DIALOG DISCARDABLE 6, 30, 168, 163
|
||||
|
8
windlg.c
8
windlg.c
@ -157,6 +157,7 @@ static void save_settings (char *section, int do_host) {
|
||||
wppi (sesskey, "NetHackKeypad", cfg.nethack_keypad);
|
||||
wppi (sesskey, "AltF4", cfg.alt_f4);
|
||||
wppi (sesskey, "AltSpace", cfg.alt_space);
|
||||
wppi (sesskey, "LdiscTerm", cfg.ldisc_term);
|
||||
wppi (sesskey, "ScrollbackLines", cfg.savelines);
|
||||
wppi (sesskey, "DECOriginMode", cfg.dec_om);
|
||||
wppi (sesskey, "AutoWrapMode", cfg.wrap_mode);
|
||||
@ -290,6 +291,7 @@ static void load_settings (char *section, int do_host) {
|
||||
gppi (sesskey, "NetHackKeypad", 0, &cfg.nethack_keypad);
|
||||
gppi (sesskey, "AltF4", 1, &cfg.alt_f4);
|
||||
gppi (sesskey, "AltSpace", 0, &cfg.alt_space);
|
||||
gppi (sesskey, "LdiscTerm", 0, &cfg.ldisc_term);
|
||||
gppi (sesskey, "ScrollbackLines", 200, &cfg.savelines);
|
||||
gppi (sesskey, "DECOriginMode", 0, &cfg.dec_om);
|
||||
gppi (sesskey, "AutoWrapMode", 1, &cfg.wrap_mode);
|
||||
@ -636,6 +638,7 @@ static int CALLBACK KeyboardProc (HWND hwnd, UINT msg,
|
||||
cfg.app_keypad ? IDC1_KPAPPLIC : IDC1_KPNORMAL);
|
||||
CheckDlgButton (hwnd, IDC1_ALTF4, cfg.alt_f4);
|
||||
CheckDlgButton (hwnd, IDC1_ALTSPACE, cfg.alt_space);
|
||||
CheckDlgButton (hwnd, IDC1_LDISCTERM, cfg.ldisc_term);
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
if (HIWORD(wParam) == BN_CLICKED ||
|
||||
@ -676,6 +679,11 @@ static int CALLBACK KeyboardProc (HWND hwnd, UINT msg,
|
||||
HIWORD(wParam) == BN_DOUBLECLICKED)
|
||||
cfg.alt_space = IsDlgButtonChecked (hwnd, IDC1_ALTSPACE);
|
||||
break;
|
||||
case IDC1_LDISCTERM:
|
||||
if (HIWORD(wParam) == BN_CLICKED ||
|
||||
HIWORD(wParam) == BN_DOUBLECLICKED)
|
||||
cfg.ldisc_term = IsDlgButtonChecked (hwnd, IDC1_LDISCTERM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return GeneralPanelProc (hwnd, msg, wParam, lParam);
|
||||
|
9
window.c
9
window.c
@ -181,7 +181,10 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) {
|
||||
}
|
||||
|
||||
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;
|
||||
@ -1016,7 +1019,7 @@ static int WINAPI WndProc (HWND hwnd, UINT message,
|
||||
len = TranslateKey (wParam, lParam, buf);
|
||||
if (len == -1)
|
||||
return DefWindowProc (hwnd, message, wParam, lParam);
|
||||
back->send (buf, len);
|
||||
ldisc->send (buf, len);
|
||||
}
|
||||
return 0;
|
||||
case WM_KEYUP:
|
||||
@ -1056,7 +1059,7 @@ static int WINAPI WndProc (HWND hwnd, UINT message,
|
||||
*/
|
||||
{
|
||||
char c = xlat_kbd2tty((unsigned char)wParam);
|
||||
back->send (&c, 1);
|
||||
ldisc->send (&c, 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user