1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

Line discipline module now uses dynamically allocated data. Also

fixed one or two other minor problems.

[originally from svn r2141]
This commit is contained in:
Simon Tatham 2002-10-26 10:16:19 +00:00
parent ba0468b983
commit 0b2523eeda
16 changed files with 326 additions and 204 deletions

View File

@ -304,7 +304,7 @@ int console_get_line(const char *prompt, char *str,
return 1;
}
void frontend_keypress(void)
void frontend_keypress(void *handle)
{
/*
* This is nothing but a stub, in console code.

185
ldisc.c
View File

@ -11,26 +11,33 @@
#include "putty.h"
#include "terminal.h"
typedef struct ldisc_tag {
Terminal *term;
Backend *back;
void *backhandle;
void *frontend;
char *buf;
int buflen, bufsiz, quotenext;
} *Ldisc;
#define ECHOING (cfg.localecho == LD_YES || \
(cfg.localecho == LD_BACKEND && \
(back->ldisc(backhandle, LD_ECHO) || \
term_ldisc(term, LD_ECHO))))
(ldisc->back->ldisc(ldisc->backhandle, LD_ECHO) || \
term_ldisc(ldisc->term, LD_ECHO))))
#define EDITING (cfg.localedit == LD_YES || \
(cfg.localedit == LD_BACKEND && \
(back->ldisc(backhandle, LD_EDIT) || \
term_ldisc(term, LD_EDIT))))
(ldisc->back->ldisc(ldisc->backhandle, LD_EDIT) || \
term_ldisc(ldisc->term, LD_EDIT))))
static void c_write(char *buf, int len)
static void c_write(Ldisc ldisc, char *buf, int len)
{
from_backend(term, 0, buf, len);
from_backend(ldisc->term, 0, buf, len);
}
static char *term_buf = NULL;
static int term_buflen = 0, term_bufsiz = 0, term_quotenext = 0;
static int plen(unsigned char c)
static int plen(Ldisc ldisc, unsigned char c)
{
if ((c >= 32 && c <= 126) || (c >= 160 && !in_utf(term)))
if ((c >= 32 && c <= 126) || (c >= 160 && !in_utf(ldisc->term)))
return 1;
else if (c < 128)
return 2; /* ^x for some x */
@ -38,41 +45,66 @@ static int plen(unsigned char c)
return 4; /* <XY> for hex XY */
}
static void pwrite(unsigned char c)
static void pwrite(Ldisc ldisc, unsigned char c)
{
if ((c >= 32 && c <= 126) || (c >= 160 && !in_utf(term))) {
c_write(&c, 1);
if ((c >= 32 && c <= 126) || (c >= 160 && !in_utf(ldisc->term))) {
c_write(ldisc, &c, 1);
} else if (c < 128) {
char cc[2];
cc[1] = (c == 127 ? '?' : c + 0x40);
cc[0] = '^';
c_write(cc, 2);
c_write(ldisc, cc, 2);
} else {
char cc[5];
sprintf(cc, "<%02X>", c);
c_write(cc, 4);
c_write(ldisc, cc, 4);
}
}
static void bsb(int n)
static void bsb(Ldisc ldisc, int n)
{
while (n--)
c_write("\010 \010", 3);
c_write(ldisc, "\010 \010", 3);
}
#define CTRL(x) (x^'@')
#define KCTRL(x) ((x^'@') | 0x100)
void ldisc_send(char *buf, int len, int interactive)
void *ldisc_create(Terminal *term,
Backend *back, void *backhandle,
void *frontend)
{
Ldisc ldisc = smalloc(sizeof(*ldisc));
ldisc->buf = NULL;
ldisc->buflen = 0;
ldisc->bufsiz = 0;
ldisc->quotenext = 0;
ldisc->back = back;
ldisc->backhandle = backhandle;
ldisc->term = term;
ldisc->frontend = frontend;
/* Link ourselves into the backend and the terminal */
if (term)
term->ldisc = ldisc;
if (back)
back->provide_ldisc(backhandle, ldisc);
return ldisc;
}
void ldisc_send(void *handle, char *buf, int len, int interactive)
{
Ldisc ldisc = (Ldisc) handle;
int keyflag = 0;
/*
* Called with len=0 when the options change. We must inform
* the front end in case it needs to know.
*/
if (len == 0) {
void ldisc_update(int echo, int edit);
ldisc_update(ECHOING, EDITING);
ldisc_update(ldisc->frontend, ECHOING, EDITING);
return;
}
/*
@ -80,7 +112,8 @@ void ldisc_send(char *buf, int len, int interactive)
* it's depending on finding out (e.g. keypress termination for
* Close On Exit).
*/
frontend_keypress();
frontend_keypress(ldisc->frontend);
/*
* Less than zero means null terminated special string.
*/
@ -97,7 +130,7 @@ void ldisc_send(char *buf, int len, int interactive)
c = *buf++ + keyflag;
if (!interactive && c == '\r')
c += KCTRL('@');
switch (term_quotenext ? ' ' : c) {
switch (ldisc->quotenext ? ' ' : c) {
/*
* ^h/^?: delete one char and output one BSB
* ^w: delete, and output BSBs, to return to last
@ -114,20 +147,20 @@ void ldisc_send(char *buf, int len, int interactive)
*/
case KCTRL('H'):
case KCTRL('?'): /* backspace/delete */
if (term_buflen > 0) {
if (ldisc->buflen > 0) {
if (ECHOING)
bsb(plen(term_buf[term_buflen - 1]));
term_buflen--;
bsb(ldisc, plen(ldisc, ldisc->buf[ldisc->buflen - 1]));
ldisc->buflen--;
}
break;
case CTRL('W'): /* delete word */
while (term_buflen > 0) {
while (ldisc->buflen > 0) {
if (ECHOING)
bsb(plen(term_buf[term_buflen - 1]));
term_buflen--;
if (term_buflen > 0 &&
isspace(term_buf[term_buflen - 1]) &&
!isspace(term_buf[term_buflen]))
bsb(ldisc, plen(ldisc, ldisc->buf[ldisc->buflen - 1]));
ldisc->buflen--;
if (ldisc->buflen > 0 &&
isspace(ldisc->buf[ldisc->buflen - 1]) &&
!isspace(ldisc->buf[ldisc->buflen]))
break;
}
break;
@ -135,12 +168,12 @@ void ldisc_send(char *buf, int len, int interactive)
case CTRL('C'): /* Send IP */
case CTRL('\\'): /* Quit */
case CTRL('Z'): /* Suspend */
while (term_buflen > 0) {
while (ldisc->buflen > 0) {
if (ECHOING)
bsb(plen(term_buf[term_buflen - 1]));
term_buflen--;
bsb(ldisc, plen(ldisc, ldisc->buf[ldisc->buflen - 1]));
ldisc->buflen--;
}
back->special(backhandle, TS_EL);
ldisc->back->special(ldisc->backhandle, TS_EL);
/*
* We don't send IP, SUSP or ABORT if the user has
* configured telnet specials off! This breaks
@ -149,29 +182,29 @@ void ldisc_send(char *buf, int len, int interactive)
if (!cfg.telnet_keyboard)
goto default_case;
if (c == CTRL('C'))
back->special(backhandle, TS_IP);
ldisc->back->special(ldisc->backhandle, TS_IP);
if (c == CTRL('Z'))
back->special(backhandle, TS_SUSP);
ldisc->back->special(ldisc->backhandle, TS_SUSP);
if (c == CTRL('\\'))
back->special(backhandle, TS_ABORT);
ldisc->back->special(ldisc->backhandle, TS_ABORT);
break;
case CTRL('R'): /* redraw line */
if (ECHOING) {
int i;
c_write("^R\r\n", 4);
for (i = 0; i < term_buflen; i++)
pwrite(term_buf[i]);
c_write(ldisc, "^R\r\n", 4);
for (i = 0; i < ldisc->buflen; i++)
pwrite(ldisc, ldisc->buf[i]);
}
break;
case CTRL('V'): /* quote next char */
term_quotenext = TRUE;
ldisc->quotenext = TRUE;
break;
case CTRL('D'): /* logout or send */
if (term_buflen == 0) {
back->special(backhandle, TS_EOF);
if (ldisc->buflen == 0) {
ldisc->back->special(ldisc->backhandle, TS_EOF);
} else {
back->send(backhandle, term_buf, term_buflen);
term_buflen = 0;
ldisc->back->send(ldisc->backhandle, ldisc->buf, ldisc->buflen);
ldisc->buflen = 0;
}
break;
/*
@ -199,81 +232,81 @@ void ldisc_send(char *buf, int len, int interactive)
*/
case CTRL('J'):
if (cfg.protocol == PROT_RAW &&
term_buflen > 0 && term_buf[term_buflen - 1] == '\r') {
ldisc->buflen > 0 && ldisc->buf[ldisc->buflen - 1] == '\r') {
if (ECHOING)
bsb(plen(term_buf[term_buflen - 1]));
term_buflen--;
bsb(ldisc, plen(ldisc, ldisc->buf[ldisc->buflen - 1]));
ldisc->buflen--;
/* FALLTHROUGH */
case KCTRL('M'): /* send with newline */
if (term_buflen > 0)
back->send(backhandle, term_buf, term_buflen);
if (ldisc->buflen > 0)
ldisc->back->send(ldisc->backhandle, ldisc->buf, ldisc->buflen);
if (cfg.protocol == PROT_RAW)
back->send(backhandle, "\r\n", 2);
ldisc->back->send(ldisc->backhandle, "\r\n", 2);
else if (cfg.protocol == PROT_TELNET && cfg.telnet_newline)
back->special(backhandle, TS_EOL);
ldisc->back->special(ldisc->backhandle, TS_EOL);
else
back->send(backhandle, "\r", 1);
ldisc->back->send(ldisc->backhandle, "\r", 1);
if (ECHOING)
c_write("\r\n", 2);
term_buflen = 0;
c_write(ldisc, "\r\n", 2);
ldisc->buflen = 0;
break;
}
/* FALLTHROUGH */
default: /* get to this label from ^V handler */
default_case:
if (term_buflen >= term_bufsiz) {
term_bufsiz = term_buflen + 256;
term_buf = saferealloc(term_buf, term_bufsiz);
if (ldisc->buflen >= ldisc->bufsiz) {
ldisc->bufsiz = ldisc->buflen + 256;
ldisc->buf = srealloc(ldisc->buf, ldisc->bufsiz);
}
term_buf[term_buflen++] = c;
ldisc->buf[ldisc->buflen++] = c;
if (ECHOING)
pwrite((unsigned char) c);
term_quotenext = FALSE;
pwrite(ldisc, (unsigned char) c);
ldisc->quotenext = FALSE;
break;
}
}
} else {
if (term_buflen != 0) {
back->send(backhandle, term_buf, term_buflen);
while (term_buflen > 0) {
bsb(plen(term_buf[term_buflen - 1]));
term_buflen--;
if (ldisc->buflen != 0) {
ldisc->back->send(ldisc->backhandle, ldisc->buf, ldisc->buflen);
while (ldisc->buflen > 0) {
bsb(ldisc, plen(ldisc, ldisc->buf[ldisc->buflen - 1]));
ldisc->buflen--;
}
}
if (len > 0) {
if (ECHOING)
c_write(buf, len);
c_write(ldisc, buf, len);
if (keyflag && cfg.protocol == PROT_TELNET && len == 1) {
switch (buf[0]) {
case CTRL('M'):
if (cfg.protocol == PROT_TELNET && cfg.telnet_newline)
back->special(backhandle, TS_EOL);
ldisc->back->special(ldisc->backhandle, TS_EOL);
else
back->send(backhandle, "\r", 1);
ldisc->back->send(ldisc->backhandle, "\r", 1);
break;
case CTRL('?'):
case CTRL('H'):
if (cfg.telnet_keyboard) {
back->special(backhandle, TS_EC);
ldisc->back->special(ldisc->backhandle, TS_EC);
break;
}
case CTRL('C'):
if (cfg.telnet_keyboard) {
back->special(backhandle, TS_IP);
ldisc->back->special(ldisc->backhandle, TS_IP);
break;
}
case CTRL('Z'):
if (cfg.telnet_keyboard) {
back->special(backhandle, TS_SUSP);
ldisc->back->special(ldisc->backhandle, TS_SUSP);
break;
}
default:
back->send(backhandle, buf, len);
ldisc->back->send(ldisc->backhandle, buf, len);
break;
}
} else
back->send(backhandle, buf, len);
ldisc->back->send(ldisc->backhandle, buf, len);
}
}
}

View File

@ -73,7 +73,7 @@ int term_ldisc(Terminal *term, int mode)
{
return FALSE;
}
void ldisc_update(int echo, int edit)
void ldisc_update(void *frontend, int echo, int edit)
{
/* Update stdin read mode to reflect changes in line discipline. */
DWORD mode;

11
putty.h
View File

@ -200,6 +200,7 @@ struct backend_tag {
int (*exitcode) (void *handle);
int (*sendok) (void *handle);
int (*ldisc) (void *handle, int);
void (*provide_ldisc) (void *handle, void *ldisc);
/*
* back->unthrottle() tells the back end that the front end
* buffer is clearing.
@ -430,7 +431,8 @@ void beep(int);
void begin_session(void);
void sys_cursor(int x, int y);
void request_paste(void);
void frontend_keypress(void);
void frontend_keypress(void *frontend);
void ldisc_update(void *frontend, int echo, int edit);
#define OPTIMISE_IS_SCROLL 1
void set_iconic(int iconic);
@ -536,7 +538,8 @@ extern Backend ssh_backend;
* Exports from ldisc.c.
*/
extern void ldisc_send(char *buf, int len, int interactive);
void *ldisc_create(Terminal *, Backend *, void *, void *);
void ldisc_send(void *handle, char *buf, int len, int interactive);
/*
* Exports from sshrand.c.
@ -566,8 +569,8 @@ extern char ver[];
#define CP_UTF8 65001
#endif
void init_ucs_tables(void);
void lpage_send(int codepage, char *buf, int len, int interactive);
void luni_send(wchar_t * widebuf, int len, int interactive);
void lpage_send(void *, int codepage, char *buf, int len, int interactive);
void luni_send(void *, wchar_t * widebuf, int len, int interactive);
wchar_t xlat_uskbd2cyrllic(int ch);
int check_compose(int first, int second);
int decode_codepage(char *cp_name);

6
raw.c
View File

@ -186,6 +186,11 @@ static int raw_ldisc(void *handle, int option)
return 0;
}
static void raw_provide_ldisc(void *handle, void *ldisc)
{
/* This is a stub. */
}
static int raw_exitcode(void *handle)
{
/* Exit codes are a meaningless concept in the Raw protocol */
@ -202,6 +207,7 @@ Backend raw_backend = {
raw_exitcode,
raw_sendok,
raw_ldisc,
raw_provide_ldisc,
raw_unthrottle,
1
};

View File

@ -250,6 +250,11 @@ static int rlogin_ldisc(void *handle, int option)
return 0;
}
static void rlogin_provide_ldisc(void *handle, void *ldisc)
{
/* This is a stub. */
}
static int rlogin_exitcode(void *handle)
{
Rlogin rlogin = (Rlogin) handle;
@ -267,6 +272,7 @@ Backend rlogin_backend = {
rlogin_exitcode,
rlogin_sendok,
rlogin_ldisc,
rlogin_provide_ldisc,
rlogin_unthrottle,
1
};

16
ssh.c
View File

@ -555,6 +555,8 @@ struct ssh_tag {
Socket s;
void *ldisc;
unsigned char session_key[32];
int v1_compressing;
int v1_remote_protoflags;
@ -3233,7 +3235,8 @@ static void ssh1_protocol(Ssh ssh, unsigned char *in, int inlen, int ispkt)
if (ssh->eof_needed)
ssh_special(ssh, TS_EOF);
ldisc_send(NULL, 0, 0); /* cause ldisc to notice changes */
if (ssh->ldisc)
ldisc_send(ssh->ldisc, NULL, 0, 0);/* cause ldisc to notice changes */
ssh->send_ok = 1;
ssh->channels = newtree234(ssh_channelcmp);
while (1) {
@ -5379,7 +5382,8 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
/*
* Transfer data!
*/
ldisc_send(NULL, 0, 0); /* cause ldisc to notice changes */
if (ssh->ldisc)
ldisc_send(ssh->ldisc, NULL, 0, 0);/* cause ldisc to notice changes */
ssh->send_ok = 1;
while (1) {
crReturnV;
@ -5854,6 +5858,7 @@ static char *ssh_init(void *frontend_handle, void **backend_handle,
ssh->state = SSH_STATE_PREPACKET;
ssh->size_needed = FALSE;
ssh->eof_needed = FALSE;
ssh->ldisc = NULL;
{
static const struct Packet empty = { 0, 0, NULL, NULL, 0 };
ssh->pktin = ssh->pktout = empty;
@ -6133,6 +6138,12 @@ static int ssh_ldisc(void *handle, int option)
return FALSE;
}
static void ssh_provide_ldisc(void *handle, void *ldisc)
{
Ssh ssh = (Ssh) handle;
ssh->ldisc = ldisc;
}
static int ssh_return_exitcode(void *handle)
{
Ssh ssh = (Ssh) handle;
@ -6160,6 +6171,7 @@ Backend ssh_backend = {
ssh_return_exitcode,
ssh_sendok,
ssh_ldisc,
ssh_provide_ldisc,
ssh_unthrottle,
22
};

View File

@ -192,6 +192,7 @@ typedef struct telnet_tag {
Socket s;
void *frontend;
void *ldisc;
int term_width, term_height;
int opt_states[NUM_OPTS];
@ -261,7 +262,8 @@ static void option_side_effects(Telnet telnet, const struct Opt *o, int enabled)
telnet->echoing = !enabled;
else if (o->option == TELOPT_SGA && o->send == DO)
telnet->editing = !enabled;
ldisc_send(NULL, 0, 0); /* cause ldisc to notice the change */
if (telnet->ldisc) /* cause ldisc to notice the change */
ldisc_send(telnet->ldisc, NULL, 0, 0);
/* Ensure we get the minimum options */
if (!telnet->activated) {
@ -908,6 +910,12 @@ static int telnet_ldisc(void *handle, int option)
return FALSE;
}
static void telnet_provide_ldisc(void *handle, void *ldisc)
{
Telnet telnet = (Telnet) handle;
telnet->ldisc = ldisc;
}
static int telnet_exitcode(void *handle)
{
Telnet telnet = (Telnet) handle;
@ -925,6 +933,7 @@ Backend telnet_backend = {
telnet_exitcode,
telnet_sendok,
telnet_ldisc,
telnet_provide_ldisc,
telnet_unthrottle,
23
};

View File

@ -241,7 +241,8 @@ void term_seen_key_event(Terminal *term)
void term_pwron(Terminal *term)
{
power_on(term);
ldisc_send(NULL, 0, 0); /* cause ldisc to notice changes */
if (term->ldisc) /* cause ldisc to notice changes */
ldisc_send(term->ldisc, NULL, 0, 0);
fix_cpos;
term->disptop = 0;
deselect(term);
@ -309,7 +310,7 @@ Terminal *term_init(void)
term->vt52_mode = FALSE;
term->cr_lf_return = FALSE;
term->seen_disp_event = FALSE;
term->xterm_mouse = FALSE;
term->xterm_mouse = term->mouse_is_down = FALSE;
term->reset_132 = FALSE;
term->blinker = term->tblinker = 0;
term->has_focus = 1;
@ -915,7 +916,8 @@ static void toggle_mode(Terminal *term, int mode, int query, int state)
break;
case 10: /* set local edit mode */
term->term_editing = state;
ldisc_send(NULL, 0, 0); /* cause ldisc to notice changes */
if (term->ldisc) /* cause ldisc to notice changes */
ldisc_send(term->ldisc, NULL, 0, 0);
break;
case 25: /* enable/disable cursor */
compatibility2(OTHER, VT220);
@ -965,7 +967,8 @@ static void toggle_mode(Terminal *term, int mode, int query, int state)
break;
case 12: /* set echo mode */
term->term_echoing = !state;
ldisc_send(NULL, 0, 0); /* cause ldisc to notice changes */
if (term->ldisc) /* cause ldisc to notice changes */
ldisc_send(term->ldisc, NULL, 0, 0);
break;
case 20: /* Return sends ... */
term->cr_lf_return = state;
@ -1288,7 +1291,7 @@ void term_out(Terminal *term)
* An xterm returns "xterm" (5 characters)
*/
compatibility(ANSIMIN);
{
if (term->ldisc) {
char abuf[256], *s, *d;
int state = 0;
for (s = cfg.answerback, d = abuf; *s; s++) {
@ -1306,7 +1309,8 @@ void term_out(Terminal *term)
} else
*d++ = *s;
}
lpage_send(DEFAULT_CODEPAGE, abuf, d - abuf, 0);
lpage_send(term->ldisc, DEFAULT_CODEPAGE,
abuf, d - abuf, 0);
}
break;
case '\007':
@ -1617,12 +1621,15 @@ void term_out(Terminal *term)
break;
case 'Z': /* terminal type query */
compatibility(VT100);
ldisc_send(term->id_string, strlen(term->id_string), 0);
if (term->ldisc)
ldisc_send(term->ldisc, term->id_string,
strlen(term->id_string), 0);
break;
case 'c': /* restore power-on settings */
compatibility(VT100);
power_on(term);
ldisc_send(NULL, 0, 0);/* cause ldisc to notice changes */
if (term->ldisc) /* cause ldisc to notice changes */
ldisc_send(term->ldisc, NULL, 0, 0);
if (term->reset_132) {
if (!cfg.no_remote_resize)
request_resize(80, term->rows);
@ -1783,7 +1790,8 @@ void term_out(Terminal *term)
compatibility(OTHER);
/* this reports xterm version 136 so that VIM can
use the drag messages from the mouse reporting */
ldisc_send("\033[>0;136;0c", 11, 0);
if (term->ldisc)
ldisc_send(term->ldisc, "\033[>0;136;0c", 11, 0);
break;
case 'a': /* move right N cols */
compatibility(ANSI);
@ -1885,17 +1893,20 @@ void term_out(Terminal *term)
case 'c': /* terminal type query */
compatibility(VT100);
/* This is the response for a VT102 */
ldisc_send(term->id_string,
strlen(term->id_string), 0);
if (term->ldisc)
ldisc_send(term->ldisc, term->id_string,
strlen(term->id_string), 0);
break;
case 'n': /* cursor position query */
if (term->esc_args[0] == 6) {
char buf[32];
sprintf(buf, "\033[%d;%dR", term->curs.y + 1,
term->curs.x + 1);
ldisc_send(buf, strlen(buf), 0);
} else if (term->esc_args[0] == 5) {
ldisc_send("\033[0n", 4, 0);
if (term->ldisc) {
if (term->esc_args[0] == 6) {
char buf[32];
sprintf(buf, "\033[%d;%dR", term->curs.y + 1,
term->curs.x + 1);
ldisc_send(term->ldisc, buf, strlen(buf), 0);
} else if (term->esc_args[0] == 5) {
ldisc_send(term->ldisc, "\033[0n", 4, 0);
}
}
break;
case 'h': /* toggle modes to high */
@ -2175,23 +2186,31 @@ void term_out(Terminal *term)
TRUE : FALSE);
break;
case 11:
ldisc_send(is_iconic() ? "\033[1t" : "\033[2t",
4, 0);
if (term->ldisc)
ldisc_send(term->ldisc,
is_iconic() ? "\033[1t" :
"\033[2t", 4, 0);
break;
case 13:
get_window_pos(&x, &y);
len = sprintf(buf, "\033[3;%d;%dt", x, y);
ldisc_send(buf, len, 0);
if (term->ldisc) {
get_window_pos(&x, &y);
len = sprintf(buf, "\033[3;%d;%dt", x, y);
ldisc_send(term->ldisc, buf, len, 0);
}
break;
case 14:
get_window_pixels(&x, &y);
len = sprintf(buf, "\033[4;%d;%dt", x, y);
ldisc_send(buf, len, 0);
if (term->ldisc) {
get_window_pixels(&x, &y);
len = sprintf(buf, "\033[4;%d;%dt", x, y);
ldisc_send(term->ldisc, buf, len, 0);
}
break;
case 18:
len = sprintf(buf, "\033[8;%d;%dt",
term->rows, term->cols);
ldisc_send(buf, len, 0);
if (term->ldisc) {
len = sprintf(buf, "\033[8;%d;%dt",
term->rows, term->cols);
ldisc_send(term->ldisc, buf, len, 0);
}
break;
case 19:
/*
@ -2211,18 +2230,22 @@ void term_out(Terminal *term)
*/
break;
case 20:
p = get_window_title(TRUE);
len = strlen(p);
ldisc_send("\033]L", 3, 0);
ldisc_send(p, len, 0);
ldisc_send("\033\\", 2, 0);
if (term->ldisc) {
p = get_window_title(TRUE);
len = strlen(p);
ldisc_send(term->ldisc, "\033]L", 3, 0);
ldisc_send(term->ldisc, p, len, 0);
ldisc_send(term->ldisc, "\033\\", 2, 0);
}
break;
case 21:
p = get_window_title(FALSE);
len = strlen(p);
ldisc_send("\033]l", 3, 0);
ldisc_send(p, len, 0);
ldisc_send("\033\\", 2, 0);
if (term->ldisc) {
p = get_window_title(FALSE);
len = strlen(p);
ldisc_send(term->ldisc, "\033]l", 3, 0);
ldisc_send(term->ldisc, p, len, 0);
ldisc_send(term->ldisc, "\033\\", 2, 0);
}
break;
}
}
@ -2290,13 +2313,13 @@ void term_out(Terminal *term)
break;
case 'x': /* report terminal characteristics */
compatibility(VT100);
{
if (term->ldisc) {
char buf[32];
int i = def(term->esc_args[0], 0);
if (i == 0 || i == 1) {
strcpy(buf, "\033[2;1;1;112;112;1;0x");
buf[2] += i;
ldisc_send(buf, 20, 0);
ldisc_send(term->ldisc, buf, 20, 0);
}
}
break;
@ -2620,7 +2643,8 @@ void term_out(Terminal *term)
term->termstate = VT52_Y1;
break;
case 'Z':
ldisc_send("\033/Z", 3, 0);
if (term->ldisc)
ldisc_send(term->ldisc, "\033/Z", 3, 0);
break;
case '=':
term->app_keypad_keys = TRUE;
@ -3281,9 +3305,10 @@ void term_copyall(Terminal *term)
*/
static int wordtype(Terminal *term, int uc)
{
static struct {
struct ucsword {
int start, end, ctype;
} *wptr, ucs_words[] = {
};
static const struct ucsword ucs_words[] = {
{
128, 160, 0}, {
161, 191, 1}, {
@ -3347,6 +3372,7 @@ static int wordtype(Terminal *term, int uc)
{
0, 0, 0}
};
const struct ucsword *wptr;
uc &= (CSET_MASK | CHAR_MASK);
@ -3524,7 +3550,8 @@ void term_do_paste(Terminal *term)
/* Assume a small paste will be OK in one go. */
if (term->paste_len < 256) {
luni_send(term->paste_buffer, term->paste_len, 0);
if (term->ldisc)
luni_send(term->ldisc, term->paste_buffer, term->paste_len, 0);
if (term->paste_buffer)
sfree(term->paste_buffer);
term->paste_buffer = 0;
@ -3573,52 +3600,54 @@ void term_mouse(Terminal *term, Mouse_Button b, Mouse_Action a, int x, int y,
if (raw_mouse) {
int encstate = 0, r, c;
char abuf[16];
static int is_down = 0;
switch (b) {
case MBT_LEFT:
encstate = 0x20; /* left button down */
break;
case MBT_MIDDLE:
encstate = 0x21;
break;
case MBT_RIGHT:
encstate = 0x22;
break;
case MBT_WHEEL_UP:
encstate = 0x60;
break;
case MBT_WHEEL_DOWN:
encstate = 0x61;
break;
default: break; /* placate gcc warning about enum use */
}
switch (a) {
case MA_DRAG:
if (term->xterm_mouse == 1)
return;
encstate += 0x20;
break;
case MA_RELEASE:
encstate = 0x23;
is_down = 0;
break;
case MA_CLICK:
if (is_down == b)
return;
is_down = b;
break;
default: break; /* placate gcc warning about enum use */
}
if (shift)
encstate += 0x04;
if (ctrl)
encstate += 0x10;
r = y + 33;
c = x + 33;
if (term->ldisc) {
sprintf(abuf, "\033[M%c%c%c", encstate, c, r);
ldisc_send(abuf, 6, 0);
switch (b) {
case MBT_LEFT:
encstate = 0x20; /* left button down */
break;
case MBT_MIDDLE:
encstate = 0x21;
break;
case MBT_RIGHT:
encstate = 0x22;
break;
case MBT_WHEEL_UP:
encstate = 0x60;
break;
case MBT_WHEEL_DOWN:
encstate = 0x61;
break;
default: break; /* placate gcc warning about enum use */
}
switch (a) {
case MA_DRAG:
if (term->xterm_mouse == 1)
return;
encstate += 0x20;
break;
case MA_RELEASE:
encstate = 0x23;
term->mouse_is_down = 0;
break;
case MA_CLICK:
if (term->mouse_is_down == b)
return;
term->mouse_is_down = b;
break;
default: break; /* placate gcc warning about enum use */
}
if (shift)
encstate += 0x04;
if (ctrl)
encstate += 0x10;
r = y + 33;
c = x + 33;
sprintf(abuf, "\033[M%c%c%c", encstate, c, r);
ldisc_send(term->ldisc, abuf, 6, 0);
}
return;
}
@ -3775,7 +3804,8 @@ void term_paste(Terminal *term)
if (term->paste_buffer[term->paste_pos + n++] == '\r')
break;
}
luni_send(term->paste_buffer + term->paste_pos, n, 0);
if (term->ldisc)
luni_send(term->ldisc, term->paste_buffer + term->paste_pos, n, 0);
term->paste_pos += n;
if (term->paste_pos < term->paste_len) {

View File

@ -94,6 +94,7 @@ struct terminal_tag {
long last_tblink;
int xterm_mouse; /* send mouse messages to app */
int mouse_is_down; /* used while tracking mouse buttons */
unsigned long cset_attr[2];
@ -160,6 +161,8 @@ struct terminal_tag {
void (*resize_fn)(void *, int, int);
void *resize_ctx;
void *ldisc;
};
#define in_utf(term) ((term)->utf || line_codepage==CP_UTF8)

View File

@ -598,14 +598,14 @@ static void link_font(WCHAR * line_tbl, WCHAR * font_tbl, WCHAR attr)
}
}
void lpage_send(int codepage, char *buf, int len, int interactive)
void lpage_send(void *ldisc, int codepage, char *buf, int len, int interactive)
{
static wchar_t *widebuffer = 0;
static int widesize = 0;
int wclen;
if (codepage < 0) {
ldisc_send(buf, len, interactive);
ldisc_send(ldisc, buf, len, interactive);
return;
}
@ -616,10 +616,10 @@ void lpage_send(int codepage, char *buf, int len, int interactive)
}
wclen = mb_to_wc(codepage, 0, buf, len, widebuffer, widesize);
luni_send(widebuffer, wclen, interactive);
luni_send(ldisc, widebuffer, wclen, interactive);
}
void luni_send(wchar_t * widebuf, int len, int interactive)
void luni_send(void *ldisc, wchar_t * widebuf, int len, int interactive)
{
static char *linebuffer = 0;
static int linesize = 0;
@ -677,7 +677,7 @@ void luni_send(wchar_t * widebuf, int len, int interactive)
}
}
if (p > linebuffer)
ldisc_send(linebuffer, p - linebuffer, interactive);
ldisc_send(ldisc, linebuffer, p - linebuffer, interactive);
}
wchar_t xlat_uskbd2cyrllic(int ch)

View File

@ -53,13 +53,14 @@ struct gui_data {
char wintitle[sizeof(((Config *)0)->wintitle)];
char icontitle[sizeof(((Config *)0)->wintitle)];
int master_fd, master_func_id, exited;
void *ldisc;
};
static struct gui_data the_inst;
static struct gui_data *inst = &the_inst; /* so we always write `inst->' */
static int send_raw_mouse;
void ldisc_update(int echo, int edit)
void ldisc_update(void *frontend, int echo, int edit)
{
/*
* This is a stub in pterm. If I ever produce a Unix
@ -792,7 +793,7 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
printf("\n");
#endif
ldisc_send(output+start, end-start, 1);
ldisc_send(inst->ldisc, output+start, end-start, 1);
show_mouseptr(0);
term_seen_key_event(term);
term_out(term);
@ -924,8 +925,10 @@ void done_with_pty(struct gui_data *inst)
}
}
void frontend_keypress(void)
void frontend_keypress(void *handle)
{
struct gui_data *inst = (struct gui_data *)handle;
/*
* If our child process has exited but not closed, terminate on
* any keypress.
@ -1965,7 +1968,9 @@ int main(int argc, char **argv)
term_provide_resize_fn(term, back->size, backhandle);
term_size(term, cfg.height, cfg.width, cfg.savelines);
ldisc_send(NULL, 0, 0); /* cause ldisc to notice changes */
inst->ldisc = ldisc_create(term, back, backhandle, inst);
ldisc_send(inst->ldisc, NULL, 0, 0);/* cause ldisc to notice changes */
inst->master_fd = pty_master_fd;
inst->exited = FALSE;

View File

@ -589,6 +589,11 @@ static int pty_ldisc(void *handle, int option)
return 0; /* neither editing nor echoing */
}
static void pty_provide_ldisc(void *handle, void *ldisc)
{
/* This is a stub. */
}
static int pty_exitcode(void *handle)
{
if (!pty_child_dead)
@ -607,6 +612,7 @@ Backend pty_backend = {
pty_exitcode,
pty_sendok,
pty_ldisc,
pty_provide_ldisc,
pty_unthrottle,
1
};

View File

@ -14,12 +14,12 @@
* are ISO8859-1.
*/
void lpage_send(int codepage, char *buf, int len, int interactive)
void lpage_send(void *ldisc, int codepage, char *buf, int len, int interactive)
{
ldisc_send(buf, len, interactive);
ldisc_send(ldisc, buf, len, interactive);
}
void luni_send(wchar_t * widebuf, int len, int interactive)
void luni_send(void *ldisc, wchar_t * widebuf, int len, int interactive)
{
static char *linebuffer = 0;
static int linesize = 0;
@ -79,7 +79,7 @@ void luni_send(wchar_t * widebuf, int len, int interactive)
}
}
if (p > linebuffer)
ldisc_send(linebuffer, p - linebuffer, interactive);
ldisc_send(ldisc, linebuffer, p - linebuffer, interactive);
}
int is_dbcs_leadbyte(int codepage, char byte)

View File

@ -108,12 +108,15 @@ static LPARAM pend_netevent_lParam = 0;
static void enact_pending_netevent(void);
static void flash_window(int mode);
static void sys_cursor_update(void);
static int is_shift_pressed(void);
static int get_fullscreen_rect(RECT * ss);
static time_t last_movement = 0;
static int caret_x = -1, caret_y = -1;
static void *ldisc;
#define FONT_NORMAL 0
#define FONT_BOLD 1
#define FONT_UNDERLINE 2
@ -168,7 +171,7 @@ static OSVERSIONINFO osVersion;
static UINT wm_mousewheel = WM_MOUSEWHEEL;
/* Dummy routine, only required in plink. */
void ldisc_update(int echo, int edit)
void ldisc_update(void *frontend, int echo, int edit)
{
}
@ -625,6 +628,11 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
*/
term_provide_resize_fn(term, back->size, backhandle);
/*
* Set up a line discipline.
*/
ldisc = ldisc_create(term, back, backhandle, NULL);
session_closed = FALSE;
/*
@ -1748,7 +1756,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
* Flush the line discipline's edit buffer in the
* case where local editing has just been disabled.
*/
ldisc_send(NULL, 0, 0);
ldisc_send(ldisc, NULL, 0, 0);
if (pal)
DeleteObject(pal);
logpal = NULL;
@ -1862,7 +1870,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
break;
case IDM_RESET:
term_pwron(term);
ldisc_send(NULL, 0, 0);
ldisc_send(ldisc, NULL, 0, 0);
break;
case IDM_TEL_AYT:
back->special(backhandle, TS_AYT);
@ -2450,7 +2458,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
* we're sent.
*/
term_seen_key_event(term);
ldisc_send(buf, len, 1);
ldisc_send(ldisc, buf, len, 1);
show_mouseptr(0);
}
}
@ -2498,7 +2506,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
*/
term_seen_key_event(term);
for (i = 0; i < n; i += 2) {
luni_send((unsigned short *)(buff+i), 1, 1);
luni_send(ldisc, (unsigned short *)(buff+i), 1, 1);
}
free(buff);
}
@ -2513,11 +2521,11 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
buf[1] = wParam;
buf[0] = wParam >> 8;
term_seen_key_event(term);
lpage_send(kbd_codepage, buf, 2, 1);
lpage_send(ldisc, kbd_codepage, buf, 2, 1);
} else {
char c = (unsigned char) wParam;
term_seen_key_event(term);
lpage_send(kbd_codepage, &c, 1, 1);
lpage_send(ldisc, kbd_codepage, &c, 1, 1);
}
return (0);
case WM_CHAR:
@ -2531,7 +2539,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
{
char c = (unsigned char)wParam;
term_seen_key_event(term);
lpage_send(CP_ACP, &c, 1, 1);
lpage_send(ldisc, CP_ACP, &c, 1, 1);
}
return 0;
case WM_SETCURSOR:
@ -3780,7 +3788,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
}
keybuf = nc;
term_seen_key_event(term);
luni_send(&keybuf, 1, 1);
luni_send(ldisc, &keybuf, 1, 1);
continue;
}
@ -3791,7 +3799,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
if (in_utf(term) || dbcs_screenfont) {
keybuf = alt_sum;
term_seen_key_event(term);
luni_send(&keybuf, 1, 1);
luni_send(ldisc, &keybuf, 1, 1);
} else {
ch = (char) alt_sum;
/*
@ -3804,25 +3812,26 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
* everything we're sent.
*/
term_seen_key_event(term);
ldisc_send(&ch, 1, 1);
ldisc_send(ldisc, &ch, 1, 1);
}
alt_sum = 0;
} else
term_seen_key_event(term);
lpage_send(kbd_codepage, &ch, 1, 1);
lpage_send(ldisc, kbd_codepage, &ch, 1, 1);
} else {
if(capsOn && ch < 0x80) {
WCHAR cbuf[2];
cbuf[0] = 27;
cbuf[1] = xlat_uskbd2cyrllic(ch);
term_seen_key_event(term);
luni_send(cbuf+!left_alt, 1+!!left_alt, 1);
luni_send(ldisc, cbuf+!left_alt, 1+!!left_alt, 1);
} else {
char cbuf[2];
cbuf[0] = '\033';
cbuf[1] = ch;
term_seen_key_event(term);
lpage_send(kbd_codepage, cbuf+!left_alt, 1+!!left_alt, 1);
lpage_send(ldisc, kbd_codepage,
cbuf+!left_alt, 1+!!left_alt, 1);
}
}
show_mouseptr(0);
@ -4559,7 +4568,7 @@ void flip_full_screen()
}
}
void frontend_keypress(void)
void frontend_keypress(void *handle)
{
/*
* Keypress termination in non-Close-On-Exit mode is not

View File

@ -174,6 +174,6 @@ void EnableSizeTip(int bEnable);
#define mb_to_wc(cp, flags, mbstr, mblen, wcstr, wclen) \
MultiByteToWideChar(cp, flags, mbstr, mblen, wcstr, wclen)
#define wc_to_mb(cp, flags, wcstr, wclen, mbstr, mblen, def, defused) \
WideCharToMultiByte(cp, flags, mbstr, mblen, wcstr, wclen, def,defused)
WideCharToMultiByte(cp, flags, wcstr, wclen, mbstr, mblen, def,defused)
#endif