First phase of porting. pterm now compiles and runs under Linux+gtk.
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Wed, 9 Oct 2002 18:09:42 +0000 (18:09 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Wed, 9 Oct 2002 18:09:42 +0000 (18:09 +0000)
The current pty.c backend is temporarily a loopback device for
terminal emulator testing, the display handling is only just enough
to show that terminal.c is functioning, the keyboard handling is
laughable, and most features are absent. Next step: bring output and
input up to a plausibly working state, and put a real pty on the
back to create a vaguely usable prototype. Oh, and a scrollbar would
be nice too.
In _theory_ the Windows builds should still work fine after this...

git-svn-id: svn://svn.tartarus.org/sgt/putty@2010 cda61777-01e9-0310-a592-d414129be87e

24 files changed:
Recipe
be_none.c
ldisc.c
logging.c
misc.c
misc.h
mkfiles.pl
pageant.c
plink.c
psftp.c
putty.h
puttygen.c
scp.c
settings.c
terminal.c
unicode.c
unix/pterm.c
unix/pty.c [new file with mode: 0644]
unix/unix.h
unix/uxprint.c [new file with mode: 0644]
unix/uxstore.c [new file with mode: 0644]
unix/uxucs.c [new file with mode: 0644]
window.c
winstuff.h

diff --git a/Recipe b/Recipe
index 3e91897..f31d17b 100644 (file)
--- a/Recipe
+++ b/Recipe
@@ -132,4 +132,5 @@ puttygen : [G] puttygen sshrsag sshdssg sshprime sshdes sshbn sshmd5 version
          + sshrand noise sshsha winstore misc winctrls sshrsa sshdss
          + sshpubk sshaes sshsh512 import winutils puttygen.res LIBS
 
-pterm    : [X] pterm terminal wcwidth unicode uxmisc
+pterm    : [X] pterm terminal wcwidth uxucs uxmisc tree234 misc ldisc
+         + logging uxprint settings pty be_none uxstore
index a08a938..879a20c 100644 (file)
--- a/be_none.c
+++ b/be_none.c
@@ -4,7 +4,6 @@
  * lookups.
  */
 
-#include <windows.h>
 #include <stdio.h>
 #include "putty.h"
 
diff --git a/ldisc.c b/ldisc.c
index 131cc42..e6a110b 100644 (file)
--- a/ldisc.c
+++ b/ldisc.c
@@ -5,7 +5,6 @@
  * depending on what's currently configured.
  */
 
-#include <windows.h>
 #include <stdio.h>
 #include <ctype.h>
 
index b311784..c843118 100644 (file)
--- a/logging.c
+++ b/logging.c
@@ -1,5 +1,3 @@
-#include <windows.h>
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <ctype.h>
@@ -11,7 +9,6 @@
 
 /* log session to file stuff ... */
 static FILE *lgfp = NULL;
-static char timdatbuf[20];
 static char currlogfilename[FILENAME_MAX];
 
 static void xlatlognam(char *d, char *s, char *hostname, struct tm *tm);
@@ -150,7 +147,6 @@ void logfclose(void)
 static void xlatlognam(char *d, char *s, char *hostname, struct tm *tm) {
     char buf[10], *bufp;
     int size;
-    char *ds = d; /* save start pos. */
     int len = FILENAME_MAX-1;
 
     while (*s) {
@@ -159,6 +155,7 @@ static void xlatlognam(char *d, char *s, char *hostname, struct tm *tm) {
        if (*s == '&') {
            char c;
            s++;
+           size = 0;
            if (*s) switch (c = *s++, tolower(c)) {
              case 'y':
                size = strftime(buf, sizeof(buf), "%Y", tm);
diff --git a/misc.c b/misc.c
index f91e8a7..2d0a463 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -1,6 +1,6 @@
-#include <windows.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdarg.h>
 #include <assert.h>
 #include "putty.h"
 
@@ -472,9 +472,7 @@ void *safemalloc(size_t size)
 #else
        strcpy(str, "Out of memory!");
 #endif
-       MessageBox(NULL, str, "PuTTY Fatal Error",
-                  MB_SYSTEMMODAL | MB_ICONERROR | MB_OK);
-       cleanup_exit(1);
+       modalfatalbox(str);
     }
 #ifdef MALLOC_LOG
     if (fp)
@@ -509,9 +507,7 @@ void *saferealloc(void *ptr, size_t size)
 #else
        strcpy(str, "Out of memory!");
 #endif
-       MessageBox(NULL, str, "PuTTY Fatal Error",
-                  MB_SYSTEMMODAL | MB_ICONERROR | MB_OK);
-       cleanup_exit(1);
+       modalfatalbox(str);
     }
 #ifdef MALLOC_LOG
     if (fp)
diff --git a/misc.h b/misc.h
index a59317e..e4e70b1 100644 (file)
--- a/misc.h
+++ b/misc.h
@@ -54,10 +54,15 @@ void debug_memdump(void *buf, int len, int L);
 #define dmemdumpl(buf,len)
 #endif
 
-
 #ifndef lenof
 #define lenof(x) ( (sizeof((x))) / (sizeof(*(x))))
 #endif
 
+#ifndef min
+#define min(x,y) ( (x) < (y) ? (x) : (y) )
+#endif
+#ifndef max
+#define max(x,y) ( (x) < (y) ? (x) : (y) )
+#endif
 
 #endif
index d59854d..6851718 100755 (executable)
@@ -481,12 +481,12 @@ print
 "# TOOLPATH = /opt/gcc/bin\n".
 "CC = \$(TOOLPATH)cc\n".
 "\n".
-&splitline("CFLAGS = -Wall -O2 -I. -I.. `gtk-config --cflags`")."\n".
-"LDFLAGS = -s `gtk-config --libs`\n".
+&splitline("CFLAGS = -Wall -g -I. -I.. `gtk-config --cflags`")."\n".
+"LDFLAGS = `gtk-config --libs`\n".
 "\n".
 ".SUFFIXES:\n".
 "\n".
-"%.o: %.c\n".
+"%.o:\n".
 "\t\$(CC) \$(COMPAT) \$(FWHACK) \$(XFLAGS) \$(CFLAGS) -c \$<\n".
 "\n";
 print &splitline("all:" . join "", map { " $_" } &prognames("X"));
index 757091a..71753c0 100644 (file)
--- a/pageant.c
+++ b/pageant.c
@@ -59,6 +59,22 @@ static char *putty_path;
 #define PUTTY_DEFAULT     "Default%20Settings"
 static int initial_menuitems_count;
 
+/*
+ * Print a modal (Really Bad) message box and perform a fatal exit.
+ */
+void modalfatalbox(char *fmt, ...)
+{
+    va_list ap;
+    char stuff[200];
+
+    va_start(ap, fmt);
+    vsprintf(stuff, fmt, ap);
+    va_end(ap);
+    MessageBox(main_hwnd, stuff, "Pageant Fatal Error",
+              MB_SYSTEMMODAL | MB_ICONERROR | MB_OK);
+    exit(1);
+}
+
 /* Un-munge session names out of the registry. */
 static void unmungestr(char *in, char *out, int outlen)
 {
diff --git a/plink.c b/plink.c
index ed4f134..0d79a98 100644 (file)
--- a/plink.c
+++ b/plink.c
@@ -29,6 +29,17 @@ void fatalbox(char *p, ...)
     WSACleanup();
     cleanup_exit(1);
 }
+void modalfatalbox(char *p, ...)
+{
+    va_list ap;
+    fprintf(stderr, "FATAL ERROR: ");
+    va_start(ap, p);
+    vfprintf(stderr, p, ap);
+    va_end(ap);
+    fputc('\n', stderr);
+    WSACleanup();
+    cleanup_exit(1);
+}
 void connection_fatal(char *p, ...)
 {
     va_list ap;
diff --git a/psftp.c b/psftp.c
index 6f849d4..4657091 100644 (file)
--- a/psftp.c
+++ b/psftp.c
@@ -1457,6 +1457,19 @@ void fatalbox(char *fmt, ...)
 
     cleanup_exit(1);
 }
+void modalfatalbox(char *fmt, ...)
+{
+    char str[0x100];                  /* Make the size big enough */
+    va_list ap;
+    va_start(ap, fmt);
+    strcpy(str, "Fatal:");
+    vsprintf(str + strlen(str), fmt, ap);
+    va_end(ap);
+    strcat(str, "\n");
+    fputs(str, stderr);
+
+    cleanup_exit(1);
+}
 void connection_fatal(char *fmt, ...)
 {
     char str[0x100];                  /* Make the size big enough */
diff --git a/putty.h b/putty.h
index e7bb859..c4230c3 100644 (file)
--- a/putty.h
+++ b/putty.h
@@ -17,6 +17,7 @@
 #endif
 
 typedef struct config_tag Config;
+typedef struct backend_tag Backend;
 
 #include "puttyps.h"
 #include "network.h"
@@ -121,6 +122,9 @@ GLOBAL int big_cursor;
 GLOBAL char *help_path;
 GLOBAL int help_has_contents;
 
+GLOBAL int nsessions;
+GLOBAL char **sessions;
+
 GLOBAL int utf;
 GLOBAL int dbcs_screenfont;
 GLOBAL int font_codepage;
@@ -199,7 +203,7 @@ enum {
     COE_ALWAYS                        /* Always close the window */
 };
 
-typedef struct {
+struct backend_tag {
     char *(*init) (char *host, int port, char **realhost, int nodelay);
     /* back->send() returns the current amount of buffered data. */
     int (*send) (char *buf, int len);
@@ -217,7 +221,7 @@ typedef struct {
      */
     void (*unthrottle) (int);
     int default_port;
-} Backend;
+};
 
 GLOBAL Backend *back;
 
@@ -427,6 +431,7 @@ void set_raw_mouse_mode(int);
 Mouse_Button translate_button(Mouse_Button b);
 void connection_fatal(char *, ...);
 void fatalbox(char *, ...);
+void modalfatalbox(char *, ...);
 void beep(int);
 void begin_session(void);
 void sys_cursor(int x, int y);
@@ -460,6 +465,8 @@ void random_destroy_seed(void);
 void save_settings(char *section, int do_host, Config * cfg);
 void load_settings(char *section, int do_host, Config * cfg);
 void get_sesslist(int allocate);
+void do_defaults(char *, Config *);
+void registry_cleanup(void);
 
 /*
  * Exports from terminal.c.
@@ -589,6 +596,15 @@ int wc_match(const char *wildcard, const char *target);
 int wc_unescape(char *output, const char *wildcard);
 
 /*
+ * Exports from windlg.c
+ */
+void logevent(char *);
+void verify_ssh_host_key(char *host, int port, char *keytype,
+                        char *keystr, char *fingerprint);
+void askcipher(char *ciphername, int cs);
+int askappend(char *filename);
+
+/*
  * Exports from console.c (that aren't equivalents to things in
  * windlg.c).
  */
index 4e2098e..4be822a 100644 (file)
@@ -22,6 +22,22 @@ static int requested_help;
 
 static char *cmdline_keyfile = NULL;
 
+/*
+ * Print a modal (Really Bad) message box and perform a fatal exit.
+ */
+void modalfatalbox(char *fmt, ...)
+{
+    va_list ap;
+    char stuff[200];
+
+    va_start(ap, fmt);
+    vsprintf(stuff, fmt, ap);
+    va_end(ap);
+    MessageBox(NULL, stuff, "PuTTYgen Fatal Error",
+              MB_SYSTEMMODAL | MB_ICONERROR | MB_OK);
+    exit(1);
+}
+
 /* ----------------------------------------------------------------------
  * Progress report code. This is really horrible :-)
  */
diff --git a/scp.c b/scp.c
index 5ebcfd2..a24d62f 100644 (file)
--- a/scp.c
+++ b/scp.c
@@ -234,6 +234,29 @@ void fatalbox(char *fmt, ...)
 
     cleanup_exit(1);
 }
+void modalfatalbox(char *fmt, ...)
+{
+    char str[0x100];                  /* Make the size big enough */
+    va_list ap;
+    va_start(ap, fmt);
+    strcpy(str, "Fatal: ");
+    vsprintf(str + strlen(str), fmt, ap);
+    va_end(ap);
+    strcat(str, "\n");
+    tell_str(stderr, str);
+    errs++;
+
+    if (gui_mode) {
+       unsigned int msg_id = WM_RET_ERR_CNT;
+       if (list)
+           msg_id = WM_LS_RET_ERR_CNT;
+       while (!PostMessage
+              ((HWND) atoi(gui_hwnd), msg_id, (WPARAM) errs,
+               0 /*lParam */ ))SleepEx(1000, TRUE);
+    }
+
+    cleanup_exit(1);
+}
 void connection_fatal(char *fmt, ...)
 {
     char str[0x100];                  /* Make the size big enough */
index ef0446f..4bc11ec 100644 (file)
@@ -2,7 +2,6 @@
  * settings.c: read and write saved sessions.
  */
 
-#include <windows.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include "putty.h"
@@ -464,8 +463,11 @@ void load_settings(char *section, int do_host, Config * cfg)
     gppi(sesskey, "TermHeight", 24, &cfg->height);
     gpps(sesskey, "Font", "Courier New", cfg->font, sizeof(cfg->font));
     gppi(sesskey, "FontIsBold", 0, &cfg->fontisbold);
+#ifdef _WINDOWS
     gppi(sesskey, "FontCharSet", ANSI_CHARSET, &cfg->fontcharset);
+#endif
     gppi(sesskey, "FontHeight", 10, &cfg->fontheight);
+#ifdef _WINDOWS
     if (cfg->fontheight < 0) {
        int oldh, newh;
        HDC hdc = GetDC(NULL);
@@ -478,6 +480,7 @@ void load_settings(char *section, int do_host, Config * cfg)
            newh--;
        cfg->fontheight = newh;
     }
+#endif
     gppi(sesskey, "FontVTMode", VT_UNICODE, (int *) &cfg->vtmode);
     gppi(sesskey, "TryPalette", 0, &cfg->try_palette);
     gppi(sesskey, "BoldAsColour", 1, &cfg->bold_colour);
index b286efe..7a6c5bc 100644 (file)
@@ -1042,6 +1042,9 @@ static void term_print_finish(void)
     int len, size;
     char c;
 
+    if (!printing && !only_printing)
+       return;                        /* we need do nothing */
+
     term_print_flush();
     while ((size = bufchain_size(&printer_buf)) > 0) {
        bufchain_prefix(&printer_buf, &data, &len);
@@ -1072,6 +1075,7 @@ void term_out(void)
 
     unget = -1;
 
+    chars = NULL;                     /* placate compiler warnings */
     while (nchars > 0 || bufchain_size(&inbuf) > 0) {
        if (unget == -1) {
            if (nchars == 0) {
@@ -3176,16 +3180,14 @@ static void clipme(pos top, pos bottom, int rect)
                    unsigned char buf[4];
                    WCHAR wbuf[4];
                    int rv;
-                   if (IsDBCSLeadByteEx(font_codepage, (BYTE) c)) {
+                   if (is_dbcs_leadbyte(font_codepage, (BYTE) c)) {
                        buf[0] = c;
                        buf[1] = (unsigned char) ldata[top.x + 1];
-                       rv = MultiByteToWideChar(font_codepage,
-                                                0, buf, 2, wbuf, 4);
+                       rv = mb_to_wc(font_codepage, 0, buf, 2, wbuf, 4);
                        top.x++;
                    } else {
                        buf[0] = c;
-                       rv = MultiByteToWideChar(font_codepage,
-                                                0, buf, 1, wbuf, 4);
+                       rv = mb_to_wc(font_codepage, 0, buf, 1, wbuf, 4);
                    }
 
                    if (rv > 0) {
index e854221..f8cd3b5 100644 (file)
--- a/unicode.c
+++ b/unicode.c
@@ -614,8 +614,7 @@ void lpage_send(int codepage, char *buf, int len, int interactive)
        widesize = len * 2;
     }
 
-    wclen =
-       MultiByteToWideChar(codepage, 0, buf, len, widebuffer, widesize);
+    wclen = mb_to_wc(codepage, 0, buf, len, widebuffer, widesize);
     luni_send(widebuffer, wclen, interactive);
 }
 
@@ -653,8 +652,8 @@ void luni_send(wchar_t * widebuf, int len, int interactive)
        }
     } else if (!uni_tbl) {
        int rv;
-       rv = WideCharToMultiByte(line_codepage, 0, widebuf, len,
-                                linebuffer, linesize, NULL, NULL);
+       rv = wc_to_mb(line_codepage, 0, widebuf, len,
+                     linebuffer, linesize, NULL, NULL);
        if (rv >= 0)
            p = linebuffer + rv;
        else
@@ -1243,7 +1242,7 @@ void get_unitab(int codepage, wchar_t * unitab, int ftype)
        for (i = 0; i < max; i++) {
            tbuf[0] = i;
 
-           if (MultiByteToWideChar(codepage, flg, tbuf, 1, unitab + i, 1)
+           if (mb_to_wc(codepage, flg, tbuf, 1, unitab + i, 1)
                != 1)
                unitab[i] = 0xFFFD;
        }
index d29762a..082a271 100644 (file)
 
 #include <string.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include <time.h>
 #include <gtk/gtk.h>
 
+#define PUTTY_DO_GLOBALS              /* actually _define_ globals */
+#include "putty.h"
+
 #define CAT2(x,y) x ## y
 #define CAT(x,y) CAT2(x,y)
 #define ASSERT(x) enum {CAT(assertion_,__LINE__) = 1 / (x)}
 
-#define lenof(x) (sizeof((x))/sizeof(*(x)))
+void ldisc_update(int echo, int edit)
+{
+    /*
+     * This is a stub in pterm. If I ever produce a Unix
+     * command-line ssh/telnet/rlogin client (i.e. a port of plink)
+     * then it will require some termios manoeuvring analogous to
+     * that in the Windows plink.c, but here it's meaningless.
+     */
+}
+
+int askappend(char *filename)
+{
+    /*
+     * FIXME: for the moment we just wipe the log file. Since I
+     * haven't yet enabled logging, this shouldn't matter yet!
+     */
+    return 2;
+}
+
+void logevent(char *string)
+{
+    /*
+     * FIXME: event log entries are currently ignored.
+     */
+}
+
+/*
+ * Translate a raw mouse button designation (LEFT, MIDDLE, RIGHT)
+ * into a cooked one (SELECT, EXTEND, PASTE).
+ * 
+ * In Unix, this is not configurable; the X button arrangement is
+ * rock-solid across all applications, everyone has a three-button
+ * mouse or a means of faking it, and there is no need to switch
+ * buttons around at all.
+ */
+Mouse_Button translate_button(Mouse_Button button)
+{
+    if (button == MBT_LEFT)
+       return MBT_SELECT;
+    if (button == MBT_MIDDLE)
+       return MBT_PASTE;
+    if (button == MBT_RIGHT)
+       return MBT_EXTEND;
+    return 0;                         /* shouldn't happen */
+}
+
+/*
+ * Minimise or restore the window in response to a server-side
+ * request.
+ */
+void set_iconic(int iconic)
+{
+    /* FIXME: currently ignored */
+}
+
+/*
+ * Move the window in response to a server-side request.
+ */
+void move_window(int x, int y)
+{
+    /* FIXME: currently ignored */
+}
+
+/*
+ * Move the window to the top or bottom of the z-order in response
+ * to a server-side request.
+ */
+void set_zorder(int top)
+{
+    /* FIXME: currently ignored */
+}
+
+/*
+ * Refresh the window in response to a server-side request.
+ */
+void refresh_window(void)
+{
+    /* FIXME: currently ignored */
+}
+
+/*
+ * Maximise or restore the window in response to a server-side
+ * request.
+ */
+void set_zoomed(int zoomed)
+{
+    /* FIXME: currently ignored */
+}
+
+/*
+ * Report whether the window is iconic, for terminal reports.
+ */
+int is_iconic(void)
+{
+    return 0;                         /* FIXME */
+}
+
+/*
+ * Report the window's position, for terminal reports.
+ */
+void get_window_pos(int *x, int *y)
+{
+    *x = 3; *y = 4;                   /* FIXME */
+}
+
+/*
+ * Report the window's pixel size, for terminal reports.
+ */
+void get_window_pixels(int *x, int *y)
+{
+    *x = 1; *y = 2;                   /* FIXME */
+}
+
+/*
+ * Return the window or icon title.
+ */
+char *get_window_title(int icon)
+{
+    return "FIXME: window title retrieval not yet implemented";
+}
 
 struct gui_data {
     GtkWidget *area;
@@ -20,6 +143,9 @@ struct gui_data {
     GdkGC *black_gc, *white_gc;
 };
 
+static struct gui_data the_inst;
+static struct gui_data *inst = &the_inst;   /* so we always write `inst->' */
+
 gint delete_window(GtkWidget *widget, GdkEvent *event, gpointer data)
 {
     /*
@@ -86,13 +212,17 @@ gint configure_area(GtkWidget *widget, GdkEventConfigure *event, gpointer data)
 
 gint expose_area(GtkWidget *widget, GdkEventExpose *event, gpointer data)
 {
-    struct gui_data *inst = (struct gui_data *)data;
+    /* struct gui_data *inst = (struct gui_data *)data; */
 
     /*
-     * FIXME: pass the exposed rect to terminal.c which will call
-     * us back to do the actual painting.
+     * Pass the exposed rectangle to terminal.c, which will call us
+     * back to do the actual painting.
      */
-    return FALSE;
+    term_paint(NULL, 
+              event->area.x / 9, event->area.y / 15,
+              (event->area.x + event->area.width - 1) / 9,
+              (event->area.y + event->area.height - 1) / 15);
+    return TRUE;
 }
 
 #define KEY_PRESSED(k) \
@@ -100,20 +230,23 @@ gint expose_area(GtkWidget *widget, GdkEventExpose *event, gpointer data)
 
 gint key_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
 {
-    struct gui_data *inst = (struct gui_data *)data;
+    /* struct gui_data *inst = (struct gui_data *)data; */
 
-    /*
-     * FIXME: all sorts of fun keyboard handling required here.
-     */
+    if (event->type == GDK_KEY_PRESS) {
+       char c[1];
+       c[0] = event->keyval;
+       ldisc_send(c, 1, 1);
+       term_out();
+    }
+
+    return TRUE;
 }
 
 gint timer_func(gpointer data)
 {
-    struct gui_data *inst = (struct gui_data *)data;
+    /* struct gui_data *inst = (struct gui_data *)data; */
 
-    /*
-     * FIXME: we're bound to need this sooner or later!
-     */
+    term_update();
     return TRUE;
 }
 
@@ -127,16 +260,150 @@ gint focus_event(GtkWidget *widget, GdkEventFocus *event, gpointer data)
     /*
      * FIXME: need to faff with the cursor shape.
      */
+    return FALSE;
+}
+
+/*
+ * set or clear the "raw mouse message" mode
+ */
+void set_raw_mouse_mode(int activate)
+{
+    /* FIXME: currently ignored */
+}
+
+void request_resize(int w, int h)
+{
+    /* FIXME: currently ignored */
+}
+
+void palette_set(int n, int r, int g, int b)
+{
+    /* FIXME: currently ignored */
+}
+void palette_reset(void)
+{
+    /* FIXME: currently ignored */
+}
+
+void write_clip(wchar_t * data, int len, int must_deselect)
+{
+    /* FIXME: currently ignored */
+}
+
+void get_clip(wchar_t ** p, int *len)
+{
+    if (p) {
+       /* FIXME: currently nonfunctional */
+       *p = NULL;
+       *len = 0;
+    }
+}
+
+void set_title(char *title)
+{
+    /* FIXME: currently ignored */
+}
+
+void set_icon(char *title)
+{
+    /* FIXME: currently ignored */
+}
+
+void set_sbar(int total, int start, int page)
+{
+    /* FIXME: currently ignored */
+}
+
+void sys_cursor(int x, int y)
+{
+    /*
+     * This is meaningless under X.
+     */
+}
+
+void beep(int mode)
+{
+    gdk_beep();
+}
+
+int CharWidth(Context ctx, int uc)
+{
+    /*
+     * Under X, any fixed-width font really _is_ fixed-width.
+     * Double-width characters will be dealt with using a separate
+     * font. For the moment we can simply return 1.
+     */
+    return 1;
+}
+
+Context get_ctx(void)
+{
+    GdkGC *gc = gdk_gc_new(inst->area->window);
+    return gc;
+}
+
+void free_ctx(Context ctx)
+{
+    GdkGC *gc = (GdkGC *)ctx;
+    gdk_gc_unref(gc);
+}
+
+/*
+ * Draw a line of text in the window, at given character
+ * coordinates, in given attributes.
+ *
+ * We are allowed to fiddle with the contents of `text'.
+ */
+void do_text(Context ctx, int x, int y, char *text, int len,
+            unsigned long attr, int lattr)
+{
+    GdkColor fg, bg;
+
+    GdkGC *gc = (GdkGC *)ctx;
+    fg.red = fg.green = fg.blue = 65535;
+    bg.red = bg.green = bg.blue = 65535;
+    gdk_gc_set_foreground(gc, &fg);
+    gdk_gc_set_background(gc, &bg);
+
+    gdk_draw_text(inst->area->window, inst->fonts[0], inst->white_gc,
+                 x*9, y*15 + inst->fonts[0]->ascent, text, len);
+}
+
+void do_cursor(Context ctx, int x, int y, char *text, int len,
+              unsigned long attr, int lattr)
+{
+    /* FIXME: passive cursor NYI */
+    if (attr & TATTR_PASCURS) {
+       attr &= ~TATTR_PASCURS;
+       attr |= TATTR_ACTCURS;
+    }
+    do_text(ctx, x, y, text, len, attr, lattr);
+}
+
+void modalfatalbox(char *p, ...)
+{
+    va_list ap;
+    fprintf(stderr, "FATAL ERROR: ");
+    va_start(ap, p);
+    vfprintf(stderr, p, ap);
+    va_end(ap);
+    fputc('\n', stderr);
+    exit(1);
 }
 
 int main(int argc, char **argv)
 {
     GtkWidget *window;
-    struct gui_data the_inst;
-    struct gui_data *inst = &the_inst;   /* so we always write `inst->' */
 
     gtk_init(&argc, &argv);
 
+    do_defaults(NULL, &cfg);
+
+    init_ucs();
+
+    back = &pty_backend;
+    back->init(NULL, 0, NULL, 0);
+
     window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
     inst->area = gtk_drawing_area_new();
     gtk_drawing_area_size(GTK_DRAWING_AREA(inst->area),
@@ -167,6 +434,9 @@ int main(int argc, char **argv)
     gtk_widget_show(inst->area);
     gtk_widget_show(window);
 
+    term_init();
+    term_size(24, 80, 2000);
+
     gtk_main();
 
     return 0;
diff --git a/unix/pty.c b/unix/pty.c
new file mode 100644 (file)
index 0000000..291247e
--- /dev/null
@@ -0,0 +1,107 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "putty.h"
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+static void pty_size(void);
+
+static void c_write(char *buf, int len)
+{
+    from_backend(0, buf, len);
+}
+
+/*
+ * Called to set up the pty.
+ * 
+ * Returns an error message, or NULL on success.
+ *
+ * Also places the canonical host name into `realhost'. It must be
+ * freed by the caller.
+ */
+static char *pty_init(char *host, int port, char **realhost, int nodelay)
+{
+    /* FIXME: do nothing for now */
+    return NULL;
+}
+
+/*
+ * Called to send data down the pty.
+ */
+static int pty_send(char *buf, int len)
+{
+    c_write(buf, len);                /* FIXME: diagnostic thingy */
+    return 0;
+}
+
+/*
+ * Called to query the current socket sendability status.
+ */
+static int pty_sendbuffer(void)
+{
+    return 0;
+}
+
+/*
+ * Called to set the size of the window
+ */
+static void pty_size(void)
+{
+    /* FIXME: will need to do TIOCSWINSZ or whatever. */
+    return;
+}
+
+/*
+ * Send special codes.
+ */
+static void pty_special(Telnet_Special code)
+{
+    /* Do nothing! */
+    return;
+}
+
+static Socket pty_socket(void)
+{
+    return NULL;                      /* shouldn't ever be needed */
+}
+
+static int pty_sendok(void)
+{
+    return 1;
+}
+
+static void pty_unthrottle(int backlog)
+{
+    /* do nothing */
+}
+
+static int pty_ldisc(int option)
+{
+    return 0;                         /* neither editing nor echoing */
+}
+
+static int pty_exitcode(void)
+{
+    /* Shouldn't ever be required */
+    return 0;
+}
+
+Backend pty_backend = {
+    pty_init,
+    pty_send,
+    pty_sendbuffer,
+    pty_size,
+    pty_special,
+    pty_socket,
+    pty_exitcode,
+    pty_sendok,
+    pty_ldisc,
+    pty_unthrottle,
+    1
+};
index 6a40e4a..a7f3fa5 100644 (file)
@@ -3,6 +3,8 @@
 
 typedef void *Context;                 /* FIXME: probably needs changing */
 
+extern Backend pty_backend;
+
 /* Simple wraparound timer function */
 unsigned long getticks(void);         /* based on gettimeofday(2) */
 #define GETTICKCOUNT getticks
@@ -12,6 +14,10 @@ unsigned long getticks(void);               /* based on gettimeofday(2) */
 #define WCHAR wchar_t
 #define BYTE unsigned char
 
+int is_dbcs_leadbyte(int codepage, char byte);
+int mb_to_wc(int codepage, int flags, char *mbstr, int mblen,
+            wchar_t *wcstr, int wclen);
+void init_ucs(void);
 
 #define DEFAULT_CODEPAGE 0            /* FIXME: no idea how to do this */
 
diff --git a/unix/uxprint.c b/unix/uxprint.c
new file mode 100644 (file)
index 0000000..6558317
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Printing interface for PuTTY.
+ */
+
+#include <assert.h>
+#include "putty.h"
+
+printer_job *printer_start_job(char *printer)
+{
+    /* FIXME: open pipe to lpr */
+    return NULL;
+}
+
+void printer_job_data(printer_job *pj, void *data, int len)
+{
+    /* FIXME: receive a pipe to lpr, write things to it */
+    assert(!"We shouldn't get here");
+}
+
+void printer_finish_job(printer_job *pj)
+{
+    /* FIXME: receive a pipe to lpr, close it */
+    assert(!"We shouldn't get here either");
+}
diff --git a/unix/uxstore.c b/unix/uxstore.c
new file mode 100644 (file)
index 0000000..76e19c1
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * uxstore.c: Unix-specific implementation of the interface defined
+ * in storage.h.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "putty.h"
+#include "storage.h"
+
+/* FIXME. For the moment, we do nothing at all here. */
+
+void *open_settings_w(char *sessionname)
+{
+    return NULL;
+}
+
+void write_setting_s(void *handle, char *key, char *value)
+{
+}
+
+void write_setting_i(void *handle, char *key, int value)
+{
+}
+
+void close_settings_w(void *handle)
+{
+}
+
+void *open_settings_r(char *sessionname)
+{
+    return NULL;
+}
+
+char *read_setting_s(void *handle, char *key, char *buffer, int buflen)
+{
+    return NULL;
+}
+
+int read_setting_i(void *handle, char *key, int defvalue)
+{
+    return defvalue;
+}
+
+void close_settings_r(void *handle)
+{
+}
+
+void del_settings(char *sessionname)
+{
+}
+
+void *enum_settings_start(void)
+{
+    return NULL;
+}
+
+char *enum_settings_next(void *handle, char *buffer, int buflen)
+{
+    return NULL;
+}
+
+void enum_settings_finish(void *handle)
+{
+}
+
+int verify_host_key(char *hostname, int port, char *keytype, char *key)
+{
+    return 1;                         /* key does not exist in registry */
+}
+
+void store_host_key(char *hostname, int port, char *keytype, char *key)
+{
+}
+
+void read_random_seed(noise_consumer_t consumer)
+{
+}
+
+void write_random_seed(void *data, int len)
+{
+}
+
+void cleanup_all(void)
+{
+}
diff --git a/unix/uxucs.c b/unix/uxucs.c
new file mode 100644 (file)
index 0000000..fbd4e96
--- /dev/null
@@ -0,0 +1,114 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <time.h>
+#include "putty.h"
+#include "misc.h"
+
+/*
+ * Unix Unicode-handling routines.
+ * 
+ * FIXME: currently trivial stub versions assuming all codepages
+ * are ISO8859-1.
+ */
+
+void lpage_send(int codepage, char *buf, int len, int interactive)
+{
+    ldisc_send(buf, len, interactive);
+}
+
+void luni_send(wchar_t * widebuf, int len, int interactive)
+{
+    static char *linebuffer = 0;
+    static int linesize = 0;
+    int ratio = (in_utf)?6:1;
+    int i;
+    char *p;
+
+    if (len * ratio > linesize) {
+       sfree(linebuffer);
+       linebuffer = smalloc(len * ratio * 2 * sizeof(wchar_t));
+       linesize = len * ratio * 2;
+    }
+
+    if (in_utf) {
+       /* UTF is a simple algorithm */
+       for (p = linebuffer, i = 0; i < len; i++) {
+           wchar_t ch = widebuf[i];
+
+           if ((ch&0xF800) == 0xD800) ch = '.';
+
+           if (ch < 0x80) {
+               *p++ = (char) (ch);
+           } else if (ch < 0x800) {
+               *p++ = (0xC0 | (ch >> 6));
+               *p++ = (0x80 | (ch & 0x3F));
+           } else if (ch < 0x10000) {
+               *p++ = (0xE0 | (ch >> 12));
+               *p++ = (0x80 | ((ch >> 6) & 0x3F));
+               *p++ = (0x80 | (ch & 0x3F));
+           } else if (ch < 0x200000) {
+               *p++ = (0xF0 | (ch >> 18));
+               *p++ = (0x80 | ((ch >> 12) & 0x3F));
+               *p++ = (0x80 | ((ch >> 6) & 0x3F));
+               *p++ = (0x80 | (ch & 0x3F));
+           } else if (ch < 0x4000000) {
+               *p++ = (0xF8 | (ch >> 24));
+               *p++ = (0x80 | ((ch >> 18) & 0x3F));
+               *p++ = (0x80 | ((ch >> 12) & 0x3F));
+               *p++ = (0x80 | ((ch >> 6) & 0x3F));
+               *p++ = (0x80 | (ch & 0x3F));
+           } else {
+               *p++ = (0xFC | (ch >> 30));
+               *p++ = (0x80 | ((ch >> 24) & 0x3F));
+               *p++ = (0x80 | ((ch >> 18) & 0x3F));
+               *p++ = (0x80 | ((ch >> 12) & 0x3F));
+               *p++ = (0x80 | ((ch >> 6) & 0x3F));
+               *p++ = (0x80 | (ch & 0x3F));
+           }
+       }
+    } else {
+       for (p = linebuffer, i = 0; i < len; i++) {
+           wchar_t ch = widebuf[i];
+           if (ch < 0x100)
+               *p++ = (char) ch;
+           else
+               *p++ = '.';
+       }
+    }
+    if (p > linebuffer)
+       ldisc_send(linebuffer, p - linebuffer, interactive);
+}
+
+int is_dbcs_leadbyte(int codepage, char byte)
+{
+    return 0;                         /* we don't do DBCS */
+}
+
+int mb_to_wc(int codepage, int flags, char *mbstr, int mblen,
+            wchar_t *wcstr, int wclen)
+{
+    int ret = 0;
+    while (mblen > 0 && wclen > 0) {
+       *wcstr++ = (unsigned char) *mbstr++;
+       ret++;
+    }
+    return ret;                               /* FIXME: check error codes! */
+}
+
+void init_ucs(void)
+{
+    int i;
+    /* Find the line control characters. FIXME: this is not right. */
+    for (i = 0; i < 256; i++)
+       if (i < ' ' || (i >= 0x7F && i < 0xA0))
+           unitab_ctrl[i] = i;
+       else
+           unitab_ctrl[i] = 0xFF;
+
+    for (i = 0; i < 256; i++) {
+       unitab_line[i] = unitab_scoacs[i] = i;
+       unitab_xterm[i] = i & 0x1F;
+    }
+}
\ No newline at end of file
index 9ea6c01..59757d9 100644 (file)
--- a/window.c
+++ b/window.c
@@ -4202,6 +4202,22 @@ void fatalbox(char *fmt, ...)
 }
 
 /*
+ * Print a modal (Really Bad) message box and perform a fatal exit.
+ */
+void modalfatalbox(char *fmt, ...)
+{
+    va_list ap;
+    char stuff[200];
+
+    va_start(ap, fmt);
+    vsprintf(stuff, fmt, ap);
+    va_end(ap);
+    MessageBox(hwnd, stuff, "PuTTY Fatal Error",
+              MB_SYSTEMMODAL | MB_ICONERROR | MB_OK);
+    cleanup_exit(1);
+}
+
+/*
  * Manage window caption / taskbar flashing, if enabled.
  * 0 = stop, 1 = maintain, 2 = start
  */
index f21053f..3bf43bc 100644 (file)
@@ -143,24 +143,23 @@ void fwdsetter(struct ctlpos *cp, int listid, char *stext, int sid,
 void defuse_showwindow(void);
 int do_config(void);
 int do_reconfig(HWND);
-void do_defaults(char *, Config *);
-void logevent(char *);
 void showeventlog(HWND);
 void showabout(HWND);
-void verify_ssh_host_key(char *host, int port, char *keytype,
-                        char *keystr, char *fingerprint);
-void askcipher(char *ciphername, int cs);
-int askappend(char *filename);
-void registry_cleanup(void);
 void force_normal(HWND hwnd);
 
-GLOBAL int nsessions;
-GLOBAL char **sessions;
-
 /*
  * Exports from sizetip.c.
  */
 void UpdateSizeTip(HWND src, int cx, int cy);
 void EnableSizeTip(int bEnable);
 
+/*
+ * Unicode and multi-byte character handling stuff.
+ */
+#define is_dbcs_leadbyte(cp, c) IsDBCSLeadByteEx(cp, c)
+#define mb_to_wc(cp, flags, mbstr, mblen, wcstr, wclen) \
+       MultiByteToWideChar(cp, flags, mbstr, mblen, wcstr, wclen)
+#define wc_to_mb(cp, flags, wcstr, wclen, mbstr, mblen, def, defused) \
+       WideCharToMultiByte(cp, flags, mbstr, mblen, wcstr, wclen, def,defused)
+
 #endif