1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-07-05 21:42:47 -05:00

Turn Backend into a sensible classoid.

Nearly every part of the code that ever handles a full backend
structure has historically done it using a pair of pointer variables,
one pointing at a constant struct full of function pointers, and the
other pointing to a 'void *' state object that's passed to each of
those.

While I'm modernising the rest of the code, this seems like a good
time to turn that into the same more or less type-safe and less
cumbersome system as I'm using for other parts of the code, such as
Socket, Plug, BinaryPacketProtocol and so forth: the Backend structure
contains a vtable pointer, and a system of macro wrappers handles
dispatching through that vtable.
This commit is contained in:
Simon Tatham
2018-09-11 16:23:38 +01:00
parent c51fe7c217
commit eefebaaa9e
36 changed files with 633 additions and 611 deletions

55
ldisc.c
View File

@ -15,11 +15,11 @@
#define ECHOING (ldisc->localecho == FORCE_ON || \
(ldisc->localecho == AUTO && \
(ldisc->back->ldisc(ldisc->backhandle, LD_ECHO) || \
(backend_ldisc_option_state(ldisc->backend, LD_ECHO) || \
term_ldisc(ldisc->term, LD_ECHO))))
#define EDITING (ldisc->localedit == FORCE_ON || \
(ldisc->localedit == AUTO && \
(ldisc->back->ldisc(ldisc->backhandle, LD_EDIT) || \
(backend_ldisc_option_state(ldisc->backend, LD_EDIT) || \
term_ldisc(ldisc->term, LD_EDIT))))
static void c_write(Ldisc *ldisc, const void *buf, int len)
@ -78,8 +78,7 @@ static void bsb(Ldisc *ldisc, int n)
#define KCTRL(x) ((x^'@') | 0x100)
Ldisc *ldisc_create(Conf *conf, Terminal *term,
Backend *back, void *backhandle,
void *frontend)
Backend *backend, void *frontend)
{
Ldisc *ldisc = snew(Ldisc);
@ -88,8 +87,7 @@ Ldisc *ldisc_create(Conf *conf, Terminal *term,
ldisc->bufsiz = 0;
ldisc->quotenext = 0;
ldisc->back = back;
ldisc->backhandle = backhandle;
ldisc->backend = backend;
ldisc->term = term;
ldisc->frontend = frontend;
@ -98,8 +96,8 @@ Ldisc *ldisc_create(Conf *conf, Terminal *term,
/* Link ourselves into the backend and the terminal */
if (term)
term->ldisc = ldisc;
if (back)
back->provide_ldisc(backhandle, ldisc);
if (backend)
backend_provide_ldisc(backend, ldisc);
return ldisc;
}
@ -117,8 +115,8 @@ void ldisc_free(Ldisc *ldisc)
{
if (ldisc->term)
ldisc->term->ldisc = NULL;
if (ldisc->back)
ldisc->back->provide_ldisc(ldisc->backhandle, NULL);
if (ldisc->backend)
backend_provide_ldisc(ldisc->backend, NULL);
if (ldisc->buf)
sfree(ldisc->buf);
sfree(ldisc);
@ -219,7 +217,7 @@ void ldisc_send(Ldisc *ldisc, const void *vbuf, int len, int interactive)
bsb(ldisc, plen(ldisc, ldisc->buf[ldisc->buflen - 1]));
ldisc->buflen--;
}
ldisc->back->special(ldisc->backhandle, TS_EL);
backend_special(ldisc->backend, TS_EL);
/*
* We don't send IP, SUSP or ABORT if the user has
* configured telnet specials off! This breaks
@ -228,11 +226,11 @@ void ldisc_send(Ldisc *ldisc, const void *vbuf, int len, int interactive)
if (!ldisc->telnet_keyboard)
goto default_case;
if (c == CTRL('C'))
ldisc->back->special(ldisc->backhandle, TS_IP);
backend_special(ldisc->backend, TS_IP);
if (c == CTRL('Z'))
ldisc->back->special(ldisc->backhandle, TS_SUSP);
backend_special(ldisc->backend, TS_SUSP);
if (c == CTRL('\\'))
ldisc->back->special(ldisc->backhandle, TS_ABORT);
backend_special(ldisc->backend, TS_ABORT);
break;
case CTRL('R'): /* redraw line */
if (ECHOING) {
@ -247,9 +245,9 @@ void ldisc_send(Ldisc *ldisc, const void *vbuf, int len, int interactive)
break;
case CTRL('D'): /* logout or send */
if (ldisc->buflen == 0) {
ldisc->back->special(ldisc->backhandle, TS_EOF);
backend_special(ldisc->backend, TS_EOF);
} else {
ldisc->back->send(ldisc->backhandle, ldisc->buf, ldisc->buflen);
backend_send(ldisc->backend, ldisc->buf, ldisc->buflen);
ldisc->buflen = 0;
}
break;
@ -285,13 +283,14 @@ void ldisc_send(Ldisc *ldisc, const void *vbuf, int len, int interactive)
/* FALLTHROUGH */
case KCTRL('M'): /* send with newline */
if (ldisc->buflen > 0)
ldisc->back->send(ldisc->backhandle, ldisc->buf, ldisc->buflen);
backend_send(ldisc->backend,
ldisc->buf, ldisc->buflen);
if (ldisc->protocol == PROT_RAW)
ldisc->back->send(ldisc->backhandle, "\r\n", 2);
backend_send(ldisc->backend, "\r\n", 2);
else if (ldisc->protocol == PROT_TELNET && ldisc->telnet_newline)
ldisc->back->special(ldisc->backhandle, TS_EOL);
backend_special(ldisc->backend, TS_EOL);
else
ldisc->back->send(ldisc->backhandle, "\r", 1);
backend_send(ldisc->backend, "\r", 1);
if (ECHOING)
c_write(ldisc, "\r\n", 2);
ldisc->buflen = 0;
@ -313,7 +312,7 @@ void ldisc_send(Ldisc *ldisc, const void *vbuf, int len, int interactive)
}
} else {
if (ldisc->buflen != 0) {
ldisc->back->send(ldisc->backhandle, ldisc->buf, ldisc->buflen);
backend_send(ldisc->backend, ldisc->buf, ldisc->buflen);
while (ldisc->buflen > 0) {
bsb(ldisc, plen(ldisc, ldisc->buf[ldisc->buflen - 1]));
ldisc->buflen--;
@ -326,33 +325,33 @@ void ldisc_send(Ldisc *ldisc, const void *vbuf, int len, int interactive)
switch (buf[0]) {
case CTRL('M'):
if (ldisc->protocol == PROT_TELNET && ldisc->telnet_newline)
ldisc->back->special(ldisc->backhandle, TS_EOL);
backend_special(ldisc->backend, TS_EOL);
else
ldisc->back->send(ldisc->backhandle, "\r", 1);
backend_send(ldisc->backend, "\r", 1);
break;
case CTRL('?'):
case CTRL('H'):
if (ldisc->telnet_keyboard) {
ldisc->back->special(ldisc->backhandle, TS_EC);
backend_special(ldisc->backend, TS_EC);
break;
}
case CTRL('C'):
if (ldisc->telnet_keyboard) {
ldisc->back->special(ldisc->backhandle, TS_IP);
backend_special(ldisc->backend, TS_IP);
break;
}
case CTRL('Z'):
if (ldisc->telnet_keyboard) {
ldisc->back->special(ldisc->backhandle, TS_SUSP);
backend_special(ldisc->backend, TS_SUSP);
break;
}
default:
ldisc->back->send(ldisc->backhandle, buf, len);
backend_send(ldisc->backend, buf, len);
break;
}
} else
ldisc->back->send(ldisc->backhandle, buf, len);
backend_send(ldisc->backend, buf, len);
}
}
}