]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - putty.h
first pass
[PuTTY.git] / putty.h
diff --git a/putty.h b/putty.h
index 79731b1877f722fa0e12b424da1208bf449b153b..fd2d0250650ca7268d48ecf72b6657c376f36a24 100644 (file)
--- a/putty.h
+++ b/putty.h
@@ -31,6 +31,8 @@ typedef struct terminal_tag Terminal;
  * Fingerprints of the PGP master keys that can be used to establish a trust
  * path between an executable and other files.
  */
+#define PGP_MASTER_KEY_FP \
+    "440D E3B5 B7A1 CA85 B3CC  1718 AB58 5DC6 0467 6F7C"
 #define PGP_RSA_MASTER_KEY_FP \
     "8F 15 97 DA 25 30 AB 0D  88 D1 92 54 11 CF 0C 4C"
 #define PGP_DSA_MASTER_KEY_FP \
@@ -139,7 +141,7 @@ typedef struct terminal_tag Terminal;
 
 struct sesslist {
     int nsessions;
-    char **sessions;
+    const char **sessions;
     char *buffer;                     /* so memory can be freed later */
 };
 
@@ -180,7 +182,14 @@ typedef enum {
     /* Pseudo-specials used for constructing the specials menu. */
     TS_SEP,        /* Separator */
     TS_SUBMENU,            /* Start a new submenu with specified name */
-    TS_EXITMENU            /* Exit current submenu or end of specials */
+    TS_EXITMENU,    /* Exit current submenu or end of specials */
+    /* Starting point for protocols to invent special-action codes
+     * that can't live in this enum at all, e.g. because they change
+     * with every session.
+     *
+     * Of course, this must remain the last value in this
+     * enumeration. */
+    TS_LOCALSTART
 } Telnet_Special;
 
 struct telnet_special {
@@ -253,9 +262,22 @@ enum {
     KEX_DHGROUP14,
     KEX_DHGEX,
     KEX_RSA,
+    KEX_ECDH,
     KEX_MAX
 };
 
+enum {
+    /*
+     * SSH-2 host key algorithms
+     */
+    HK_WARN,
+    HK_RSA,
+    HK_DSA,
+    HK_ECDSA,
+    HK_ED25519,
+    HK_MAX
+};
+
 enum {
     /*
      * SSH ciphers (both SSH-1 and SSH-2)
@@ -266,6 +288,7 @@ enum {
     CIPHER_AES,                               /* (SSH-2 only) */
     CIPHER_DES,
     CIPHER_ARCFOUR,
+    CIPHER_CHACHA20,
     CIPHER_MAX                        /* no. ciphers (inc warn) */
 };
 
@@ -275,9 +298,9 @@ enum {
      * three-way settings whose values are `always yes', `always
      * no', and `decide by some more complex automated means'. This
      * is true of line discipline options (local echo and line
-     * editing), proxy DNS, Close On Exit, and SSH server bug
-     * workarounds. Accordingly I supply a single enum here to deal
-     * with them all.
+     * editing), proxy DNS, proxy terminal logging, Close On Exit, and
+     * SSH server bug workarounds. Accordingly I supply a single enum
+     * here to deal with them all.
      */
     FORCE_ON, FORCE_OFF, AUTO
 };
@@ -287,7 +310,7 @@ enum {
      * Proxy types.
      */
     PROXY_NONE, PROXY_SOCKS4, PROXY_SOCKS5,
-    PROXY_HTTP, PROXY_TELNET, PROXY_CMD
+    PROXY_HTTP, PROXY_TELNET, PROXY_CMD, PROXY_FUZZ
 };
 
 enum {
@@ -358,7 +381,7 @@ struct keyvalwhere {
      * Two fields which define a string and enum value to be
      * equivalent to each other.
      */
-    char *s;
+    const char *s;
     int v;
 
     /*
@@ -415,13 +438,13 @@ enum {
 
 struct backend_tag {
     const char *(*init) (void *frontend_handle, void **backend_handle,
-                        Conf *conf, char *host, int port, char **realhost,
-                        int nodelay, int keepalive);
+                        Conf *conf, const char *host, int port,
+                         char **realhost, int nodelay, int keepalive);
     void (*free) (void *handle);
     /* back->reconfig() passes in a replacement configuration. */
     void (*reconfig) (void *handle, Conf *conf);
     /* back->send() returns the current amount of buffered data. */
-    int (*send) (void *handle, char *buf, int len);
+    int (*send) (void *handle, const 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);
@@ -441,7 +464,10 @@ struct backend_tag {
      */
     void (*unthrottle) (void *handle, int);
     int (*cfg_info) (void *handle);
-    char *name;
+    /* Only implemented in the SSH protocol: check whether a
+     * connection-sharing upstream exists for a given configuration. */
+    int (*test_for_upstream)(const char *host, int port, Conf *conf);
+    const char *name;
     int protocol;
     int default_port;
 };
@@ -525,8 +551,19 @@ struct RSAKey;                            /* be a little careful of scope */
 typedef struct {
     char *prompt;
     int echo;
-    char *result;      /* allocated/freed by caller */
-    size_t result_len;
+    /*
+     * 'result' must be a dynamically allocated array of exactly
+     * 'resultsize' chars. The code for actually reading input may
+     * realloc it bigger (and adjust resultsize accordingly) if it has
+     * to. The caller should free it again when finished with it.
+     *
+     * If resultsize==0, then result may be NULL. When setting up a
+     * prompt_t, it's therefore easiest to initialise them this way,
+     * which means all actual allocation is done by the callee. This
+     * is what add_prompt does.
+     */
+    char *result;
+    size_t resultsize;
 } prompt_t;
 typedef struct {
     /*
@@ -549,7 +586,9 @@ typedef struct {
                         * get_userpass_input(); initially NULL */
 } prompts_t;
 prompts_t *new_prompts(void *frontend);
-void add_prompt(prompts_t *p, char *promptstr, int echo, size_t len);
+void add_prompt(prompts_t *p, char *promptstr, int echo);
+void prompt_set_result(prompt_t *pr, const char *newstr);
+void prompt_ensure_result_size(prompt_t *pr, int len);
 /* Burn the evidence. (Assumes _all_ strings want free()ing.) */
 void free_prompts(prompts_t *p);
 
@@ -575,9 +614,10 @@ void write_clip(void *frontend, wchar_t *, int *, int, int);
 void get_clip(void *frontend, wchar_t **, int *);
 void optimised_move(void *frontend, int, int, int);
 void set_raw_mouse_mode(void *frontend, int);
-void connection_fatal(void *frontend, char *, ...);
-void fatalbox(char *, ...);
-void modalfatalbox(char *, ...);
+void connection_fatal(void *frontend, const char *, ...);
+void nonfatal(const char *, ...);
+void fatalbox(const char *, ...);
+void modalfatalbox(const char *, ...);
 #ifdef macintosh
 #pragma noreturn(fatalbox)
 #pragma noreturn(modalfatalbox)
@@ -587,7 +627,7 @@ void begin_session(void *frontend);
 void sys_cursor(void *frontend, int x, int y);
 void request_paste(void *frontend);
 void frontend_keypress(void *frontend);
-void ldisc_update(void *frontend, int echo, int edit);
+void frontend_echoedit_update(void *frontend, int echo, int edit);
 /* It's the backend's responsibility to invoke this at the start of a
  * connection, if necessary; it can also invoke it later if the set of
  * special commands changes. It does not need to invoke it at session
@@ -609,7 +649,7 @@ char *get_ttymode(void *frontend, const char *mode);
  * 0  = `user cancelled' (FIXME distinguish "give up entirely" and "next auth"?)
  * <0 = `please call back later with more in/inlen'
  */
-int get_userpass_input(prompts_t *p, unsigned char *in, int inlen);
+int get_userpass_input(prompts_t *p, const unsigned char *in, int inlen);
 #define OPTIMISE_IS_SCROLL 1
 
 void set_iconic(void *frontend, int iconic);
@@ -631,6 +671,7 @@ enum {
     BUSY_CPU       /* Locally busy (e.g. crypto); user interaction suspended */
 };
 void set_busy_status(void *frontend, int status);
+int frontend_is_utf8(void *frontend);
 
 void cleanup_exit(int);
 
@@ -660,12 +701,14 @@ void cleanup_exit(int);
     X(STR, NONE, proxy_username) \
     X(STR, NONE, proxy_password) \
     X(STR, NONE, proxy_telnet_command) \
+    X(INT, NONE, proxy_log_to_term) \
     /* SSH options */ \
     X(STR, NONE, remote_cmd) \
     X(STR, NONE, remote_cmd2) /* fallback if remote_cmd fails; never loaded or saved */ \
     X(INT, NONE, nopty) \
     X(INT, NONE, compression) \
     X(INT, INT, ssh_kexlist) \
+    X(INT, INT, ssh_hklist) \
     X(INT, NONE, ssh_rekey_time) /* in minutes */ \
     X(STR, NONE, ssh_rekey_data) /* string encoding e.g. "100K", "2M", "1G" */ \
     X(INT, NONE, tryagent) \
@@ -673,7 +716,20 @@ void cleanup_exit(int);
     X(INT, NONE, change_username) /* allow username switching in SSH-2 */ \
     X(INT, INT, ssh_cipherlist) \
     X(FILENAME, NONE, keyfile) \
-    X(INT, NONE, sshprot) /* use v1 or v2 when both available */ \
+    /* \
+     * Which SSH protocol to use. \
+     * For historical reasons, the current legal values for CONF_sshprot \
+     * are: \
+     *  0 = SSH-1 only \
+     *  3 = SSH-2 only \
+     * We used to also support \
+     *  1 = SSH-1 with fallback to SSH-2 \
+     *  2 = SSH-2 with fallback to SSH-1 \
+     * and we continue to use 0/3 in storage formats rather than the more \
+     * obvious 1/2 to avoid surprises if someone saves a session and later \
+     * downgrades PuTTY. So it's easier to use these numbers internally too. \
+     */ \
+    X(INT, NONE, sshprot) \
     X(INT, NONE, ssh2_des_cbc) /* "des-cbc" unrecommended SSH-2 cipher */ \
     X(INT, NONE, ssh_no_userauth) /* bypass "ssh-userauth" (SSH-2 only) */ \
     X(INT, NONE, ssh_show_banner) /* show USERAUTH_BANNERs (SSH-2 only) */ \
@@ -715,6 +771,7 @@ void cleanup_exit(int);
     X(INT, NONE, no_remote_resize) /* disable remote resizing */ \
     X(INT, NONE, no_alt_screen) /* disable alternate screen */ \
     X(INT, NONE, no_remote_wintitle) /* disable remote retitling */ \
+    X(INT, NONE, no_remote_clearscroll) /* disable ESC[3J */ \
     X(INT, NONE, no_dbackspace) /* disable destructive backspace */ \
     X(INT, NONE, no_remote_charset) /* disable remote charset config */ \
     X(INT, NONE, remote_qtitle_action) /* remote win title query action */ \
@@ -735,6 +792,8 @@ void cleanup_exit(int);
     X(INT, NONE, erase_to_scrollback) \
     X(INT, NONE, compose_key) \
     X(INT, NONE, ctrlaltkeys) \
+    X(INT, NONE, osx_option_meta) \
+    X(INT, NONE, osx_command_meta) \
     X(STR, NONE, wintitle) /* initial window title */ \
     /* Terminal options */ \
     X(INT, NONE, savelines) \
@@ -778,7 +837,7 @@ void cleanup_exit(int);
     X(INT, NONE, xterm_256_colour) \
     X(INT, NONE, system_colour) \
     X(INT, NONE, try_palette) \
-    X(INT, NONE, bold_colour) \
+    X(INT, NONE, bold_style) \
     X(INT, INT, colours) \
     /* Selection options */ \
     X(INT, NONE, mouse_is_xterm) \
@@ -823,12 +882,24 @@ void cleanup_exit(int);
     X(INT, NONE, sshbug_rekey2) \
     X(INT, NONE, sshbug_maxpkt2) \
     X(INT, NONE, sshbug_ignore2) \
+    X(INT, NONE, sshbug_oldgex2) \
+    X(INT, NONE, sshbug_winadj) \
+    X(INT, NONE, sshbug_chanreq) \
     /*                                                                \
      * ssh_simple means that we promise never to open any channel     \
      * other than the main one, which means it can safely use a very  \
      * large window in SSH-2.                                         \
      */ \
     X(INT, NONE, ssh_simple) \
+    X(INT, NONE, ssh_connection_sharing) \
+    X(INT, NONE, ssh_connection_sharing_upstream) \
+    X(INT, NONE, ssh_connection_sharing_downstream) \
+    /*
+     * ssh_manual_hostkeys is conceptually a set rather than a
+     * dictionary: the string subkeys are the important thing, and the
+     * actual values to which those subkeys map are all "".
+     */ \
+    X(STR, STR, ssh_manual_hostkeys) \
     /* Options for pterm. Should split out into platform-dependent part. */ \
     X(INT, NONE, stamp_utmp) \
     X(INT, NONE, login_shell) \
@@ -859,7 +930,7 @@ int conf_get_int_int(Conf *conf, int key, int subkey);
 char *conf_get_str(Conf *conf, int key);   /* result still owned by conf */
 char *conf_get_str_str(Conf *conf, int key, const char *subkey);
 Filename *conf_get_filename(Conf *conf, int key);
-FontSpec *conf_get_fontspec(Conf *conf, int key);
+FontSpec *conf_get_fontspec(Conf *conf, int key); /* still owned by conf */
 /* Optional accessor function: return NULL if key does not exist. */
 char *conf_get_str_str_opt(Conf *conf, int key, const char *subkey);
 /* Accessor function to step through a string-subkeyed list.
@@ -883,6 +954,20 @@ int conf_serialised_size(Conf *conf);
 void conf_serialise(Conf *conf, void *data);
 int conf_deserialise(Conf *conf, void *data, int maxsize);/*returns size used*/
 
+/*
+ * Functions to copy, free, serialise and deserialise FontSpecs.
+ * Provided per-platform, to go with the platform's idea of a
+ * FontSpec's contents.
+ *
+ * fontspec_serialise returns the number of bytes written, and can
+ * handle data==NULL without crashing. So you can call it once to find
+ * out a size, then again once you've allocated a buffer.
+ */
+FontSpec *fontspec_copy(const FontSpec *f);
+void fontspec_free(FontSpec *f);
+int fontspec_serialise(FontSpec *f, void *data);
+FontSpec *fontspec_deserialise(void *data, int maxsize, int *used);
+
 /*
  * Exports from noise.c.
  */
@@ -899,12 +984,12 @@ void random_destroy_seed(void);
 Backend *backend_from_name(const char *name);
 Backend *backend_from_proto(int proto);
 char *get_remote_username(Conf *conf); /* dynamically allocated */
-char *save_settings(char *section, Conf *conf);
+char *save_settings(const char *section, Conf *conf);
 void save_open_settings(void *sesskey, Conf *conf);
-void load_settings(char *section, Conf *conf);
+void load_settings(const char *section, Conf *conf);
 void load_open_settings(void *sesskey, Conf *conf);
 void get_sesslist(struct sesslist *, int allocate);
-void do_defaults(char *, Conf *);
+void do_defaults(const char *, Conf *);
 void registry_cleanup(void);
 
 /*
@@ -917,11 +1002,15 @@ void registry_cleanup(void);
  * function is perfectly all right returning NULL, of course. The
  * Filename and FontSpec functions are _not allowed_ to fail to
  * return, since these defaults _must_ be per-platform.)
+ *
+ * The 'Filename *' returned by platform_default_filename, and the
+ * 'FontSpec *' returned by platform_default_fontspec, have ownership
+ * transferred to the caller, and must be freed.
  */
 char *platform_default_s(const char *name);
 int platform_default_i(const char *name, int def);
-Filename platform_default_filename(const char *name);
-FontSpec platform_default_fontspec(const char *name);
+Filename *platform_default_filename(const char *name);
+FontSpec *platform_default_fontspec(const char *name);
 
 /*
  * Exports from terminal.c.
@@ -944,8 +1033,6 @@ void term_update(Terminal *);
 void term_invalidate(Terminal *);
 void term_blink(Terminal *, int set_cursor);
 void term_do_paste(Terminal *);
-int term_paste_pending(Terminal *);
-void term_paste(Terminal *);
 void term_nopaste(Terminal *);
 int term_ldisc(Terminal *, int option);
 void term_copyall(Terminal *);
@@ -960,7 +1047,7 @@ void term_provide_logctx(Terminal *term, void *logctx);
 void term_set_focus(Terminal *term, int has_focus);
 char *term_get_ttymode(Terminal *term, const char *mode);
 int term_get_userpass_input(Terminal *term, prompts_t *p,
-                           unsigned char *in, int inlen);
+                           const unsigned char *in, int inlen);
 
 int format_arrow_key(char *buf, Terminal *term, int xkey, int ctrl);
 
@@ -983,9 +1070,10 @@ struct logblank_t {
     int type;
 };
 void log_packet(void *logctx, int direction, int type,
-               char *texttype, const void *data, int len,
+               const char *texttype, const void *data, int len,
                int n_blanks, const struct logblank_t *blanks,
-               const unsigned long *sequence);
+               const unsigned long *sequence,
+                unsigned downstream_id, const char *additional_log_text);
 
 /*
  * Exports from testback.c
@@ -1023,13 +1111,15 @@ extern Backend ssh_backend;
 void *ldisc_create(Conf *, Terminal *, Backend *, void *, void *);
 void ldisc_configure(void *, Conf *);
 void ldisc_free(void *);
-void ldisc_send(void *handle, char *buf, int len, int interactive);
+void ldisc_send(void *handle, const char *buf, int len, int interactive);
+void ldisc_echoedit_update(void *handle);
 
 /*
  * Exports from ldiscucs.c.
  */
-void lpage_send(void *, int codepage, char *buf, int len, int interactive);
-void luni_send(void *, wchar_t * widebuf, int len, int interactive);
+void lpage_send(void *, int codepage, const char *buf, int len,
+                int interactive);
+void luni_send(void *, const wchar_t * widebuf, int len, int interactive);
 
 /*
  * Exports from sshrand.c.
@@ -1070,7 +1160,7 @@ void ser_setup_config_box(struct controlbox *b, int midsession,
 /*
  * Exports from version.c.
  */
-extern char ver[];
+extern const char ver[];
 
 /*
  * Exports from unicode.c.
@@ -1080,10 +1170,10 @@ extern char ver[];
 #endif
 /* void init_ucs(void); -- this is now in platform-specific headers */
 int is_dbcs_leadbyte(int codepage, char byte);
-int mb_to_wc(int codepage, int flags, char *mbstr, int mblen,
+int mb_to_wc(int codepage, int flags, const char *mbstr, int mblen,
             wchar_t *wcstr, int wclen);
-int wc_to_mb(int codepage, int flags, wchar_t *wcstr, int wclen,
-            char *mbstr, int mblen, char *defchr, int *defused,
+int wc_to_mb(int codepage, int flags, const wchar_t *wcstr, int wclen,
+            char *mbstr, int mblen, const char *defchr, int *defused,
             struct unicode_data *ucsdata);
 wchar_t xlat_uskbd2cyrllic(int ch);
 int check_compose(int first, int second);
@@ -1095,10 +1185,10 @@ void get_unitab(int codepage, wchar_t * unitab, int ftype);
 /*
  * Exports from wcwidth.c
  */
-int mk_wcwidth(wchar_t ucs);
-int mk_wcswidth(const wchar_t *pwcs, size_t n);
-int mk_wcwidth_cjk(wchar_t ucs);
-int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n);
+int mk_wcwidth(unsigned int ucs);
+int mk_wcswidth(const unsigned int *pwcs, size_t n);
+int mk_wcwidth_cjk(unsigned int ucs);
+int mk_wcswidth_cjk(const unsigned int *pwcs, size_t n);
 
 /*
  * Exports from mscrypto.c
@@ -1111,17 +1201,32 @@ void crypto_wrapup();
 /*
  * Exports from pageantc.c.
  * 
- * agent_query returns 1 for here's-a-response, and 0 for query-in-
- * progress. In the latter case there will be a call to `callback'
- * at some future point, passing callback_ctx as the first
+ * agent_query returns NULL for here's-a-response, and non-NULL for
+ * query-in- progress. In the latter case there will be a call to
+ * `callback' at some future point, passing callback_ctx as the first
  * parameter and the actual reply data as the second and third.
  * 
  * The response may be a NULL pointer (in either of the synchronous
  * or asynchronous cases), which indicates failure to receive a
  * response.
+ *
+ * When the return from agent_query is not NULL, it identifies the
+ * in-progress query in case it needs to be cancelled. If
+ * agent_cancel_query is called, then the pending query is destroyed
+ * and the callback will not be called. (E.g. if you're going to throw
+ * away the thing you were using as callback_ctx.)
+ *
+ * Passing a null pointer as callback forces agent_query to behave
+ * synchronously, i.e. it will block if necessary, and guarantee to
+ * return NULL. The wrapper function agent_query_synchronous() makes
+ * this easier.
  */
-int agent_query(void *in, int inlen, void **out, int *outlen,
-               void (*callback)(void *, void *, int), void *callback_ctx);
+typedef struct agent_pending_query agent_pending_query;
+agent_pending_query *agent_query(
+    void *in, int inlen, void **out, int *outlen,
+    void (*callback)(void *, void *, int), void *callback_ctx);
+void agent_cancel_query(agent_pending_query *);
+void agent_query_synchronous(void *in, int inlen, void **out, int *outlen);
 int agent_exists(void);
 
 /*
@@ -1148,14 +1253,26 @@ void pgp_fingerprints(void);
  *    back via the provided function with a result that's either 0
  *    or +1'.
  */
-int verify_ssh_host_key(void *frontend, char *host, int port, char *keytype,
-                        char *keystr, char *fingerprint,
+int verify_ssh_host_key(void *frontend, char *host, int port,
+                        const char *keytype, char *keystr, char *fingerprint,
                         void (*callback)(void *ctx, int result), void *ctx);
 /*
- * askalg has the same set of return values as verify_ssh_host_key.
+ * have_ssh_host_key() just returns true if a key of that type is
+ * already cached and false otherwise.
+ */
+int have_ssh_host_key(const char *host, int port, const char *keytype);
+/*
+ * askalg and askhk have the same set of return values as
+ * verify_ssh_host_key.
+ *
+ * (askhk is used in the case where we're using a host key below the
+ * warning threshold because that's all we have cached, but at least
+ * one acceptable algorithm is available that we don't have cached.)
  */
 int askalg(void *frontend, const char *algtype, const char *algname,
           void (*callback)(void *ctx, int result), void *ctx);
+int askhk(void *frontend, const char *algname, const char *betteralgs,
+          void (*callback)(void *ctx, int result), void *ctx);
 /*
  * askappend can return four values:
  * 
@@ -1164,7 +1281,7 @@ int askalg(void *frontend, const char *algtype, const char *algname,
  *  - 0 means cancel logging for this session
  *  - -1 means please wait.
  */
-int askappend(void *frontend, Filename filename,
+int askappend(void *frontend, Filename *filename,
              void (*callback)(void *ctx, int result), void *ctx);
 
 /*
@@ -1172,7 +1289,8 @@ int askappend(void *frontend, Filename filename,
  * that aren't equivalents to things in windlg.c et al.
  */
 extern int console_batch_mode;
-int console_get_userpass_input(prompts_t *p, unsigned char *in, int inlen);
+int console_get_userpass_input(prompts_t *p, const unsigned char *in,
+                               int inlen);
 void console_provide_logctx(void *logctx);
 int is_interactive(void);
 
@@ -1192,16 +1310,21 @@ void printer_finish_job(printer_job *);
  * Exports from cmdline.c (and also cmdline_error(), which is
  * defined differently in various places and required _by_
  * cmdline.c).
+ *
+ * Note that cmdline_process_param takes a const option string, but a
+ * writable argument string. That's not a mistake - that's so it can
+ * zero out password arguments in the hope of not having them show up
+ * avoidably in Unix 'ps'.
  */
-int cmdline_process_param(char *, char *, int, Conf *);
+int cmdline_process_param(const char *, char *, int, Conf *);
 void cmdline_run_saved(Conf *);
 void cmdline_cleanup(void);
-int cmdline_get_passwd_input(prompts_t *p, unsigned char *in, int inlen);
+int cmdline_get_passwd_input(prompts_t *p, const unsigned char *in, int inlen);
 #define TOOLTYPE_FILETRANSFER 1
 #define TOOLTYPE_NONNETWORK 2
 extern int cmdline_tooltype;
 
-void cmdline_error(char *, ...);
+void cmdline_error(const char *, ...);
 
 /*
  * Exports from config.c.
@@ -1226,7 +1349,7 @@ void setup_config_box(struct controlbox *b, int midsession,
  * Exports from minibidi.c.
  */
 typedef struct bidi_char {
-    wchar_t origwc, wc;
+    unsigned int origwc, wc;
     unsigned short index;
 } bidi_char;
 int do_bidi(bidi_char *line, int count);
@@ -1246,13 +1369,21 @@ extern const char *const x11_authnames[];  /* declared in x11fwd.c */
 
 /*
  * Miscellaneous exports from the platform-specific code.
+ *
+ * filename_serialise and filename_deserialise have the same semantics
+ * as fontspec_serialise and fontspec_deserialise above.
  */
-Filename filename_from_str(const char *string);
+Filename *filename_from_str(const char *string);
 const char *filename_to_str(const Filename *fn);
-int filename_equal(Filename f1, Filename f2);
-int filename_is_null(Filename fn);
+int filename_equal(const Filename *f1, const Filename *f2);
+int filename_is_null(const Filename *fn);
+Filename *filename_copy(const Filename *fn);
+void filename_free(Filename *fn);
+int filename_serialise(const Filename *f, void *data);
+Filename *filename_deserialise(void *data, int maxsize, int *used);
 char *get_username(void);             /* return value needs freeing */
-char *get_random_data(int bytes);      /* used in cmdgen.c */
+char *get_random_data(int bytes, const char *device); /* used in cmdgen.c */
+char filename_char_sanitise(char c);   /* rewrite special pathname chars */
 
 /*
  * Exports and imports from timing.c.
@@ -1344,11 +1475,42 @@ char *get_random_data(int bytes);      /* used in cmdgen.c */
  * GETTICKCOUNT() and compare the result with the returned `next'
  * value to find out how long you have to make your next wait().)
  */
-typedef void (*timer_fn_t)(void *ctx, long now);
-long schedule_timer(int ticks, timer_fn_t fn, void *ctx);
+typedef void (*timer_fn_t)(void *ctx, unsigned long now);
+unsigned long schedule_timer(int ticks, timer_fn_t fn, void *ctx);
 void expire_timer_context(void *ctx);
-int run_timers(long now, long *next);
-void timer_change_notify(long next);
+int run_timers(unsigned long now, unsigned long *next);
+void timer_change_notify(unsigned long next);
+unsigned long timing_last_clock(void);
+
+/*
+ * Exports from callback.c.
+ *
+ * This provides a method of queuing function calls to be run at the
+ * earliest convenience from the top-level event loop. Use it if
+ * you're deep in a nested chain of calls and want to trigger an
+ * action which will probably lead to your function being re-entered
+ * recursively if you just call the initiating function the normal
+ * way.
+ *
+ * Most front ends run the queued callbacks by simply calling
+ * run_toplevel_callbacks() after handling each event in their
+ * top-level event loop. However, if a front end doesn't have control
+ * over its own event loop (e.g. because it's using GTK) then it can
+ * instead request notifications when a callback is available, so that
+ * it knows to ask its delegate event loop to do the same thing. Also,
+ * if a front end needs to know whether a callback is pending without
+ * actually running it (e.g. so as to put a zero timeout on a select()
+ * call) then it can call toplevel_callback_pending(), which will
+ * return true if at least one callback is in the queue.
+ */
+typedef void (*toplevel_callback_fn_t)(void *ctx);
+void queue_toplevel_callback(toplevel_callback_fn_t fn, void *ctx);
+void run_toplevel_callbacks(void);
+int toplevel_callback_pending(void);
+
+typedef void (*toplevel_callback_notify_fn_t)(void *frontend);
+void request_callback_notifications(toplevel_callback_notify_fn_t notify,
+                                    void *frontend);
 
 /*
  * Define no-op macros for the jump list functions, on platforms that
@@ -1361,4 +1523,31 @@ void timer_change_notify(long next);
 #define remove_session_from_jumplist(x) ((void)0)
 #endif
 
+/* SURROGATE PAIR */
+#define HIGH_SURROGATE_START 0xd800
+#define HIGH_SURROGATE_END 0xdbff
+#define LOW_SURROGATE_START 0xdc00
+#define LOW_SURROGATE_END 0xdfff
+
+/* These macros exist in the Windows API, so the environment may
+ * provide them. If not, define them in terms of the above. */
+#ifndef IS_HIGH_SURROGATE
+#define IS_HIGH_SURROGATE(wch) (((wch) >= HIGH_SURROGATE_START) && \
+                                ((wch) <= HIGH_SURROGATE_END))
+#define IS_LOW_SURROGATE(wch) (((wch) >= LOW_SURROGATE_START) && \
+                               ((wch) <= LOW_SURROGATE_END))
+#define IS_SURROGATE_PAIR(hs, ls) (IS_HIGH_SURROGATE(hs) && \
+                                   IS_LOW_SURROGATE(ls))
+#endif
+
+
+#define IS_SURROGATE(wch) (((wch) >= HIGH_SURROGATE_START) &&   \
+                           ((wch) <= LOW_SURROGATE_END))
+#define HIGH_SURROGATE_OF(codept) \
+    (HIGH_SURROGATE_START + (((codept) - 0x10000) >> 10))
+#define LOW_SURROGATE_OF(codept) \
+    (LOW_SURROGATE_START + (((codept) - 0x10000) & 0x3FF))
+#define FROM_SURROGATES(wch1, wch2) \
+    (0x10000 + (((wch1) & 0x3FF) << 10) + ((wch2) & 0x3FF))
+
 #endif