+typedef enum {
+ PK_NULL, /* No symbol for this key */
+ /* Main keypad keys */
+ PK_ESCAPE, PK_TAB, PK_BACKSPACE, PK_RETURN, PK_COMPOSE,
+ /* Editing keys */
+ PK_HOME, PK_INSERT, PK_DELETE, PK_END, PK_PAGEUP, PK_PAGEDOWN,
+ /* Cursor keys */
+ PK_UP, PK_DOWN, PK_RIGHT, PK_LEFT, PK_REST,
+ /* Numeric keypad */ /* Real one looks like: */
+ PK_PF1, PK_PF2, PK_PF3, PK_PF4, /* PF1 PF2 PF3 PF4 */
+ PK_KPCOMMA, PK_KPMINUS, PK_KPDECIMAL, /* 7 8 9 - */
+ PK_KP0, PK_KP1, PK_KP2, PK_KP3, PK_KP4, /* 4 5 6 , */
+ PK_KP5, PK_KP6, PK_KP7, PK_KP8, PK_KP9, /* 1 2 3 en- */
+ PK_KPBIGPLUS, PK_KPENTER, /* 0 . ter */
+ /* Top row */
+ PK_F1, PK_F2, PK_F3, PK_F4, PK_F5,
+ PK_F6, PK_F7, PK_F8, PK_F9, PK_F10,
+ PK_F11, PK_F12, PK_F13, PK_F14, PK_F15,
+ PK_F16, PK_F17, PK_F18, PK_F19, PK_F20,
+ PK_PAUSE
+} Key_Sym;
+
+#define PK_ISEDITING(k) ((k) >= PK_HOME && (k) <= PK_PAGEDOWN)
+#define PK_ISCURSOR(k) ((k) >= PK_UP && (k) <= PK_REST)
+#define PK_ISKEYPAD(k) ((k) >= PK_PF1 && (k) <= PK_KPENTER)
+#define PK_ISFKEY(k) ((k) >= PK_F1 && (k) <= PK_F20)
+
+typedef enum {
+ VT_XWINDOWS, VT_OEMANSI, VT_OEMONLY, VT_POORMAN, VT_UNICODE
+} VT_Mode;
+
+enum {
+ /*
+ * SSH ciphers (both SSH1 and SSH2)
+ */
+ CIPHER_WARN, /* pseudo 'cipher' */
+ CIPHER_3DES,
+ CIPHER_BLOWFISH,
+ CIPHER_AES, /* (SSH 2 only) */
+ CIPHER_DES,
+ CIPHER_MAX /* no. ciphers (inc warn) */
+};
+
+enum {
+ /*
+ * Line discipline option states: off, on, up to the backend.
+ */
+ LD_YES, LD_NO, LD_BACKEND
+};
+
+enum {
+ /*
+ * Line discipline options which the backend might try to control.
+ */
+ LD_EDIT, /* local line editing */
+ LD_ECHO /* local echo */
+};
+
+enum {
+ /*
+ * Close On Exit behaviours. (cfg.close_on_exit)
+ */
+ COE_NEVER, /* Never close the window */
+ COE_NORMAL, /* Close window on "normal" (non-error) exits only */
+ COE_ALWAYS /* Always close the window */
+};
+
+enum {
+ /* Function key types (cfg.funky_type) */
+ FUNKY_TILDE,
+ FUNKY_LINUX,
+ FUNKY_XTERM,
+ FUNKY_VT400,
+ FUNKY_VT100P,
+ FUNKY_SCO
+};
+
+struct backend_tag {
+ char *(*init) (void *frontend_handle, void **backend_handle, Config *cfg,
+ char *host, int port, char **realhost, int nodelay);
+ void (*free) (void *handle);
+ /* back->reconfig() passes in a replacement configuration. */
+ void (*reconfig) (void *handle, Config *cfg);
+ /* back->send() returns the current amount of buffered data. */
+ int (*send) (void *handle, char *buf, int len);
+ /* back->sendbuffer() does the same thing but without attempting a send */
+ int (*sendbuffer) (void *handle);
+ void (*size) (void *handle, int width, int height);
+ void (*special) (void *handle, Telnet_Special code);
+ Socket(*socket) (void *handle);
+ int (*exitcode) (void *handle);
+ int (*sendok) (void *handle);
+ int (*ldisc) (void *handle, int);
+ void (*provide_ldisc) (void *handle, void *ldisc);
+ void (*provide_logctx) (void *handle, void *logctx);
+ /*
+ * back->unthrottle() tells the back end that the front end
+ * buffer is clearing.
+ */
+ void (*unthrottle) (void *handle, int);
+ int default_port;
+};
+
+extern struct backend_list {