1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-25 01:02:24 +00:00

Major destabilisation, phase 1. In this phase I've moved (I think)

all the global and function-static variables out of terminal.c into
a dynamically allocated data structure. Note that this does not yet
confer the ability to run more than one of them in the same process,
because other things (the line discipline, the back end) are still
global, and also in particular the address of the dynamically
allocated terminal-data structure is held in a global variable
`term'. But what I've got here represents a reasonable stopping
point at which to check things in. In _theory_ this should all still
work happily, on both Unix and Windows. In practice, who knows?

[originally from svn r2115]
This commit is contained in:
Simon Tatham 2002-10-22 16:11:33 +00:00
parent 48314f7dc0
commit 0a80c983e2
15 changed files with 1577 additions and 1608 deletions

12
ldisc.c
View File

@ -9,17 +9,18 @@
#include <ctype.h> #include <ctype.h>
#include "putty.h" #include "putty.h"
#include "terminal.h"
#define ECHOING (cfg.localecho == LD_YES || \ #define ECHOING (cfg.localecho == LD_YES || \
(cfg.localecho == LD_BACKEND && \ (cfg.localecho == LD_BACKEND && \
(back->ldisc(LD_ECHO) || term_ldisc(LD_ECHO)))) (back->ldisc(LD_ECHO) || term_ldisc(term, LD_ECHO))))
#define EDITING (cfg.localedit == LD_YES || \ #define EDITING (cfg.localedit == LD_YES || \
(cfg.localedit == LD_BACKEND && \ (cfg.localedit == LD_BACKEND && \
(back->ldisc(LD_EDIT) || term_ldisc(LD_EDIT)))) (back->ldisc(LD_EDIT) || term_ldisc(term, LD_EDIT))))
static void c_write(char *buf, int len) static void c_write(char *buf, int len)
{ {
from_backend(0, buf, len); from_backend(term, 0, buf, len);
} }
static char *term_buf = NULL; static char *term_buf = NULL;
@ -27,7 +28,7 @@ static int term_buflen = 0, term_bufsiz = 0, term_quotenext = 0;
static int plen(unsigned char c) static int plen(unsigned char c)
{ {
if ((c >= 32 && c <= 126) || (c >= 160 && !in_utf)) if ((c >= 32 && c <= 126) || (c >= 160 && !in_utf(term)))
return 1; return 1;
else if (c < 128) else if (c < 128)
return 2; /* ^x for some x */ return 2; /* ^x for some x */
@ -37,7 +38,7 @@ static int plen(unsigned char c)
static void pwrite(unsigned char c) static void pwrite(unsigned char c)
{ {
if ((c >= 32 && c <= 126) || (c >= 160 && !in_utf)) { if ((c >= 32 && c <= 126) || (c >= 160 && !in_utf(term))) {
c_write(&c, 1); c_write(&c, 1);
} else if (c < 128) { } else if (c < 128) {
char cc[2]; char cc[2];
@ -70,6 +71,7 @@ void ldisc_send(char *buf, int len, int interactive)
if (len == 0) { if (len == 0) {
void ldisc_update(int echo, int edit); void ldisc_update(int echo, int edit);
ldisc_update(ECHOING, EDITING); ldisc_update(ECHOING, EDITING);
return;
} }
/* /*
* Less than zero means null terminated special string. * Less than zero means null terminated special string.

View File

@ -69,7 +69,7 @@ DWORD orig_console_mode;
WSAEVENT netevent; WSAEVENT netevent;
int term_ldisc(int mode) int term_ldisc(Terminal *term, int mode)
{ {
return FALSE; return FALSE;
} }
@ -164,7 +164,7 @@ void try_output(int is_stderr)
} }
} }
int from_backend(int is_stderr, char *data, int len) int from_backend(void *frontend_handle, int is_stderr, char *data, int len)
{ {
HANDLE h = (is_stderr ? errhandle : outhandle); HANDLE h = (is_stderr ? errhandle : outhandle);
int osize, esize; int osize, esize;
@ -529,7 +529,7 @@ int main(int argc, char **argv)
int nodelay = cfg.tcp_nodelay && int nodelay = cfg.tcp_nodelay &&
(GetFileType(GetStdHandle(STD_INPUT_HANDLE)) == FILE_TYPE_CHAR); (GetFileType(GetStdHandle(STD_INPUT_HANDLE)) == FILE_TYPE_CHAR);
error = back->init(cfg.host, cfg.port, &realhost, nodelay); error = back->init(NULL, cfg.host, cfg.port, &realhost, nodelay);
if (error) { if (error) {
fprintf(stderr, "Unable to open connection:\n%s", error); fprintf(stderr, "Unable to open connection:\n%s", error);
return 1; return 1;

View File

@ -1522,7 +1522,7 @@ static unsigned char *outptr; /* where to put the data */
static unsigned outlen; /* how much data required */ static unsigned outlen; /* how much data required */
static unsigned char *pending = NULL; /* any spare data */ static unsigned char *pending = NULL; /* any spare data */
static unsigned pendlen = 0, pendsize = 0; /* length and phys. size of buffer */ static unsigned pendlen = 0, pendsize = 0; /* length and phys. size of buffer */
int from_backend(int is_stderr, char *data, int datalen) int from_backend(void *frontend, int is_stderr, char *data, int datalen)
{ {
unsigned char *p = (unsigned char *) data; unsigned char *p = (unsigned char *) data;
unsigned len = (unsigned) datalen; unsigned len = (unsigned) datalen;
@ -1822,7 +1822,7 @@ static int psftp_connect(char *userhost, char *user, int portnumber)
back = &ssh_backend; back = &ssh_backend;
err = back->init(cfg.host, cfg.port, &realhost, 0); err = back->init(NULL, cfg.host, cfg.port, &realhost, 0);
if (err != NULL) { if (err != NULL) {
fprintf(stderr, "ssh_init: %s\n", err); fprintf(stderr, "ssh_init: %s\n", err);
return 1; return 1;

66
putty.h
View File

@ -18,6 +18,7 @@
typedef struct config_tag Config; typedef struct config_tag Config;
typedef struct backend_tag Backend; typedef struct backend_tag Backend;
typedef struct terminal_tag Terminal;
#include "puttyps.h" #include "puttyps.h"
#include "network.h" #include "network.h"
@ -99,23 +100,10 @@ typedef struct backend_tag Backend;
#define ATTR_CUR_AND (~(ATTR_BOLD|ATTR_REVERSE|ATTR_BLINK|ATTR_COLOURS)) #define ATTR_CUR_AND (~(ATTR_BOLD|ATTR_REVERSE|ATTR_BLINK|ATTR_COLOURS))
#define ATTR_CUR_XOR 0x00BA0000UL #define ATTR_CUR_XOR 0x00BA0000UL
GLOBAL int rows, cols, savelines;
GLOBAL int has_focus;
GLOBAL int in_vbell;
GLOBAL unsigned long vbell_startpoint;
GLOBAL int app_cursor_keys, app_keypad_keys, vt52_mode;
GLOBAL int repeat_off, cr_lf_return;
GLOBAL int seen_disp_event;
GLOBAL int alt_pressed; GLOBAL int alt_pressed;
GLOBAL int session_closed; GLOBAL int session_closed;
GLOBAL int big_cursor;
GLOBAL char *help_path; GLOBAL char *help_path;
GLOBAL int help_has_contents; GLOBAL int help_has_contents;
@ -133,7 +121,6 @@ GLOBAL wchar_t unitab_font[256];
GLOBAL wchar_t unitab_xterm[256]; GLOBAL wchar_t unitab_xterm[256];
GLOBAL wchar_t unitab_oemcp[256]; GLOBAL wchar_t unitab_oemcp[256];
GLOBAL unsigned char unitab_ctrl[256]; GLOBAL unsigned char unitab_ctrl[256];
#define in_utf (utf || line_codepage==CP_UTF8)
#define LGXF_OVR 1 /* existing logfile overwrite */ #define LGXF_OVR 1 /* existing logfile overwrite */
#define LGXF_APN 0 /* existing logfile append */ #define LGXF_APN 0 /* existing logfile append */
@ -201,7 +188,8 @@ enum {
}; };
struct backend_tag { struct backend_tag {
char *(*init) (char *host, int port, char **realhost, int nodelay); char *(*init) (void *frontend_handle,
char *host, int port, char **realhost, int nodelay);
/* back->send() returns the current amount of buffered data. */ /* back->send() returns the current amount of buffered data. */
int (*send) (char *buf, int len); int (*send) (char *buf, int len);
/* back->sendbuffer() does the same thing but without attempting a send */ /* back->sendbuffer() does the same thing but without attempting a send */
@ -410,6 +398,8 @@ GLOBAL Config cfg;
GLOBAL int default_protocol; GLOBAL int default_protocol;
GLOBAL int default_port; GLOBAL int default_port;
GLOBAL Terminal *term; /* temporary while changes are made */
struct RSAKey; /* be a little careful of scope */ struct RSAKey; /* be a little careful of scope */
/* /*
@ -476,33 +466,33 @@ void registry_cleanup(void);
* Exports from terminal.c. * Exports from terminal.c.
*/ */
void term_init(void); Terminal *term_init(void);
void term_size(int, int, int); void term_size(Terminal *, int, int, int);
void term_out(void); void term_out(Terminal *);
void term_paint(Context, int, int, int, int); void term_paint(Terminal *, Context, int, int, int, int);
void term_scroll(int, int); void term_scroll(Terminal *, int, int);
void term_pwron(void); void term_pwron(Terminal *);
void term_clrsb(void); void term_clrsb(Terminal *);
void term_mouse(Mouse_Button, Mouse_Action, int, int, int, int, int); void term_mouse(Terminal *, Mouse_Button, Mouse_Action, int,int,int,int,int);
void term_deselect(void); void term_deselect(Terminal *);
void term_update(void); void term_update(Terminal *);
void term_invalidate(void); void term_invalidate(Terminal *);
void term_blink(int set_cursor); void term_blink(Terminal *, int set_cursor);
void term_do_paste(void); void term_do_paste(Terminal *);
int term_paste_pending(void); int term_paste_pending(Terminal *);
void term_paste(void); void term_paste(Terminal *);
void term_nopaste(void); void term_nopaste(Terminal *);
int term_ldisc(int option); int term_ldisc(Terminal *, int option);
int from_backend(int is_stderr, char *data, int len); void term_copyall(Terminal *);
void logfopen(void); void term_reconfig(Terminal *);
void logfclose(void); void term_seen_key_event(Terminal *);
void term_copyall(void); int from_backend(void *, int is_stderr, char *data, int len);
void term_reconfig(void);
void term_seen_key_event(void);
/* /*
* Exports from logging.c. * Exports from logging.c.
*/ */
void logfopen();
void logfclose();
void logtraffic(unsigned char c, int logmode); void logtraffic(unsigned char c, int logmode);
enum { PKT_INCOMING, PKT_OUTGOING }; enum { PKT_INCOMING, PKT_OUTGOING };
void log_eventlog(char *string); void log_eventlog(char *string);

8
raw.c
View File

@ -15,12 +15,13 @@
static Socket s = NULL; static Socket s = NULL;
static int raw_bufsize; static int raw_bufsize;
static void *frontend;
static void raw_size(void); static void raw_size(void);
static void c_write(char *buf, int len) static void c_write(char *buf, int len)
{ {
int backlog = from_backend(0, buf, len); int backlog = from_backend(frontend, 0, buf, len);
sk_set_frozen(s, backlog > RAW_MAX_BACKLOG); sk_set_frozen(s, backlog > RAW_MAX_BACKLOG);
} }
@ -58,7 +59,8 @@ static void raw_sent(Plug plug, int bufsize)
* Also places the canonical host name into `realhost'. It must be * Also places the canonical host name into `realhost'. It must be
* freed by the caller. * freed by the caller.
*/ */
static char *raw_init(char *host, int port, char **realhost, int nodelay) static char *raw_init(void *frontend_handle, char *host, int port,
char **realhost, int nodelay)
{ {
static struct plug_function_table fn_table = { static struct plug_function_table fn_table = {
raw_closing, raw_closing,
@ -69,6 +71,8 @@ static char *raw_init(char *host, int port, char **realhost, int nodelay)
SockAddr addr; SockAddr addr;
char *err; char *err;
frontend = frontend_handle;
/* /*
* Try to find host. * Try to find host.
*/ */

View File

@ -4,6 +4,7 @@
#include <ctype.h> #include <ctype.h>
#include "putty.h" #include "putty.h"
#include "terminal.h"
#ifndef FALSE #ifndef FALSE
#define FALSE 0 #define FALSE 0
@ -16,12 +17,13 @@
static Socket s = NULL; static Socket s = NULL;
static int rlogin_bufsize; static int rlogin_bufsize;
static void *frontend;
static void rlogin_size(void); static void rlogin_size(void);
static void c_write(char *buf, int len) static void c_write(char *buf, int len)
{ {
int backlog = from_backend(0, buf, len); int backlog = from_backend(frontend, 0, buf, len);
sk_set_frozen(s, backlog > RLOGIN_MAX_BACKLOG); sk_set_frozen(s, backlog > RLOGIN_MAX_BACKLOG);
} }
@ -88,7 +90,8 @@ static void rlogin_sent(Plug plug, int bufsize)
* Also places the canonical host name into `realhost'. It must be * Also places the canonical host name into `realhost'. It must be
* freed by the caller. * freed by the caller.
*/ */
static char *rlogin_init(char *host, int port, char **realhost, int nodelay) static char *rlogin_init(void *frontend_handle,
char *host, int port, char **realhost, int nodelay)
{ {
static struct plug_function_table fn_table = { static struct plug_function_table fn_table = {
rlogin_closing, rlogin_closing,
@ -99,6 +102,8 @@ static char *rlogin_init(char *host, int port, char **realhost, int nodelay)
SockAddr addr; SockAddr addr;
char *err; char *err;
frontend = frontend_handle;
/* /*
* Try to find host. * Try to find host.
*/ */
@ -179,13 +184,13 @@ static void rlogin_size(void)
{ {
char b[12] = { '\xFF', '\xFF', 0x73, 0x73, 0, 0, 0, 0, 0, 0, 0, 0 }; char b[12] = { '\xFF', '\xFF', 0x73, 0x73, 0, 0, 0, 0, 0, 0, 0, 0 };
if (s == NULL) if (s == NULL || term == NULL)
return; return;
b[6] = cols >> 8; b[6] = term->cols >> 8;
b[7] = cols & 0xFF; b[7] = term->cols & 0xFF;
b[4] = rows >> 8; b[4] = term->rows >> 8;
b[5] = rows & 0xFF; b[5] = term->rows & 0xFF;
rlogin_bufsize = sk_write(s, b, 12); rlogin_bufsize = sk_write(s, b, 12);
return; return;
} }

4
scp.c
View File

@ -308,7 +308,7 @@ static unsigned char *outptr; /* where to put the data */
static unsigned outlen; /* how much data required */ static unsigned outlen; /* how much data required */
static unsigned char *pending = NULL; /* any spare data */ static unsigned char *pending = NULL; /* any spare data */
static unsigned pendlen = 0, pendsize = 0; /* length and phys. size of buffer */ static unsigned pendlen = 0, pendsize = 0; /* length and phys. size of buffer */
int from_backend(int is_stderr, char *data, int datalen) int from_backend(void *frontend, int is_stderr, char *data, int datalen)
{ {
unsigned char *p = (unsigned char *) data; unsigned char *p = (unsigned char *) data;
unsigned len = (unsigned) datalen; unsigned len = (unsigned) datalen;
@ -565,7 +565,7 @@ static void do_cmd(char *host, char *user, char *cmd)
back = &ssh_backend; back = &ssh_backend;
err = back->init(cfg.host, cfg.port, &realhost, 0); err = back->init(NULL, cfg.host, cfg.port, &realhost, 0);
if (err != NULL) if (err != NULL)
bump("ssh_init: %s", err); bump("ssh_init: %s", err);
ssh_scp_init(); ssh_scp_init();

29
ssh.c
View File

@ -5,6 +5,7 @@
#include <assert.h> #include <assert.h>
#include "putty.h" #include "putty.h"
#include "terminal.h"
#include "tree234.h" #include "tree234.h"
#include "ssh.h" #include "ssh.h"
@ -533,6 +534,8 @@ static int savedport;
static int ssh_send_ok; static int ssh_send_ok;
static int ssh_echoing, ssh_editing; static int ssh_echoing, ssh_editing;
static void *frontend;
static tree234 *ssh_channels; /* indexed by local id */ static tree234 *ssh_channels; /* indexed by local id */
static struct ssh_channel *mainchan; /* primary session channel */ static struct ssh_channel *mainchan; /* primary session channel */
static int ssh_exitcode = -1; static int ssh_exitcode = -1;
@ -688,7 +691,7 @@ static void c_write(char *buf, int len)
fputc(buf[i], stderr); fputc(buf[i], stderr);
return; return;
} }
from_backend(1, buf, len); from_backend(frontend, 1, buf, len);
} }
static void c_write_untrusted(char *buf, int len) static void c_write_untrusted(char *buf, int len)
@ -3124,7 +3127,8 @@ static void ssh1_protocol(unsigned char *in, int inlen, int ispkt)
if (!cfg.nopty) { if (!cfg.nopty) {
send_packet(SSH1_CMSG_REQUEST_PTY, send_packet(SSH1_CMSG_REQUEST_PTY,
PKT_STR, cfg.termtype, PKT_STR, cfg.termtype,
PKT_INT, rows, PKT_INT, cols, PKT_INT, term ? term->rows : 24,
PKT_INT, term ? term->cols : 80,
PKT_INT, 0, PKT_INT, 0, PKT_CHAR, 0, PKT_END); PKT_INT, 0, PKT_INT, 0, PKT_CHAR, 0, PKT_END);
ssh_state = SSH_STATE_INTERMED; ssh_state = SSH_STATE_INTERMED;
do { do {
@ -3198,7 +3202,7 @@ static void ssh1_protocol(unsigned char *in, int inlen, int ispkt)
pktin.type == SSH1_SMSG_STDERR_DATA) { pktin.type == SSH1_SMSG_STDERR_DATA) {
long len = GET_32BIT(pktin.body); long len = GET_32BIT(pktin.body);
int bufsize = int bufsize =
from_backend(pktin.type == SSH1_SMSG_STDERR_DATA, from_backend(frontend, pktin.type == SSH1_SMSG_STDERR_DATA,
pktin.body + 4, len); pktin.body + 4, len);
if (!ssh1_stdout_throttling && bufsize > SSH1_BUFFER_LIMIT) { if (!ssh1_stdout_throttling && bufsize > SSH1_BUFFER_LIMIT) {
ssh1_stdout_throttling = 1; ssh1_stdout_throttling = 1;
@ -5142,8 +5146,8 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
ssh2_pkt_addstring("pty-req"); ssh2_pkt_addstring("pty-req");
ssh2_pkt_addbool(1); /* want reply */ ssh2_pkt_addbool(1); /* want reply */
ssh2_pkt_addstring(cfg.termtype); ssh2_pkt_addstring(cfg.termtype);
ssh2_pkt_adduint32(cols); ssh2_pkt_adduint32(term ? term->cols : 80);
ssh2_pkt_adduint32(rows); ssh2_pkt_adduint32(term ? term->rows : 24);
ssh2_pkt_adduint32(0); /* pixel width */ ssh2_pkt_adduint32(0); /* pixel width */
ssh2_pkt_adduint32(0); /* pixel height */ ssh2_pkt_adduint32(0); /* pixel height */
ssh2_pkt_addstring_start(); ssh2_pkt_addstring_start();
@ -5281,7 +5285,7 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt)
switch (c->type) { switch (c->type) {
case CHAN_MAINSESSION: case CHAN_MAINSESSION:
bufsize = bufsize =
from_backend(pktin.type == from_backend(frontend, pktin.type ==
SSH2_MSG_CHANNEL_EXTENDED_DATA, SSH2_MSG_CHANNEL_EXTENDED_DATA,
data, length); data, length);
break; break;
@ -5706,7 +5710,8 @@ static void ssh2_protocol(unsigned char *in, int inlen, int ispkt)
* *
* Returns an error message, or NULL on success. * Returns an error message, or NULL on success.
*/ */
static char *ssh_init(char *host, int port, char **realhost, int nodelay) static char *ssh_init(void *frontend_handle,
char *host, int port, char **realhost, int nodelay)
{ {
char *p; char *p;
@ -5715,6 +5720,8 @@ static char *ssh_init(char *host, int port, char **realhost, int nodelay)
return "Microsoft high encryption pack not installed!"; return "Microsoft high encryption pack not installed!";
#endif #endif
frontend = frontend_handle;
ssh_send_ok = 0; ssh_send_ok = 0;
ssh_editing = 0; ssh_editing = 0;
ssh_echoing = 0; ssh_echoing = 0;
@ -5787,17 +5794,19 @@ static void ssh_size(void)
break; break;
case SSH_STATE_SESSION: case SSH_STATE_SESSION:
if (!cfg.nopty) { if (!cfg.nopty) {
if (!term)
return;
if (ssh_version == 1) { if (ssh_version == 1) {
send_packet(SSH1_CMSG_WINDOW_SIZE, send_packet(SSH1_CMSG_WINDOW_SIZE,
PKT_INT, rows, PKT_INT, cols, PKT_INT, term->rows, PKT_INT, term->cols,
PKT_INT, 0, PKT_INT, 0, PKT_END); PKT_INT, 0, PKT_INT, 0, PKT_END);
} else { } else {
ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST); ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST);
ssh2_pkt_adduint32(mainchan->remoteid); ssh2_pkt_adduint32(mainchan->remoteid);
ssh2_pkt_addstring("window-change"); ssh2_pkt_addstring("window-change");
ssh2_pkt_addbool(0); ssh2_pkt_addbool(0);
ssh2_pkt_adduint32(cols); ssh2_pkt_adduint32(term->cols);
ssh2_pkt_adduint32(rows); ssh2_pkt_adduint32(term->rows);
ssh2_pkt_adduint32(0); ssh2_pkt_adduint32(0);
ssh2_pkt_adduint32(0); ssh2_pkt_adduint32(0);
ssh2_pkt_send(); ssh2_pkt_send();

View File

@ -3,6 +3,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "putty.h" #include "putty.h"
#include "terminal.h"
#ifndef FALSE #ifndef FALSE
#define FALSE 0 #define FALSE 0
@ -13,6 +14,8 @@
static Socket s = NULL; static Socket s = NULL;
static void *frontend;
#define IAC 255 /* interpret as command: */ #define IAC 255 /* interpret as command: */
#define DONT 254 /* you are not to use option */ #define DONT 254 /* you are not to use option */
#define DO 253 /* please, you use option */ #define DO 253 /* please, you use option */
@ -189,7 +192,7 @@ static void c_write1(int c)
{ {
int backlog; int backlog;
char cc = (char) c; char cc = (char) c;
backlog = from_backend(0, &cc, 1); backlog = from_backend(frontend, 0, &cc, 1);
sk_set_frozen(s, backlog > TELNET_MAX_BACKLOG); sk_set_frozen(s, backlog > TELNET_MAX_BACKLOG);
} }
@ -451,9 +454,9 @@ static void process_subneg(void)
} }
static enum { static enum {
TOPLEVEL, SEENIAC, SEENWILL, SEENWONT, SEENDO, SEENDONT, TOP_LEVEL, SEENIAC, SEENWILL, SEENWONT, SEENDO, SEENDONT,
SEENSB, SUBNEGOT, SUBNEG_IAC, SEENCR SEENSB, SUBNEGOT, SUBNEG_IAC, SEENCR
} telnet_state = TOPLEVEL; } telnet_state = TOP_LEVEL;
static void do_telnet_read(char *buf, int len) static void do_telnet_read(char *buf, int len)
{ {
@ -462,10 +465,10 @@ static void do_telnet_read(char *buf, int len)
int c = (unsigned char) *buf++; int c = (unsigned char) *buf++;
switch (telnet_state) { switch (telnet_state) {
case TOPLEVEL: case TOP_LEVEL:
case SEENCR: case SEENCR:
if (c == NUL && telnet_state == SEENCR) if (c == NUL && telnet_state == SEENCR)
telnet_state = TOPLEVEL; telnet_state = TOP_LEVEL;
else if (c == IAC) else if (c == IAC)
telnet_state = SEENIAC; telnet_state = SEENIAC;
else { else {
@ -487,7 +490,7 @@ static void do_telnet_read(char *buf, int len)
if (c == CR) if (c == CR)
telnet_state = SEENCR; telnet_state = SEENCR;
else else
telnet_state = TOPLEVEL; telnet_state = TOP_LEVEL;
} }
break; break;
case SEENIAC: case SEENIAC:
@ -503,30 +506,30 @@ static void do_telnet_read(char *buf, int len)
telnet_state = SEENSB; telnet_state = SEENSB;
else if (c == DM) { else if (c == DM) {
in_synch = 0; in_synch = 0;
telnet_state = TOPLEVEL; telnet_state = TOP_LEVEL;
} else { } else {
/* ignore everything else; print it if it's IAC */ /* ignore everything else; print it if it's IAC */
if (c == IAC) { if (c == IAC) {
c_write1(c); c_write1(c);
} }
telnet_state = TOPLEVEL; telnet_state = TOP_LEVEL;
} }
break; break;
case SEENWILL: case SEENWILL:
proc_rec_opt(WILL, c); proc_rec_opt(WILL, c);
telnet_state = TOPLEVEL; telnet_state = TOP_LEVEL;
break; break;
case SEENWONT: case SEENWONT:
proc_rec_opt(WONT, c); proc_rec_opt(WONT, c);
telnet_state = TOPLEVEL; telnet_state = TOP_LEVEL;
break; break;
case SEENDO: case SEENDO:
proc_rec_opt(DO, c); proc_rec_opt(DO, c);
telnet_state = TOPLEVEL; telnet_state = TOP_LEVEL;
break; break;
case SEENDONT: case SEENDONT:
proc_rec_opt(DONT, c); proc_rec_opt(DONT, c);
telnet_state = TOPLEVEL; telnet_state = TOP_LEVEL;
break; break;
case SEENSB: case SEENSB:
sb_opt = c; sb_opt = c;
@ -559,7 +562,7 @@ static void do_telnet_read(char *buf, int len)
goto subneg_addchar; /* yes, it's a hack, I know, but... */ goto subneg_addchar; /* yes, it's a hack, I know, but... */
else { else {
process_subneg(); process_subneg();
telnet_state = TOPLEVEL; telnet_state = TOP_LEVEL;
} }
break; break;
} }
@ -602,7 +605,8 @@ static void telnet_sent(Plug plug, int bufsize)
* Also places the canonical host name into `realhost'. It must be * Also places the canonical host name into `realhost'. It must be
* freed by the caller. * freed by the caller.
*/ */
static char *telnet_init(char *host, int port, char **realhost, int nodelay) static char *telnet_init(void *frontend_handle,
char *host, int port, char **realhost, int nodelay)
{ {
static struct plug_function_table fn_table = { static struct plug_function_table fn_table = {
telnet_closing, telnet_closing,
@ -613,6 +617,8 @@ static char *telnet_init(char *host, int port, char **realhost, int nodelay)
SockAddr addr; SockAddr addr;
char *err; char *err;
frontend = frontend_handle;
/* /*
* Try to find host. * Try to find host.
*/ */
@ -718,15 +724,15 @@ static void telnet_size(void)
unsigned char b[16]; unsigned char b[16];
char logbuf[50]; char logbuf[50];
if (s == NULL || o_naws.state != ACTIVE) if (s == NULL || term == NULL || o_naws.state != ACTIVE)
return; return;
b[0] = IAC; b[0] = IAC;
b[1] = SB; b[1] = SB;
b[2] = TELOPT_NAWS; b[2] = TELOPT_NAWS;
b[3] = cols >> 8; b[3] = term->cols >> 8;
b[4] = cols & 0xFF; b[4] = term->cols & 0xFF;
b[5] = rows >> 8; b[5] = term->rows >> 8;
b[6] = rows & 0xFF; b[6] = term->rows & 0xFF;
b[7] = IAC; b[7] = IAC;
b[8] = SE; b[8] = SE;
telnet_bufsize = sk_write(s, b, 9); telnet_bufsize = sk_write(s, b, 9);

2561
terminal.c

File diff suppressed because it is too large Load Diff

View File

@ -8,6 +8,7 @@
#include <time.h> #include <time.h>
#include "putty.h" #include "putty.h"
#include "terminal.h"
#include "misc.h" #include "misc.h"
/* Character conversion arrays; they are usually taken from windows, /* Character conversion arrays; they are usually taken from windows,
@ -622,7 +623,7 @@ void luni_send(wchar_t * widebuf, int len, int interactive)
{ {
static char *linebuffer = 0; static char *linebuffer = 0;
static int linesize = 0; static int linesize = 0;
int ratio = (in_utf)?3:1; int ratio = (in_utf(term))?3:1;
int i; int i;
char *p; char *p;
@ -632,7 +633,7 @@ void luni_send(wchar_t * widebuf, int len, int interactive)
linesize = len * ratio * 2; linesize = len * ratio * 2;
} }
if (in_utf) { if (in_utf(term)) {
/* UTF is a simple algorithm */ /* UTF is a simple algorithm */
for (p = linebuffer, i = 0; i < len; i++) { for (p = linebuffer, i = 0; i < len; i++) {
wchar_t ch = widebuf[i]; wchar_t ch = widebuf[i];

View File

@ -18,6 +18,7 @@
#define PUTTY_DO_GLOBALS /* actually _define_ globals */ #define PUTTY_DO_GLOBALS /* actually _define_ globals */
#include "putty.h" #include "putty.h"
#include "terminal.h"
#define CAT2(x,y) x ## y #define CAT2(x,y) x ## y
#define CAT(x,y) CAT2(x,y) #define CAT(x,y) CAT2(x,y)
@ -161,7 +162,7 @@ void set_zorder(int top)
*/ */
void refresh_window(void) void refresh_window(void)
{ {
term_invalidate(); term_invalidate(term);
} }
/* /*
@ -286,7 +287,7 @@ gint configure_area(GtkWidget *widget, GdkEventConfigure *event, gpointer data)
} }
if (need_size) { if (need_size) {
term_size(h, w, cfg.savelines); term_size(term, h, w, cfg.savelines);
} }
return TRUE; return TRUE;
@ -410,11 +411,11 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
* at all. * at all.
*/ */
if (event->keyval == GDK_Page_Up && (event->state & GDK_SHIFT_MASK)) { if (event->keyval == GDK_Page_Up && (event->state & GDK_SHIFT_MASK)) {
term_scroll(0, -cfg.height/2); term_scroll(term, 0, -cfg.height/2);
return TRUE; return TRUE;
} }
if (event->keyval == GDK_Page_Down && (event->state & GDK_SHIFT_MASK)) { if (event->keyval == GDK_Page_Down && (event->state & GDK_SHIFT_MASK)) {
term_scroll(0, +cfg.height/2); term_scroll(term, 0, +cfg.height/2);
return TRUE; return TRUE;
} }
@ -517,7 +518,7 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
/* /*
* Application keypad mode. * Application keypad mode.
*/ */
if (app_keypad_keys && !cfg.no_applic_k) { if (term->app_keypad_keys && !cfg.no_applic_k) {
int xkey = 0; int xkey = 0;
switch (event->keyval) { switch (event->keyval) {
case GDK_Num_Lock: xkey = 'P'; break; case GDK_Num_Lock: xkey = 'P'; break;
@ -555,7 +556,7 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
case GDK_KP_Decimal: case GDK_KP_Delete: xkey = 'n'; break; case GDK_KP_Decimal: case GDK_KP_Delete: xkey = 'n'; break;
} }
if (xkey) { if (xkey) {
if (vt52_mode) { if (term->vt52_mode) {
if (xkey >= 'P' && xkey <= 'S') if (xkey >= 'P' && xkey <= 'S')
end = 1 + sprintf(output+1, "\033%c", xkey); end = 1 + sprintf(output+1, "\033%c", xkey);
else else
@ -663,7 +664,7 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
if (cfg.funky_type == 3 && code <= 6) if (cfg.funky_type == 3 && code <= 6)
code = "\0\2\1\4\5\3\6"[code]; code = "\0\2\1\4\5\3\6"[code];
if (vt52_mode && code > 0 && code <= 6) { if (term->vt52_mode && code > 0 && code <= 6) {
end = 1 + sprintf(output+1, "\x1B%c", " HLMEIG"[code]); end = 1 + sprintf(output+1, "\x1B%c", " HLMEIG"[code]);
goto done; goto done;
} }
@ -702,13 +703,14 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
} }
goto done; goto done;
} }
if ((vt52_mode || cfg.funky_type == 4) && code >= 11 && code <= 24) { if ((term->vt52_mode || cfg.funky_type == 4) &&
code >= 11 && code <= 24) {
int offt = 0; int offt = 0;
if (code > 15) if (code > 15)
offt++; offt++;
if (code > 21) if (code > 21)
offt++; offt++;
if (vt52_mode) if (term->vt52_mode)
end = 1 + sprintf(output+1, end = 1 + sprintf(output+1,
"\x1B%c", code + 'P' - 11 - offt); "\x1B%c", code + 'P' - 11 - offt);
else else
@ -721,7 +723,7 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
goto done; goto done;
} }
if (cfg.funky_type == 2 && code >= 11 && code <= 14) { if (cfg.funky_type == 2 && code >= 11 && code <= 14) {
if (vt52_mode) if (term->vt52_mode)
end = 1 + sprintf(output+1, "\x1B%c", code + 'P' - 11); end = 1 + sprintf(output+1, "\x1B%c", code + 'P' - 11);
else else
end = 1 + sprintf(output+1, "\x1BO%c", code + 'P' - 11); end = 1 + sprintf(output+1, "\x1BO%c", code + 'P' - 11);
@ -759,9 +761,9 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
* app cursor keys mode they do ESC O A instead. * app cursor keys mode they do ESC O A instead.
* Ctrl toggles the two modes. * Ctrl toggles the two modes.
*/ */
if (vt52_mode) { if (term->vt52_mode) {
end = 1 + sprintf(output+1, "\033%c", xkey); end = 1 + sprintf(output+1, "\033%c", xkey);
} else if (!app_cursor_keys ^ } else if (!term->app_cursor_keys ^
!(event->state & GDK_CONTROL_MASK)) { !(event->state & GDK_CONTROL_MASK)) {
end = 1 + sprintf(output+1, "\033O%c", xkey); end = 1 + sprintf(output+1, "\033O%c", xkey);
} else { } else {
@ -786,8 +788,8 @@ gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
ldisc_send(output+start, end-start, 1); ldisc_send(output+start, end-start, 1);
show_mouseptr(0); show_mouseptr(0);
term_seen_key_event(); term_seen_key_event(term);
term_out(); term_out(term);
} }
return TRUE; return TRUE;
@ -801,11 +803,11 @@ gint button_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
show_mouseptr(1); show_mouseptr(1);
if (event->button == 4 && event->type == GDK_BUTTON_PRESS) { if (event->button == 4 && event->type == GDK_BUTTON_PRESS) {
term_scroll(0, -5); term_scroll(term, 0, -5);
return TRUE; return TRUE;
} }
if (event->button == 5 && event->type == GDK_BUTTON_PRESS) { if (event->button == 5 && event->type == GDK_BUTTON_PRESS) {
term_scroll(0, +5); term_scroll(term, 0, +5);
return TRUE; return TRUE;
} }
@ -836,7 +838,7 @@ gint button_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
x = (event->x - cfg.window_border) / inst->font_width; x = (event->x - cfg.window_border) / inst->font_width;
y = (event->y - cfg.window_border) / inst->font_height; y = (event->y - cfg.window_border) / inst->font_height;
term_mouse(button, act, x, y, shift, ctrl, alt); term_mouse(term, button, act, x, y, shift, ctrl, alt);
return TRUE; return TRUE;
} }
@ -863,7 +865,7 @@ gint motion_event(GtkWidget *widget, GdkEventMotion *event, gpointer data)
x = (event->x - cfg.window_border) / inst->font_width; x = (event->x - cfg.window_border) / inst->font_width;
y = (event->y - cfg.window_border) / inst->font_height; y = (event->y - cfg.window_border) / inst->font_height;
term_mouse(button, MA_DRAG, x, y, shift, ctrl, alt); term_mouse(term, button, MA_DRAG, x, y, shift, ctrl, alt);
return TRUE; return TRUE;
} }
@ -885,8 +887,8 @@ gint timer_func(gpointer data)
exit(0); exit(0);
} }
term_update(); term_update(term);
term_blink(0); term_blink(term, 0);
return TRUE; return TRUE;
} }
@ -912,9 +914,9 @@ void pty_input_func(gpointer data, gint sourcefd, GdkInputCondition condition)
exit(1); exit(1);
} }
if (ret > 0) if (ret > 0)
from_backend(0, buf, ret); from_backend(term, 0, buf, ret);
term_blink(1); term_blink(term, 1);
term_out(); term_out(term);
} }
void destroy(GtkWidget *widget, gpointer data) void destroy(GtkWidget *widget, gpointer data)
@ -924,9 +926,9 @@ void destroy(GtkWidget *widget, gpointer data)
gint focus_event(GtkWidget *widget, GdkEventFocus *event, gpointer data) gint focus_event(GtkWidget *widget, GdkEventFocus *event, gpointer data)
{ {
has_focus = event->in; term->has_focus = event->in;
term_out(); term_out(term);
term_update(); term_update(term);
show_mouseptr(1); show_mouseptr(1);
return FALSE; return FALSE;
} }
@ -1100,7 +1102,7 @@ void selection_get(GtkWidget *widget, GtkSelectionData *seldata,
gint selection_clear(GtkWidget *widget, GdkEventSelection *seldata, gint selection_clear(GtkWidget *widget, GdkEventSelection *seldata,
gpointer data) gpointer data)
{ {
term_deselect(); term_deselect(term);
if (inst->pasteout_data) if (inst->pasteout_data)
sfree(inst->pasteout_data); sfree(inst->pasteout_data);
inst->pasteout_data = NULL; inst->pasteout_data = NULL;
@ -1136,9 +1138,9 @@ void selection_received(GtkWidget *widget, GtkSelectionData *seldata,
mb_to_wc(0, 0, seldata->data, seldata->length, mb_to_wc(0, 0, seldata->data, seldata->length,
inst->pastein_data, inst->pastein_data_len); inst->pastein_data, inst->pastein_data_len);
term_do_paste(); term_do_paste(term);
if (term_paste_pending()) if (term_paste_pending(term))
inst->term_paste_idle_id = gtk_idle_add(idle_paste_func, inst); inst->term_paste_idle_id = gtk_idle_add(idle_paste_func, inst);
} }
@ -1146,8 +1148,8 @@ gint idle_paste_func(gpointer data)
{ {
struct gui_data *inst = (struct gui_data *)data; struct gui_data *inst = (struct gui_data *)data;
if (term_paste_pending()) if (term_paste_pending(term))
term_paste(); term_paste(term);
else else
gtk_idle_remove(inst->term_paste_idle_id); gtk_idle_remove(inst->term_paste_idle_id);
@ -1197,7 +1199,7 @@ void scrollbar_moved(GtkAdjustment *adj, gpointer data)
if (!cfg.scrollbar) if (!cfg.scrollbar)
return; return;
if (!inst->ignore_sbar) if (!inst->ignore_sbar)
term_scroll(1, (int)adj->value); term_scroll(term, 1, (int)adj->value);
} }
void sys_cursor(int x, int y) void sys_cursor(int x, int y)
@ -1280,10 +1282,10 @@ void do_text_internal(Context ctx, int x, int y, char *text, int len,
if (lattr != LATTR_NORM) { if (lattr != LATTR_NORM) {
x *= 2; x *= 2;
if (x >= cols) if (x >= term->cols)
return; return;
if (x + len*2 > cols) if (x + len*2 > term->cols)
len = (cols-x)/2; /* trim to LH half */ len = (term->cols-x)/2; /* trim to LH half */
} }
gdk_gc_set_foreground(gc, &inst->cols[nbg]); gdk_gc_set_foreground(gc, &inst->cols[nbg]);
@ -1362,10 +1364,10 @@ void do_text(Context ctx, int x, int y, char *text, int len,
if (lattr != LATTR_NORM) { if (lattr != LATTR_NORM) {
x *= 2; x *= 2;
if (x >= cols) if (x >= term->cols)
return; return;
if (x + len*2 > cols) if (x + len*2 > term->cols)
len = (cols-x)/2; /* trim to LH half */ len = (term->cols-x)/2; /* trim to LH half */
len *= 2; len *= 2;
} }
@ -1395,10 +1397,10 @@ void do_cursor(Context ctx, int x, int y, char *text, int len,
if (lattr != LATTR_NORM) { if (lattr != LATTR_NORM) {
x *= 2; x *= 2;
if (x >= cols) if (x >= term->cols)
return; return;
if (x + len*2 > cols) if (x + len*2 > term->cols)
len = (cols-x)/2; /* trim to LH half */ len = (term->cols-x)/2; /* trim to LH half */
len *= 2; len *= 2;
} }
@ -1875,14 +1877,16 @@ int main(int argc, char **argv)
inst->currcursor = inst->textcursor; inst->currcursor = inst->textcursor;
show_mouseptr(1); show_mouseptr(1);
term = term_init();
back = &pty_backend; back = &pty_backend;
back->init(NULL, 0, NULL, 0); back->init((void *)term, NULL, 0, NULL, 0);
term_size(term, cfg.height, cfg.width, cfg.savelines);
ldisc_send(NULL, 0, 0); /* cause ldisc to notice changes */
gdk_input_add(pty_master_fd, GDK_INPUT_READ, pty_input_func, inst); gdk_input_add(pty_master_fd, GDK_INPUT_READ, pty_input_func, inst);
term_init();
term_size(cfg.height, cfg.width, cfg.savelines);
gtk_main(); gtk_main();
return 0; return 0;

View File

@ -18,6 +18,7 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include "putty.h" #include "putty.h"
#include "terminal.h"
#ifndef FALSE #ifndef FALSE
#define FALSE 0 #define FALSE 0
@ -372,7 +373,8 @@ void pty_pre_init(void)
* Also places the canonical host name into `realhost'. It must be * Also places the canonical host name into `realhost'. It must be
* freed by the caller. * freed by the caller.
*/ */
static char *pty_init(char *host, int port, char **realhost, int nodelay) static char *pty_init(void *frontend,
char *host, int port, char **realhost, int nodelay)
{ {
int slavefd; int slavefd;
pid_t pid, pgrp; pid_t pid, pgrp;
@ -521,10 +523,10 @@ static void pty_size(void)
{ {
struct winsize size; struct winsize size;
size.ws_row = (unsigned short)rows; size.ws_row = (unsigned short)term->rows;
size.ws_col = (unsigned short)cols; size.ws_col = (unsigned short)term->cols;
size.ws_xpixel = (unsigned short) cols * font_dimension(0); size.ws_xpixel = (unsigned short) term->cols * font_dimension(0);
size.ws_ypixel = (unsigned short) rows * font_dimension(1); size.ws_ypixel = (unsigned short) term->rows * font_dimension(1);
ioctl(pty_master_fd, TIOCSWINSZ, (void *)&size); ioctl(pty_master_fd, TIOCSWINSZ, (void *)&size);
return; return;
} }

View File

@ -4,6 +4,7 @@
#include <time.h> #include <time.h>
#include "putty.h" #include "putty.h"
#include "terminal.h"
#include "misc.h" #include "misc.h"
/* /*
@ -22,7 +23,7 @@ void luni_send(wchar_t * widebuf, int len, int interactive)
{ {
static char *linebuffer = 0; static char *linebuffer = 0;
static int linesize = 0; static int linesize = 0;
int ratio = (in_utf)?6:1; int ratio = (in_utf(term))?6:1;
int i; int i;
char *p; char *p;
@ -32,7 +33,7 @@ void luni_send(wchar_t * widebuf, int len, int interactive)
linesize = len * ratio * 2; linesize = len * ratio * 2;
} }
if (in_utf) { if (in_utf(term)) {
/* UTF is a simple algorithm */ /* UTF is a simple algorithm */
for (p = linebuffer, i = 0; i < len; i++) { for (p = linebuffer, i = 0; i < len; i++) {
wchar_t ch = widebuf[i]; wchar_t ch = widebuf[i];

316
window.c
View File

@ -26,6 +26,7 @@
#define PUTTY_DO_GLOBALS /* actually _define_ globals */ #define PUTTY_DO_GLOBALS /* actually _define_ globals */
#include "putty.h" #include "putty.h"
#include "terminal.h"
#include "winstuff.h" #include "winstuff.h"
#include "storage.h" #include "storage.h"
#include "win_res.h" #include "win_res.h"
@ -492,8 +493,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
hwnd = NULL; hwnd = NULL;
savelines = cfg.savelines; term = term_init();
term_init();
cfgtopalette(); cfgtopalette();
@ -508,9 +508,9 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
font_height = 20; font_height = 20;
extra_width = 25; extra_width = 25;
extra_height = 28; extra_height = 28;
term_size(cfg.height, cfg.width, cfg.savelines); term_size(term, cfg.height, cfg.width, cfg.savelines);
guess_width = extra_width + font_width * cols; guess_width = extra_width + font_width * term->cols;
guess_height = extra_height + font_height * rows; guess_height = extra_height + font_height * term->rows;
{ {
RECT r; RECT r;
get_fullscreen_rect(&r); get_fullscreen_rect(&r);
@ -559,8 +559,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
* Resize the window, now we know what size we _really_ want it * Resize the window, now we know what size we _really_ want it
* to be. * to be.
*/ */
guess_width = extra_width + font_width * cols; guess_width = extra_width + font_width * term->cols;
guess_height = extra_height + font_height * rows; guess_height = extra_height + font_height * term->rows;
SetWindowPos(hwnd, NULL, 0, 0, guess_width, guess_height, SetWindowPos(hwnd, NULL, 0, 0, guess_width, guess_height,
SWP_NOMOVE | SWP_NOREDRAW | SWP_NOZORDER); SWP_NOMOVE | SWP_NOREDRAW | SWP_NOZORDER);
@ -586,8 +586,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
si.cbSize = sizeof(si); si.cbSize = sizeof(si);
si.fMask = SIF_ALL | SIF_DISABLENOSCROLL; si.fMask = SIF_ALL | SIF_DISABLENOSCROLL;
si.nMin = 0; si.nMin = 0;
si.nMax = rows - 1; si.nMax = term->rows - 1;
si.nPage = rows; si.nPage = term->rows;
si.nPos = 0; si.nPos = 0;
SetScrollInfo(hwnd, SB_VERT, &si, FALSE); SetScrollInfo(hwnd, SB_VERT, &si, FALSE);
} }
@ -600,7 +600,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
char msg[1024], *title; char msg[1024], *title;
char *realhost; char *realhost;
error = back->init(cfg.host, cfg.port, &realhost, cfg.tcp_nodelay); error = back->init((void *)term,
cfg.host, cfg.port, &realhost, cfg.tcp_nodelay);
if (error) { if (error) {
sprintf(msg, "Unable to open connection to\n" sprintf(msg, "Unable to open connection to\n"
"%.800s\n" "%s", cfg.host, error); "%.800s\n" "%s", cfg.host, error);
@ -706,7 +707,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
logpal = NULL; logpal = NULL;
init_palette(); init_palette();
has_focus = (GetForegroundWindow() == hwnd); term->has_focus = (GetForegroundWindow() == hwnd);
UpdateWindow(hwnd); UpdateWindow(hwnd);
if (GetMessage(&msg, NULL, 0, 0) == 1) { if (GetMessage(&msg, NULL, 0, 0) == 1) {
@ -729,10 +730,10 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
DispatchMessage(&msg); DispatchMessage(&msg);
/* Make sure we blink everything that needs it. */ /* Make sure we blink everything that needs it. */
term_blink(0); term_blink(term, 0);
/* Send the paste buffer if there's anything to send */ /* Send the paste buffer if there's anything to send */
term_paste(); term_paste(term);
/* If there's nothing new in the queue then we can do everything /* If there's nothing new in the queue then we can do everything
* we've delayed, reading the socket, writing, and repainting * we've delayed, reading the socket, writing, and repainting
@ -745,7 +746,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
enact_pending_netevent(); enact_pending_netevent();
/* Force the cursor blink on */ /* Force the cursor blink on */
term_blink(1); term_blink(term, 1);
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
continue; continue;
@ -761,20 +762,21 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
} }
HideCaret(hwnd); HideCaret(hwnd);
if (GetCapture() != hwnd || if (GetCapture() != hwnd ||
(send_raw_mouse && !(cfg.mouse_override && is_shift_pressed()))) (send_raw_mouse &&
term_out(); !(cfg.mouse_override && is_shift_pressed())))
term_update(); term_out(term);
term_update(term);
ShowCaret(hwnd); ShowCaret(hwnd);
flash_window(1); /* maintain */ flash_window(1); /* maintain */
/* The messages seem unreliable; especially if we're being tricky */ /* The messages seem unreliable; especially if we're being tricky */
has_focus = (GetForegroundWindow() == hwnd); term->has_focus = (GetForegroundWindow() == hwnd);
if (in_vbell) if (term->in_vbell)
/* Hmm, term_update didn't want to do an update too soon ... */ /* Hmm, term_update didn't want to do an update too soon ... */
timer_id = SetTimer(hwnd, 1, 50, NULL); timer_id = SetTimer(hwnd, 1, 50, NULL);
else if (!has_focus) else if (!term->has_focus)
timer_id = SetTimer(hwnd, 1, 500, NULL); timer_id = SetTimer(hwnd, 1, 500, NULL);
else else
timer_id = SetTimer(hwnd, 1, 100, NULL); timer_id = SetTimer(hwnd, 1, 100, NULL);
@ -1250,7 +1252,7 @@ void request_resize(int w, int h)
} }
if (cfg.resize_action == RESIZE_DISABLED) return; if (cfg.resize_action == RESIZE_DISABLED) return;
if (h == rows && w == cols) return; if (h == term->rows && w == term->cols) return;
/* Sanity checks ... */ /* Sanity checks ... */
{ {
@ -1280,7 +1282,7 @@ void request_resize(int w, int h)
} }
} }
term_size(h, w, cfg.savelines); term_size(term, h, w, cfg.savelines);
if (cfg.resize_action != RESIZE_FONT && !IsZoomed(hwnd)) { if (cfg.resize_action != RESIZE_FONT && !IsZoomed(hwnd)) {
width = extra_width + font_width * w; width = extra_width + font_width * w;
@ -1334,10 +1336,10 @@ static void reset_window(int reinit) {
/* Is the window out of position ? */ /* Is the window out of position ? */
if ( !reinit && if ( !reinit &&
(offset_width != (win_width-font_width*cols)/2 || (offset_width != (win_width-font_width*term->cols)/2 ||
offset_height != (win_height-font_height*rows)/2) ){ offset_height != (win_height-font_height*term->rows)/2) ){
offset_width = (win_width-font_width*cols)/2; offset_width = (win_width-font_width*term->cols)/2;
offset_height = (win_height-font_height*rows)/2; offset_height = (win_height-font_height*term->rows)/2;
InvalidateRect(hwnd, NULL, TRUE); InvalidateRect(hwnd, NULL, TRUE);
#ifdef RDB_DEBUG_PATCH #ifdef RDB_DEBUG_PATCH
debug((27, "reset_window() -> Reposition terminal")); debug((27, "reset_window() -> Reposition terminal"));
@ -1353,12 +1355,12 @@ static void reset_window(int reinit) {
extra_height = wr.bottom - wr.top - cr.bottom + cr.top; extra_height = wr.bottom - wr.top - cr.bottom + cr.top;
if (cfg.resize_action != RESIZE_TERM) { if (cfg.resize_action != RESIZE_TERM) {
if ( font_width != win_width/cols || if ( font_width != win_width/term->cols ||
font_height != win_height/rows) { font_height != win_height/term->rows) {
deinit_fonts(); deinit_fonts();
init_fonts(win_width/cols, win_height/rows); init_fonts(win_width/term->cols, win_height/term->rows);
offset_width = (win_width-font_width*cols)/2; offset_width = (win_width-font_width*term->cols)/2;
offset_height = (win_height-font_height*rows)/2; offset_height = (win_height-font_height*term->rows)/2;
InvalidateRect(hwnd, NULL, TRUE); InvalidateRect(hwnd, NULL, TRUE);
#ifdef RDB_DEBUG_PATCH #ifdef RDB_DEBUG_PATCH
debug((25, "reset_window() -> Z font resize to (%d, %d)", debug((25, "reset_window() -> Z font resize to (%d, %d)",
@ -1366,15 +1368,15 @@ static void reset_window(int reinit) {
#endif #endif
} }
} else { } else {
if ( font_width != win_width/cols || if ( font_width != win_width/term->cols ||
font_height != win_height/rows) { font_height != win_height/term->rows) {
/* Our only choice at this point is to change the /* Our only choice at this point is to change the
* size of the terminal; Oh well. * size of the terminal; Oh well.
*/ */
term_size( win_height/font_height, win_width/font_width, term_size(term, win_height/font_height, win_width/font_width,
cfg.savelines); cfg.savelines);
offset_width = (win_width-font_width*cols)/2; offset_width = (win_width-font_width*term->cols)/2;
offset_height = (win_height-font_height*rows)/2; offset_height = (win_height-font_height*term->rows)/2;
InvalidateRect(hwnd, NULL, TRUE); InvalidateRect(hwnd, NULL, TRUE);
#ifdef RDB_DEBUG_PATCH #ifdef RDB_DEBUG_PATCH
debug((27, "reset_window() -> Zoomed term_size")); debug((27, "reset_window() -> Zoomed term_size"));
@ -1396,16 +1398,16 @@ static void reset_window(int reinit) {
extra_width = wr.right - wr.left - cr.right + cr.left + offset_width*2; extra_width = wr.right - wr.left - cr.right + cr.left + offset_width*2;
extra_height = wr.bottom - wr.top - cr.bottom + cr.top +offset_height*2; extra_height = wr.bottom - wr.top - cr.bottom + cr.top +offset_height*2;
if (win_width != font_width*cols + offset_width*2 || if (win_width != font_width*term->cols + offset_width*2 ||
win_height != font_height*rows + offset_height*2) { win_height != font_height*term->rows + offset_height*2) {
/* If this is too large windows will resize it to the maximum /* If this is too large windows will resize it to the maximum
* allowed window size, we will then be back in here and resize * allowed window size, we will then be back in here and resize
* the font or terminal to fit. * the font or terminal to fit.
*/ */
SetWindowPos(hwnd, NULL, 0, 0, SetWindowPos(hwnd, NULL, 0, 0,
font_width*cols + extra_width, font_width*term->cols + extra_width,
font_height*rows + extra_height, font_height*term->rows + extra_height,
SWP_NOMOVE | SWP_NOZORDER); SWP_NOMOVE | SWP_NOZORDER);
} }
@ -1424,8 +1426,8 @@ static void reset_window(int reinit) {
extra_width = wr.right - wr.left - cr.right + cr.left + offset_width*2; extra_width = wr.right - wr.left - cr.right + cr.left + offset_width*2;
extra_height = wr.bottom - wr.top - cr.bottom + cr.top +offset_height*2; extra_height = wr.bottom - wr.top - cr.bottom + cr.top +offset_height*2;
if (win_width != font_width*cols + offset_width*2 || if (win_width != font_width*term->cols + offset_width*2 ||
win_height != font_height*rows + offset_height*2) { win_height != font_height*term->rows + offset_height*2) {
static RECT ss; static RECT ss;
int width, height; int width, height;
@ -1436,13 +1438,15 @@ static void reset_window(int reinit) {
height = (ss.bottom - ss.top - extra_height) / font_height; height = (ss.bottom - ss.top - extra_height) / font_height;
/* Grrr too big */ /* Grrr too big */
if ( rows > height || cols > width ) { if ( term->rows > height || term->cols > width ) {
if (cfg.resize_action == RESIZE_EITHER) { if (cfg.resize_action == RESIZE_EITHER) {
/* Make the font the biggest we can */ /* Make the font the biggest we can */
if (cols > width) if (term->cols > width)
font_width = (ss.right - ss.left - extra_width)/cols; font_width = (ss.right - ss.left - extra_width)
if (rows > height) / term->cols;
font_height = (ss.bottom - ss.top - extra_height)/rows; if (term->rows > height)
font_height = (ss.bottom - ss.top - extra_height)
/ term->rows;
deinit_fonts(); deinit_fonts();
init_fonts(font_width, font_height); init_fonts(font_width, font_height);
@ -1450,9 +1454,9 @@ static void reset_window(int reinit) {
width = (ss.right - ss.left - extra_width) / font_width; width = (ss.right - ss.left - extra_width) / font_width;
height = (ss.bottom - ss.top - extra_height) / font_height; height = (ss.bottom - ss.top - extra_height) / font_height;
} else { } else {
if ( height > rows ) height = rows; if ( height > term->rows ) height = term->rows;
if ( width > cols ) width = cols; if ( width > term->cols ) width = term->cols;
term_size(height, width, cfg.savelines); term_size(term, height, width, cfg.savelines);
#ifdef RDB_DEBUG_PATCH #ifdef RDB_DEBUG_PATCH
debug((27, "reset_window() -> term resize to (%d,%d)", debug((27, "reset_window() -> term resize to (%d,%d)",
height, width)); height, width));
@ -1461,15 +1465,15 @@ static void reset_window(int reinit) {
} }
SetWindowPos(hwnd, NULL, 0, 0, SetWindowPos(hwnd, NULL, 0, 0,
font_width*cols + extra_width, font_width*term->cols + extra_width,
font_height*rows + extra_height, font_height*term->rows + extra_height,
SWP_NOMOVE | SWP_NOZORDER); SWP_NOMOVE | SWP_NOZORDER);
InvalidateRect(hwnd, NULL, TRUE); InvalidateRect(hwnd, NULL, TRUE);
#ifdef RDB_DEBUG_PATCH #ifdef RDB_DEBUG_PATCH
debug((27, "reset_window() -> window resize to (%d,%d)", debug((27, "reset_window() -> window resize to (%d,%d)",
font_width*cols + extra_width, font_width*term->cols + extra_width,
font_height*rows + extra_height)); font_height*term->rows + extra_height));
#endif #endif
} }
return; return;
@ -1477,14 +1481,14 @@ static void reset_window(int reinit) {
/* We're allowed to or must change the font but do we want to ? */ /* We're allowed to or must change the font but do we want to ? */
if (font_width != (win_width-cfg.window_border*2)/cols || if (font_width != (win_width-cfg.window_border*2)/term->cols ||
font_height != (win_height-cfg.window_border*2)/rows) { font_height != (win_height-cfg.window_border*2)/term->rows) {
deinit_fonts(); deinit_fonts();
init_fonts((win_width-cfg.window_border*2)/cols, init_fonts((win_width-cfg.window_border*2)/term->cols,
(win_height-cfg.window_border*2)/rows); (win_height-cfg.window_border*2)/term->rows);
offset_width = (win_width-font_width*cols)/2; offset_width = (win_width-font_width*term->cols)/2;
offset_height = (win_height-font_height*rows)/2; offset_height = (win_height-font_height*term->rows)/2;
extra_width = wr.right - wr.left - cr.right + cr.left +offset_width*2; extra_width = wr.right - wr.left - cr.right + cr.left +offset_width*2;
extra_height = wr.bottom - wr.top - cr.bottom + cr.top+offset_height*2; extra_height = wr.bottom - wr.top - cr.bottom + cr.top+offset_height*2;
@ -1513,7 +1517,7 @@ static void click(Mouse_Button b, int x, int y, int shift, int ctrl, int alt)
if (send_raw_mouse && !(cfg.mouse_override && shift)) { if (send_raw_mouse && !(cfg.mouse_override && shift)) {
lastbtn = MBT_NOTHING; lastbtn = MBT_NOTHING;
term_mouse(b, MA_CLICK, x, y, shift, ctrl, alt); term_mouse(term, b, MA_CLICK, x, y, shift, ctrl, alt);
return; return;
} }
@ -1526,7 +1530,7 @@ static void click(Mouse_Button b, int x, int y, int shift, int ctrl, int alt)
lastact = MA_CLICK; lastact = MA_CLICK;
} }
if (lastact != MA_NOTHING) if (lastact != MA_NOTHING)
term_mouse(b, lastact, x, y, shift, ctrl, alt); term_mouse(term, b, lastact, x, y, shift, ctrl, alt);
lasttime = thistime; lasttime = thistime;
} }
@ -1597,10 +1601,10 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
enact_pending_netevent(); enact_pending_netevent();
if (GetCapture() != hwnd || if (GetCapture() != hwnd ||
(send_raw_mouse && !(cfg.mouse_override && is_shift_pressed()))) (send_raw_mouse && !(cfg.mouse_override && is_shift_pressed())))
term_out(); term_out(term);
noise_regular(); noise_regular();
HideCaret(hwnd); HideCaret(hwnd);
term_update(); term_update(term);
ShowCaret(hwnd); ShowCaret(hwnd);
if (cfg.ping_interval > 0) { if (cfg.ping_interval > 0) {
time_t now; time_t now;
@ -1748,7 +1752,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
init_palette(); init_palette();
/* Give terminal a heads-up on miscellaneous stuff */ /* Give terminal a heads-up on miscellaneous stuff */
term_reconfig(); term_reconfig(term);
/* Screen size changed ? */ /* Screen size changed ? */
if (cfg.height != prev_cfg.height || if (cfg.height != prev_cfg.height ||
@ -1757,7 +1761,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
cfg.resize_action == RESIZE_FONT || cfg.resize_action == RESIZE_FONT ||
(cfg.resize_action == RESIZE_EITHER && IsZoomed(hwnd)) || (cfg.resize_action == RESIZE_EITHER && IsZoomed(hwnd)) ||
cfg.resize_action == RESIZE_DISABLED) cfg.resize_action == RESIZE_DISABLED)
term_size(cfg.height, cfg.width, cfg.savelines); term_size(term, cfg.height, cfg.width, cfg.savelines);
/* Enable or disable the scroll bar, etc */ /* Enable or disable the scroll bar, etc */
{ {
@ -1846,13 +1850,14 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
} }
break; break;
case IDM_COPYALL: case IDM_COPYALL:
term_copyall(); term_copyall(term);
break; break;
case IDM_CLRSB: case IDM_CLRSB:
term_clrsb(); term_clrsb(term);
break; break;
case IDM_RESET: case IDM_RESET:
term_pwron(); term_pwron(term);
ldisc_send(NULL, 0, 0);
break; break;
case IDM_TEL_AYT: case IDM_TEL_AYT:
back->special(TS_AYT); back->special(TS_AYT);
@ -2004,7 +2009,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
is_alt_pressed()); is_alt_pressed());
SetCapture(hwnd); SetCapture(hwnd);
} else { } else {
term_mouse(button, MA_RELEASE, term_mouse(term, button, MA_RELEASE,
TO_CHR_X(X_POS(lParam)), TO_CHR_X(X_POS(lParam)),
TO_CHR_Y(Y_POS(lParam)), wParam & MK_SHIFT, TO_CHR_Y(Y_POS(lParam)), wParam & MK_SHIFT,
wParam & MK_CONTROL, is_alt_pressed()); wParam & MK_CONTROL, is_alt_pressed());
@ -2029,7 +2034,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
b = MBT_MIDDLE; b = MBT_MIDDLE;
else else
b = MBT_RIGHT; b = MBT_RIGHT;
term_mouse(b, MA_DRAG, TO_CHR_X(X_POS(lParam)), term_mouse(term, b, MA_DRAG, TO_CHR_X(X_POS(lParam)),
TO_CHR_Y(Y_POS(lParam)), wParam & MK_SHIFT, TO_CHR_Y(Y_POS(lParam)), wParam & MK_SHIFT,
wParam & MK_CONTROL, is_alt_pressed()); wParam & MK_CONTROL, is_alt_pressed());
} }
@ -2043,7 +2048,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
break; break;
case WM_DESTROYCLIPBOARD: case WM_DESTROYCLIPBOARD:
if (!ignore_clip) if (!ignore_clip)
term_deselect(); term_deselect(term);
ignore_clip = FALSE; ignore_clip = FALSE;
return 0; return 0;
case WM_PAINT: case WM_PAINT:
@ -2055,7 +2060,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
SelectPalette(hdc, pal, TRUE); SelectPalette(hdc, pal, TRUE);
RealizePalette(hdc); RealizePalette(hdc);
} }
term_paint(hdc, term_paint(term, hdc,
(p.rcPaint.left-offset_width)/font_width, (p.rcPaint.left-offset_width)/font_width,
(p.rcPaint.top-offset_height)/font_height, (p.rcPaint.top-offset_height)/font_height,
(p.rcPaint.right-offset_width-1)/font_width, (p.rcPaint.right-offset_width-1)/font_width,
@ -2064,8 +2069,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
if (p.fErase || if (p.fErase ||
p.rcPaint.left < offset_width || p.rcPaint.left < offset_width ||
p.rcPaint.top < offset_height || p.rcPaint.top < offset_height ||
p.rcPaint.right >= offset_width + font_width*cols || p.rcPaint.right >= offset_width + font_width*term->cols ||
p.rcPaint.bottom>= offset_height + font_height*rows) p.rcPaint.bottom>= offset_height + font_height*term->rows)
{ {
HBRUSH fillcolour, oldbrush; HBRUSH fillcolour, oldbrush;
HPEN edge, oldpen; HPEN edge, oldpen;
@ -2089,8 +2094,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
ExcludeClipRect(hdc, ExcludeClipRect(hdc,
offset_width, offset_height, offset_width, offset_height,
offset_width+font_width*cols, offset_width+font_width*term->cols,
offset_height+font_height*rows); offset_height+font_height*term->rows);
Rectangle(hdc, p.rcPaint.left, p.rcPaint.top, Rectangle(hdc, p.rcPaint.left, p.rcPaint.top,
p.rcPaint.right, p.rcPaint.bottom); p.rcPaint.right, p.rcPaint.bottom);
@ -2125,21 +2130,21 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
time(&last_movement); time(&last_movement);
return 0; return 0;
case WM_SETFOCUS: case WM_SETFOCUS:
has_focus = TRUE; term->has_focus = TRUE;
CreateCaret(hwnd, caretbm, font_width, font_height); CreateCaret(hwnd, caretbm, font_width, font_height);
ShowCaret(hwnd); ShowCaret(hwnd);
flash_window(0); /* stop */ flash_window(0); /* stop */
compose_state = 0; compose_state = 0;
term_out(); term_out(term);
term_update(); term_update(term);
break; break;
case WM_KILLFOCUS: case WM_KILLFOCUS:
show_mouseptr(1); show_mouseptr(1);
has_focus = FALSE; term->has_focus = FALSE;
DestroyCaret(); DestroyCaret();
caret_x = caret_y = -1; /* ensure caret is replaced next time */ caret_x = caret_y = -1; /* ensure caret is replaced next time */
term_out(); term_out(term);
term_update(); term_update(term);
break; break;
case WM_ENTERSIZEMOVE: case WM_ENTERSIZEMOVE:
#ifdef RDB_DEBUG_PATCH #ifdef RDB_DEBUG_PATCH
@ -2156,7 +2161,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
debug((27, "WM_EXITSIZEMOVE")); debug((27, "WM_EXITSIZEMOVE"));
#endif #endif
if (need_backend_resize) { if (need_backend_resize) {
term_size(cfg.height, cfg.width, cfg.savelines); term_size(term, cfg.height, cfg.width, cfg.savelines);
InvalidateRect(hwnd, NULL, TRUE); InvalidateRect(hwnd, NULL, TRUE);
} }
break; break;
@ -2171,7 +2176,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
LPRECT r = (LPRECT) lParam; LPRECT r = (LPRECT) lParam;
if ( !need_backend_resize && cfg.resize_action == RESIZE_EITHER && if ( !need_backend_resize && cfg.resize_action == RESIZE_EITHER &&
(cfg.height != rows || cfg.width != cols )) { (cfg.height != term->rows || cfg.width != term->cols )) {
/* /*
* Great! It seems that both the terminal size and the * Great! It seems that both the terminal size and the
* font size have been changed and the user is now dragging. * font size have been changed and the user is now dragging.
@ -2181,10 +2186,10 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
* *
* This would be easier but it seems to be too confusing. * This would be easier but it seems to be too confusing.
term_size(cfg.height, cfg.width, cfg.savelines); term_size(term, cfg.height, cfg.width, cfg.savelines);
reset_window(2); reset_window(2);
*/ */
cfg.height=rows; cfg.width=cols; cfg.height=term->rows; cfg.width=term->cols;
InvalidateRect(hwnd, NULL, TRUE); InvalidateRect(hwnd, NULL, TRUE);
need_backend_resize = TRUE; need_backend_resize = TRUE;
@ -2228,25 +2233,25 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
width = r->right - r->left - ex_width; width = r->right - r->left - ex_width;
height = r->bottom - r->top - ex_height; height = r->bottom - r->top - ex_height;
w = (width + cols/2)/cols; w = (width + term->cols/2)/term->cols;
h = (height + rows/2)/rows; h = (height + term->rows/2)/term->rows;
if ( r->right != r->left + w*cols + ex_width) if ( r->right != r->left + w*term->cols + ex_width)
rv = 1; rv = 1;
if (wParam == WMSZ_LEFT || if (wParam == WMSZ_LEFT ||
wParam == WMSZ_BOTTOMLEFT || wParam == WMSZ_TOPLEFT) wParam == WMSZ_BOTTOMLEFT || wParam == WMSZ_TOPLEFT)
r->left = r->right - w*cols - ex_width; r->left = r->right - w*term->cols - ex_width;
else else
r->right = r->left + w*cols + ex_width; r->right = r->left + w*term->cols + ex_width;
if (r->bottom != r->top + h*rows + ex_height) if (r->bottom != r->top + h*term->rows + ex_height)
rv = 1; rv = 1;
if (wParam == WMSZ_TOP || if (wParam == WMSZ_TOP ||
wParam == WMSZ_TOPRIGHT || wParam == WMSZ_TOPLEFT) wParam == WMSZ_TOPRIGHT || wParam == WMSZ_TOPLEFT)
r->top = r->bottom - h*rows - ex_height; r->top = r->bottom - h*term->rows - ex_height;
else else
r->bottom = r->top + h*rows + ex_height; r->bottom = r->top + h*term->rows + ex_height;
return rv; return rv;
} }
@ -2292,21 +2297,21 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
if (!resizing) { if (!resizing) {
if (wParam == SIZE_MAXIMIZED && !was_zoomed) { if (wParam == SIZE_MAXIMIZED && !was_zoomed) {
was_zoomed = 1; was_zoomed = 1;
prev_rows = rows; prev_rows = term->rows;
prev_cols = cols; prev_cols = term->cols;
if (cfg.resize_action == RESIZE_TERM) { if (cfg.resize_action == RESIZE_TERM) {
w = width / font_width; w = width / font_width;
if (w < 1) w = 1; if (w < 1) w = 1;
h = height / font_height; h = height / font_height;
if (h < 1) h = 1; if (h < 1) h = 1;
term_size(h, w, cfg.savelines); term_size(term, h, w, cfg.savelines);
} }
reset_window(0); reset_window(0);
} else if (wParam == SIZE_RESTORED && was_zoomed) { } else if (wParam == SIZE_RESTORED && was_zoomed) {
was_zoomed = 0; was_zoomed = 0;
if (cfg.resize_action == RESIZE_TERM) if (cfg.resize_action == RESIZE_TERM)
term_size(prev_rows, prev_cols, cfg.savelines); term_size(term, prev_rows, prev_cols, cfg.savelines);
if (cfg.resize_action != RESIZE_FONT) if (cfg.resize_action != RESIZE_FONT)
reset_window(2); reset_window(2);
else else
@ -2345,26 +2350,26 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
case WM_VSCROLL: case WM_VSCROLL:
switch (LOWORD(wParam)) { switch (LOWORD(wParam)) {
case SB_BOTTOM: case SB_BOTTOM:
term_scroll(-1, 0); term_scroll(term, -1, 0);
break; break;
case SB_TOP: case SB_TOP:
term_scroll(+1, 0); term_scroll(term, +1, 0);
break; break;
case SB_LINEDOWN: case SB_LINEDOWN:
term_scroll(0, +1); term_scroll(term, 0, +1);
break; break;
case SB_LINEUP: case SB_LINEUP:
term_scroll(0, -1); term_scroll(term, 0, -1);
break; break;
case SB_PAGEDOWN: case SB_PAGEDOWN:
term_scroll(0, +rows / 2); term_scroll(term, 0, +term->rows / 2);
break; break;
case SB_PAGEUP: case SB_PAGEUP:
term_scroll(0, -rows / 2); term_scroll(term, 0, -term->rows / 2);
break; break;
case SB_THUMBPOSITION: case SB_THUMBPOSITION:
case SB_THUMBTRACK: case SB_THUMBTRACK:
term_scroll(1, HIWORD(wParam)); term_scroll(term, 1, HIWORD(wParam));
break; break;
} }
break; break;
@ -2429,7 +2434,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
* preferable to having to faff about buffering * preferable to having to faff about buffering
* things. * things.
*/ */
term_nopaste(); term_nopaste(term);
/* /*
* We need not bother about stdin backlogs * We need not bother about stdin backlogs
@ -2439,7 +2444,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
* messages. We _have_ to buffer everything * messages. We _have_ to buffer everything
* we're sent. * we're sent.
*/ */
term_seen_key_event(); term_seen_key_event(term);
ldisc_send(buf, len, 1); ldisc_send(buf, len, 1);
show_mouseptr(0); show_mouseptr(0);
} }
@ -2486,7 +2491,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
* luni_send() covering the whole of buff. So * luni_send() covering the whole of buff. So
* instead we luni_send the characters one by one. * instead we luni_send the characters one by one.
*/ */
term_seen_key_event(); term_seen_key_event(term);
for (i = 0; i < n; i += 2) { for (i = 0; i < n; i += 2) {
luni_send((unsigned short *)(buff+i), 1, 1); luni_send((unsigned short *)(buff+i), 1, 1);
} }
@ -2502,11 +2507,11 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
buf[1] = wParam; buf[1] = wParam;
buf[0] = wParam >> 8; buf[0] = wParam >> 8;
term_seen_key_event(); term_seen_key_event(term);
lpage_send(kbd_codepage, buf, 2, 1); lpage_send(kbd_codepage, buf, 2, 1);
} else { } else {
char c = (unsigned char) wParam; char c = (unsigned char) wParam;
term_seen_key_event(); term_seen_key_event(term);
lpage_send(kbd_codepage, &c, 1, 1); lpage_send(kbd_codepage, &c, 1, 1);
} }
return (0); return (0);
@ -2520,7 +2525,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
*/ */
{ {
char c = (unsigned char)wParam; char c = (unsigned char)wParam;
term_seen_key_event(); term_seen_key_event(term);
lpage_send(CP_ACP, &c, 1, 1); lpage_send(CP_ACP, &c, 1, 1);
} }
return 0; return 0;
@ -2563,18 +2568,19 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
if (send_raw_mouse && if (send_raw_mouse &&
!(cfg.mouse_override && shift_pressed)) { !(cfg.mouse_override && shift_pressed)) {
/* send a mouse-down followed by a mouse up */ /* send a mouse-down followed by a mouse up */
term_mouse(b, term_mouse(term, b,
MA_CLICK, MA_CLICK,
TO_CHR_X(X_POS(lParam)), TO_CHR_X(X_POS(lParam)),
TO_CHR_Y(Y_POS(lParam)), shift_pressed, TO_CHR_Y(Y_POS(lParam)), shift_pressed,
control_pressed, is_alt_pressed()); control_pressed, is_alt_pressed());
term_mouse(b, MA_RELEASE, TO_CHR_X(X_POS(lParam)), term_mouse(term, b, MA_RELEASE, TO_CHR_X(X_POS(lParam)),
TO_CHR_Y(Y_POS(lParam)), shift_pressed, TO_CHR_Y(Y_POS(lParam)), shift_pressed,
control_pressed, is_alt_pressed()); control_pressed, is_alt_pressed());
} else { } else {
/* trigger a scroll */ /* trigger a scroll */
term_scroll(0, term_scroll(term, 0,
b == MBT_WHEEL_UP ? -rows / 2 : rows / 2); b == MBT_WHEEL_UP ?
-term->rows / 2 : term->rows / 2);
} }
} }
return 0; return 0;
@ -2594,7 +2600,7 @@ void sys_cursor(int x, int y)
{ {
int cx, cy; int cx, cy;
if (!has_focus) return; if (!term->has_focus) return;
/* /*
* Avoid gratuitously re-updating the cursor position and IMM * Avoid gratuitously re-updating the cursor position and IMM
@ -2615,7 +2621,7 @@ static void sys_cursor_update(void)
COMPOSITIONFORM cf; COMPOSITIONFORM cf;
HIMC hIMC; HIMC hIMC;
if (!has_focus) return; if (!term->has_focus) return;
if (caret_x < 0 || caret_y < 0) if (caret_x < 0 || caret_y < 0)
return; return;
@ -2672,7 +2678,7 @@ void do_text(Context ctx, int x, int y, char *text, int len,
} }
/* Only want the left half of double width lines */ /* Only want the left half of double width lines */
if (lattr != LATTR_NORM && x*2 >= cols) if (lattr != LATTR_NORM && x*2 >= term->cols)
return; return;
x *= fnt_width; x *= fnt_width;
@ -2680,7 +2686,7 @@ void do_text(Context ctx, int x, int y, char *text, int len,
x += offset_width; x += offset_width;
y += offset_height; y += offset_height;
if ((attr & TATTR_ACTCURS) && (cfg.cursor_type == 0 || big_cursor)) { if ((attr & TATTR_ACTCURS) && (cfg.cursor_type == 0 || term->big_cursor)) {
attr &= ATTR_CUR_AND | (bold_mode != BOLD_COLOURS ? ATTR_BOLD : 0); attr &= ATTR_CUR_AND | (bold_mode != BOLD_COLOURS ? ATTR_BOLD : 0);
attr ^= ATTR_CUR_XOR; attr ^= ATTR_CUR_XOR;
} }
@ -2781,8 +2787,8 @@ void do_text(Context ctx, int x, int y, char *text, int len,
line_box.bottom = y + font_height; line_box.bottom = y + font_height;
/* Only want the left half of double width lines */ /* Only want the left half of double width lines */
if (line_box.right > font_width*cols+offset_width) if (line_box.right > font_width*term->cols+offset_width)
line_box.right = font_width*cols+offset_width; line_box.right = font_width*term->cols+offset_width;
/* We're using a private area for direct to font. (512 chars.) */ /* We're using a private area for direct to font. (512 chars.) */
if (dbcs_screenfont && (attr & CSET_MASK) == ATTR_ACP) { if (dbcs_screenfont && (attr & CSET_MASK) == ATTR_ACP) {
@ -2896,7 +2902,7 @@ void do_cursor(Context ctx, int x, int y, char *text, int len,
HDC hdc = ctx; HDC hdc = ctx;
int ctype = cfg.cursor_type; int ctype = cfg.cursor_type;
if ((attr & TATTR_ACTCURS) && (ctype == 0 || big_cursor)) { if ((attr & TATTR_ACTCURS) && (ctype == 0 || term->big_cursor)) {
if (((attr & CSET_MASK) | (unsigned char) *text) != UCSWIDE) { if (((attr & CSET_MASK) | (unsigned char) *text) != UCSWIDE) {
do_text(ctx, x, y, text, len, attr, lattr); do_text(ctx, x, y, text, len, attr, lattr);
return; return;
@ -2913,7 +2919,7 @@ void do_cursor(Context ctx, int x, int y, char *text, int len,
x += offset_width; x += offset_width;
y += offset_height; y += offset_height;
if ((attr & TATTR_PASCURS) && (ctype == 0 || big_cursor)) { if ((attr & TATTR_PASCURS) && (ctype == 0 || term->big_cursor)) {
POINT pts[5]; POINT pts[5];
HPEN oldpen; HPEN oldpen;
pts[0].x = pts[1].x = pts[4].x = x; pts[0].x = pts[1].x = pts[4].x = x;
@ -3129,7 +3135,8 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
/* Nastyness with NUMLock - Shift-NUMLock is left alone though */ /* Nastyness with NUMLock - Shift-NUMLock is left alone though */
if ((cfg.funky_type == 3 || if ((cfg.funky_type == 3 ||
(cfg.funky_type <= 1 && app_keypad_keys && !cfg.no_applic_k)) (cfg.funky_type <= 1 && term->app_keypad_keys &&
!cfg.no_applic_k))
&& wParam == VK_NUMLOCK && !(keystate[VK_SHIFT] & 0x80)) { && wParam == VK_NUMLOCK && !(keystate[VK_SHIFT] & 0x80)) {
wParam = VK_EXECUTE; wParam = VK_EXECUTE;
@ -3144,7 +3151,8 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
} }
/* Disable Auto repeat if required */ /* Disable Auto repeat if required */
if (repeat_off && (HIWORD(lParam) & (KF_UP | KF_REPEAT)) == KF_REPEAT) if (term->repeat_off &&
(HIWORD(lParam) & (KF_UP | KF_REPEAT)) == KF_REPEAT)
return 0; return 0;
if ((HIWORD(lParam) & KF_ALTDOWN) && (keystate[VK_RMENU] & 0x80) == 0) if ((HIWORD(lParam) & KF_ALTDOWN) && (keystate[VK_RMENU] & 0x80) == 0)
@ -3194,7 +3202,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
compose_state = 0; compose_state = 0;
/* Sanitize the number pad if not using a PC NumPad */ /* Sanitize the number pad if not using a PC NumPad */
if (left_alt || (app_keypad_keys && !cfg.no_applic_k if (left_alt || (term->app_keypad_keys && !cfg.no_applic_k
&& cfg.funky_type != 2) && cfg.funky_type != 2)
|| cfg.funky_type == 3 || cfg.nethack_keypad || compose_state) { || cfg.funky_type == 3 || cfg.nethack_keypad || compose_state) {
if ((HIWORD(lParam) & KF_EXTENDED) == 0) { if ((HIWORD(lParam) & KF_EXTENDED) == 0) {
@ -3258,7 +3266,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
return 0; return 0;
} }
if (wParam == VK_INSERT && shift_state == 1) { if (wParam == VK_INSERT && shift_state == 1) {
term_do_paste(); term_do_paste(term);
return 0; return 0;
} }
if (left_alt && wParam == VK_F4 && cfg.alt_f4) { if (left_alt && wParam == VK_F4 && cfg.alt_f4) {
@ -3276,7 +3284,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
} }
/* Control-Numlock for app-keypad mode switch */ /* Control-Numlock for app-keypad mode switch */
if (wParam == VK_PAUSE && shift_state == 2) { if (wParam == VK_PAUSE && shift_state == 2) {
app_keypad_keys ^= 1; term->app_keypad_keys ^= 1;
return 0; return 0;
} }
@ -3319,7 +3327,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
if (cfg.funky_type == 3 || if (cfg.funky_type == 3 ||
(cfg.funky_type <= 1 && (cfg.funky_type <= 1 &&
app_keypad_keys && !cfg.no_applic_k)) switch (wParam) { term->app_keypad_keys && !cfg.no_applic_k)) switch (wParam) {
case VK_EXECUTE: case VK_EXECUTE:
xkey = 'P'; xkey = 'P';
break; break;
@ -3333,7 +3341,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
xkey = 'S'; xkey = 'S';
break; break;
} }
if (app_keypad_keys && !cfg.no_applic_k) if (term->app_keypad_keys && !cfg.no_applic_k)
switch (wParam) { switch (wParam) {
case VK_NUMPAD0: case VK_NUMPAD0:
xkey = 'p'; xkey = 'p';
@ -3400,7 +3408,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
break; break;
} }
if (xkey) { if (xkey) {
if (vt52_mode) { if (term->vt52_mode) {
if (xkey >= 'P' && xkey <= 'S') if (xkey >= 'P' && xkey <= 'S')
p += sprintf((char *) p, "\x1B%c", xkey); p += sprintf((char *) p, "\x1B%c", xkey);
else else
@ -3459,7 +3467,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
*p++ = 0x1C; *p++ = 0x1C;
return p - output; return p - output;
} }
if (shift_state == 0 && wParam == VK_RETURN && cr_lf_return) { if (shift_state == 0 && wParam == VK_RETURN && term->cr_lf_return) {
*p++ = '\r'; *p++ = '\r';
*p++ = '\n'; *p++ = '\n';
return p - output; return p - output;
@ -3561,7 +3569,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
if (cfg.funky_type == 3 && code <= 6) if (cfg.funky_type == 3 && code <= 6)
code = "\0\2\1\4\5\3\6"[code]; code = "\0\2\1\4\5\3\6"[code];
if (vt52_mode && code > 0 && code <= 6) { if (term->vt52_mode && code > 0 && code <= 6) {
p += sprintf((char *) p, "\x1B%c", " HLMEIG"[code]); p += sprintf((char *) p, "\x1B%c", " HLMEIG"[code]);
return p - output; return p - output;
} }
@ -3599,13 +3607,13 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
} }
return p - output; return p - output;
} }
if ((vt52_mode || cfg.funky_type == 4) && code >= 11 && code <= 24) { if ((term->vt52_mode || cfg.funky_type == 4) && code >= 11 && code <= 24) {
int offt = 0; int offt = 0;
if (code > 15) if (code > 15)
offt++; offt++;
if (code > 21) if (code > 21)
offt++; offt++;
if (vt52_mode) if (term->vt52_mode)
p += sprintf((char *) p, "\x1B%c", code + 'P' - 11 - offt); p += sprintf((char *) p, "\x1B%c", code + 'P' - 11 - offt);
else else
p += p +=
@ -3617,7 +3625,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
return p - output; return p - output;
} }
if (cfg.funky_type == 2 && code >= 11 && code <= 14) { if (cfg.funky_type == 2 && code >= 11 && code <= 14) {
if (vt52_mode) if (term->vt52_mode)
p += sprintf((char *) p, "\x1B%c", code + 'P' - 11); p += sprintf((char *) p, "\x1B%c", code + 'P' - 11);
else else
p += sprintf((char *) p, "\x1BO%c", code + 'P' - 11); p += sprintf((char *) p, "\x1BO%c", code + 'P' - 11);
@ -3656,10 +3664,10 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
break; break;
} }
if (xkey) { if (xkey) {
if (vt52_mode) if (term->vt52_mode)
p += sprintf((char *) p, "\x1B%c", xkey); p += sprintf((char *) p, "\x1B%c", xkey);
else { else {
int app_flg = (app_cursor_keys && !cfg.no_applic_c); int app_flg = (term->app_cursor_keys && !cfg.no_applic_c);
#if 0 #if 0
/* /*
* RDB: VT100 & VT102 manuals both state the * RDB: VT100 & VT102 manuals both state the
@ -3675,7 +3683,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
* _this_ I'll have to put in a configurable * _this_ I'll have to put in a configurable
* option. * option.
*/ */
if (!app_keypad_keys) if (!term->app_keypad_keys)
app_flg = 0; app_flg = 0;
#endif #endif
/* Useful mapping of Ctrl-arrows */ /* Useful mapping of Ctrl-arrows */
@ -3722,7 +3730,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
#ifdef SHOW_TOASCII_RESULT #ifdef SHOW_TOASCII_RESULT
if (r == 1 && !key_down) { if (r == 1 && !key_down) {
if (alt_sum) { if (alt_sum) {
if (in_utf || dbcs_screenfont) if (in_utf(term) || dbcs_screenfont)
debug((", (U+%04x)", alt_sum)); debug((", (U+%04x)", alt_sum));
else else
debug((", LCH(%d)", alt_sum)); debug((", LCH(%d)", alt_sum));
@ -3746,7 +3754,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
* sensible, but for the moment it's preferable to * sensible, but for the moment it's preferable to
* having to faff about buffering things. * having to faff about buffering things.
*/ */
term_nopaste(); term_nopaste(term);
p = output; p = output;
for (i = 0; i < r; i++) { for (i = 0; i < r; i++) {
@ -3766,7 +3774,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
return 0; return 0;
} }
keybuf = nc; keybuf = nc;
term_seen_key_event(); term_seen_key_event(term);
luni_send(&keybuf, 1, 1); luni_send(&keybuf, 1, 1);
continue; continue;
} }
@ -3775,9 +3783,9 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
if (!key_down) { if (!key_down) {
if (alt_sum) { if (alt_sum) {
if (in_utf || dbcs_screenfont) { if (in_utf(term) || dbcs_screenfont) {
keybuf = alt_sum; keybuf = alt_sum;
term_seen_key_event(); term_seen_key_event(term);
luni_send(&keybuf, 1, 1); luni_send(&keybuf, 1, 1);
} else { } else {
ch = (char) alt_sum; ch = (char) alt_sum;
@ -3790,25 +3798,25 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
* messages. We _have_ to buffer * messages. We _have_ to buffer
* everything we're sent. * everything we're sent.
*/ */
term_seen_key_event(); term_seen_key_event(term);
ldisc_send(&ch, 1, 1); ldisc_send(&ch, 1, 1);
} }
alt_sum = 0; alt_sum = 0;
} else } else
term_seen_key_event(); term_seen_key_event(term);
lpage_send(kbd_codepage, &ch, 1, 1); lpage_send(kbd_codepage, &ch, 1, 1);
} else { } else {
if(capsOn && ch < 0x80) { if(capsOn && ch < 0x80) {
WCHAR cbuf[2]; WCHAR cbuf[2];
cbuf[0] = 27; cbuf[0] = 27;
cbuf[1] = xlat_uskbd2cyrllic(ch); cbuf[1] = xlat_uskbd2cyrllic(ch);
term_seen_key_event(); term_seen_key_event(term);
luni_send(cbuf+!left_alt, 1+!!left_alt, 1); luni_send(cbuf+!left_alt, 1+!!left_alt, 1);
} else { } else {
char cbuf[2]; char cbuf[2];
cbuf[0] = '\033'; cbuf[0] = '\033';
cbuf[1] = ch; cbuf[1] = ch;
term_seen_key_event(); term_seen_key_event(term);
lpage_send(kbd_codepage, cbuf+!left_alt, 1+!!left_alt, 1); lpage_send(kbd_codepage, cbuf+!left_alt, 1+!!left_alt, 1);
} }
} }
@ -3824,7 +3832,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
if (!left_alt) if (!left_alt)
keys[0] = 0; keys[0] = 0;
/* If we will be using alt_sum fix the 256s */ /* If we will be using alt_sum fix the 256s */
else if (keys[0] && (in_utf || dbcs_screenfont)) else if (keys[0] && (in_utf(term) || dbcs_screenfont))
keys[0] = 10; keys[0] = 10;
} }
@ -3848,7 +3856,7 @@ void request_paste(void)
* clipboard with no difficulty, so request_paste() can just go * clipboard with no difficulty, so request_paste() can just go
* ahead and paste. * ahead and paste.
*/ */
term_do_paste(); term_do_paste(term);
} }
void set_title(char *title) void set_title(char *title)
@ -4213,7 +4221,7 @@ void optimised_move(int to, int from, int lines)
max = to + from - min; max = to + from - min;
r.left = offset_width; r.left = offset_width;
r.right = offset_width + cols * font_width; r.right = offset_width + term->cols * font_width;
r.top = offset_height + min * font_height; r.top = offset_height + min * font_height;
r.bottom = offset_height + (max + lines) * font_height; r.bottom = offset_height + (max + lines) * font_height;
ScrollWindow(hwnd, 0, (to - from) * font_height, &r, &r); ScrollWindow(hwnd, 0, (to - from) * font_height, &r, &r);
@ -4322,7 +4330,7 @@ void beep(int mode)
} }
} }
/* Otherwise, either visual bell or disabled; do nothing here */ /* Otherwise, either visual bell or disabled; do nothing here */
if (!has_focus) { if (!term->has_focus) {
flash_window(2); /* start */ flash_window(2); /* start */
} }
} }