return 1;
}
-void frontend_keypress(void)
+void frontend_keypress(void *handle)
{
/*
* This is nothing but a stub, in console code.
#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 */
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;
}
/*
* 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.
*/
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
*/
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;
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
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;
/*
*/
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);
}
}
}
{
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;
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.
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);
* 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.
#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);
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 */
raw_exitcode,
raw_sendok,
raw_ldisc,
+ raw_provide_ldisc,
raw_unthrottle,
1
};
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;
rlogin_exitcode,
rlogin_sendok,
rlogin_ldisc,
+ rlogin_provide_ldisc,
rlogin_unthrottle,
1
};
Socket s;
+ void *ldisc;
+
unsigned char session_key[32];
int v1_compressing;
int v1_remote_protoflags;
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) {
/*
* 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;
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;
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;
ssh_return_exitcode,
ssh_sendok,
ssh_ldisc,
+ ssh_provide_ldisc,
ssh_unthrottle,
22
};
Socket s;
void *frontend;
+ void *ldisc;
int term_width, term_height;
int opt_states[NUM_OPTS];
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) {
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;
telnet_exitcode,
telnet_sendok,
telnet_ldisc,
+ telnet_provide_ldisc,
telnet_unthrottle,
23
};
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);
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;
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);
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;
* 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++) {
} else
*d++ = *s;
}
- lpage_send(DEFAULT_CODEPAGE, abuf, d - abuf, 0);
+ lpage_send(term->ldisc, DEFAULT_CODEPAGE,
+ abuf, d - abuf, 0);
}
break;
case '\007':
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);
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);
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 */
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:
/*
*/
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;
}
}
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;
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;
*/
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}, {
{
0, 0, 0}
};
+ const struct ucsword *wptr;
uc &= (CSET_MASK | CHAR_MASK);
/* 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;
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 (term->ldisc) {
+
+ 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);
}
- 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(abuf, 6, 0);
return;
}
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) {
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];
void (*resize_fn)(void *, int, int);
void *resize_ctx;
+
+ void *ldisc;
};
#define in_utf(term) ((term)->utf || line_codepage==CP_UTF8)
}
}
-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;
}
}
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;
}
}
if (p > linebuffer)
- ldisc_send(linebuffer, p - linebuffer, interactive);
+ ldisc_send(ldisc, linebuffer, p - linebuffer, interactive);
}
wchar_t xlat_uskbd2cyrllic(int ch)
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
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);
}
}
-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.
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;
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)
pty_exitcode,
pty_sendok,
pty_ldisc,
+ pty_provide_ldisc,
pty_unthrottle,
1
};
* 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;
}
}
if (p > linebuffer)
- ldisc_send(linebuffer, p - linebuffer, interactive);
+ ldisc_send(ldisc, linebuffer, p - linebuffer, interactive);
}
int is_dbcs_leadbyte(int codepage, char byte)
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
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)
{
}
*/
term_provide_resize_fn(term, back->size, backhandle);
+ /*
+ * Set up a line discipline.
+ */
+ ldisc = ldisc_create(term, back, backhandle, NULL);
+
session_closed = FALSE;
/*
* 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;
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);
* we're sent.
*/
term_seen_key_event(term);
- ldisc_send(buf, len, 1);
+ ldisc_send(ldisc, buf, len, 1);
show_mouseptr(0);
}
}
*/
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);
}
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:
{
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:
}
keybuf = nc;
term_seen_key_event(term);
- luni_send(&keybuf, 1, 1);
+ luni_send(ldisc, &keybuf, 1, 1);
continue;
}
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;
/*
* 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);
}
}
-void frontend_keypress(void)
+void frontend_keypress(void *handle)
{
/*
* Keypress termination in non-Close-On-Exit mode is not
#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