From phaethon@linux.ucla.edu Fri Apr 12 00:32:22 2002
Received: from linux.ucla.edu (fire2.LINUX.UCLA.EDU [131.179.104.17])
	by stalker.iguide.co.il (8.9.3/8.9.3) with ESMTP id AAA29606
	for <vassilii@tarunz.org>; Fri, 12 Apr 2002 00:32:16 +0300
Received: from linux.ucla.edu (phaethon@localhost [127.0.0.1])
	by linux.ucla.edu (8.12.1/8.12.1/Debian -5) with ESMTP id g3BLYQOJ019970
	for <vassilii@tarunz.org>; Thu, 11 Apr 2002 14:34:26 -0700
Received: (from phaethon@localhost)
	by linux.ucla.edu (8.12.1/8.12.1/Debian -5) id g3BLYOT2019968
	for vassilii@tarunz.org; Thu, 11 Apr 2002 14:34:24 -0700
Date: Thu, 11 Apr 2002 14:34:23 -0700
From: Frederick Lee <phaethon@linux.ucla.edu>
To: vassilii@tarunz.org
Subject: Pilot VT100 patches
Message-ID: <20020411213422.GA19611@linux.ucla.edu>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
User-Agent: Mutt/1.3.28i

Vassilii Khachaturov,

Hi.  I've grown rather fond of Pilot VT100 despite its shortcomings, and hacked
on it a bit for my own benefit for use on my Palm IIIxe (PalmOS 3.5.2).

I've appended the relevant diff file (hopefully it comes through intact).

Things I added:
* Uses PalmOS SDK 4.0
 - Also uses the backwards compatibility library, libPalmOSGlue.a
* Expanded selection of baud rates
 - I think having a custom-rate option would be useful.
* Saving screen content across launches ("persistent" sessions)
 - Uses Unsaved Preferences DB.
 - This gives me "persistent sessions", so that I don't have to keep tapping
    out my settings every time I need to switch out and in of Pilot VT100.
 - Serial settings and Line state are preserved as well.
 - Screen content is not saved if Line state is off.
* Keymap remapping.  Notation is a mix of shell, C, and some others.
 - The caret (^) introduces a control character (e.g. "^C", "^D", "^@")
 - Backslash introduces character escaping (e.g. "\e", "\\", "\^", "\007")
 - ASCII ESC may be represented as either "\e" or "^[".
 - Similar dual form for other C \-sequences (\a ^G, \b ^H, \n ^J, etc)
 - Clearing the form field(s) restores default binding.
* Preferences DB for serial settings, keymap, screen content.
 - Done rather messily, but works for now.
 - Saving the screen content in (Unsaved) PrefsDB seems rather hefty.
* Options to convert(1) appears to have changed slightly over time.
 - In particular, the transparency color option

New bugs introduced:
* when the receive buffer overruns, keymap becomes inconsistent.


I can provide expanded explanations of these additions if you'd like.

-Fred

diff -ur vt100-orig/Makefile vt100-new/Makefile
--- vt100-orig/Makefile	Fri Aug 13 06:08:23 1999
+++ vt100-new/Makefile	Mon Apr  1 13:27:37 2002
@@ -15,7 +15,8 @@
 
 ### app config
 
-OBJS = term.o vt100.o keymap.o
+GLUELIB=/usr/share/prc-tools/sdk/lib/m68k-palmos-coff/libPalmOSGlue.a
+OBJS = term.o vt100.o keymap.o $(GLUELIB)
 APP = vt100
 export APP
 PRC = $(APP).prc
@@ -27,18 +28,19 @@
 DEVICE = /dev/pilot # symlink to wherever pilot is attached
 CODEVICE = /dev/copilot # symlink to /dev/ttyqe
 PORT=2000
-PALMINCS=/usr/local/m68k-palmos-coff/include/PalmOS2
+#PALMINCS=/usr/local/m68k-palmos-coff/include/PalmOS2
+PALMINCS=/usr/share/prc-tools/sdk/include
 RELEASE=1.0
 export RELEASE
 
 ### tool definitions
 
-CC = m68k-palmos-coff-gcc
+CC = m68k-palmos-gcc
 PILRC = pilrc
-OBJRES = m68k-palmos-coff-obj-res
+OBJRES = m68k-palmos-obj-res
 BUILDPRC = build-prc
-CFLAGS = -O2 -Wall -W -I$(PALMINCS)
-GDB=m68k-palmos-coff-gdb
+CFLAGS = -O2 -Wall -W -I$(PALMINCS) -DAPPID=$(APPID)
+GDB=m68k-palmos-gdb
 PILOT_XFER=pilot-xfer
 COPILOT = cd ..; xcopilot512 -double -serial
 
diff -ur vt100-orig/chcodes.h vt100-new/chcodes.h
--- vt100-orig/chcodes.h	Fri Jan 16 09:18:57 1998
+++ vt100-new/chcodes.h	Mon Apr  1 16:13:03 2002
@@ -2,3 +2,7 @@
 #define CTL(c) ((c) - 'A' + 1)
 #define CHAR_XOFF CTL('S')
 #define CHAR_XON CTL('Q')
+
+#define PREFIX_CONTROL '^'
+#define PREFIX_ESCAPE '\\'
+#define PREFIX_META '#'
diff -ur vt100-orig/docs/Makefile vt100-new/docs/Makefile
--- vt100-orig/docs/Makefile	Fri Aug 13 07:33:40 1999
+++ vt100-new/docs/Makefile	Sun Mar 31 23:59:43 2002
@@ -114,7 +114,7 @@
 # image convertors suite instead:
 zoom.%.gif: %.gif
 	giftopnm $< | pnmenlarge $(ZOOMFACTOR) | \
-		$(CONVERT) $(CONVERT_GIFFLAGS) -transparency white - gif:$@
+		$(CONVERT) $(CONVERT_GIFFLAGS) -transparent white - gif:$@
 
 webclean:
 	-rm -rf html *.prc
diff -ur vt100-orig/keymap.c vt100-new/keymap.c
--- vt100-orig/keymap.c	Fri Mar  6 07:00:25 1998
+++ vt100-new/keymap.c	Thu Apr 11 13:57:01 2002
@@ -1,8 +1,12 @@
 /* $Id: keymap.c,v 1.3 1998/01/16 17:18:11 vassilii Exp $ */
 
+#if 0
 #include <Common.h>
 #include <System/SysAll.h>
 #include <UI/UIAll.h>
+#endif /* 0 */
+#include <PalmOS.h>
+#include <PalmCompatibility.h>
 
 #include "rsrc.h"
 #include "keymap.h"
@@ -38,6 +42,59 @@
 	{1, {CTL('L')}} /* redraw screen in most terminal apps -- kinda HotSync...*/
 };
 
+
+int
+keymap_defaults (int mapentry)
+{
+  int i;
+
+#define SETKEY(n, sz, str) \
+  if ((mapentry < 0) || (mapentry == n)) { \
+    keymap[n].byteCharsActuallyUsed = sz; \
+    for (i = 0; i < sz; i++) { keymap[n].a_byteMapTo[i] = str[i]; } \
+  }
+
+  SETKEY(eKeyPageUp, 3, "\eOA");
+  SETKEY(eKeyPageDn, 3, "\eOB");
+  SETKEY(eKeyHard1, 1, "\003");
+  SETKEY(eKeyHard2, 3, "\eOD");
+  SETKEY(eKeyHard3, 3, "\eOC");
+  SETKEY(eKeyHard4, 1, "\n");
+  SETKEY(eKeyCradle, 1, "\014");
+  return 0;
+}
+
+
+Boolean
+keymap_getprefs (UInt32 appid, UInt16 prefid)
+{
+  UInt16 prefsize;
+  Int16 prefver;
+
+  prefsize = sizeof(keymap);
+  prefver = PrefGetAppPreferences(appid, prefid, &keymap, &prefsize, true);
+  if ((prefver == noPreferenceFound) || (prefsize != sizeof(keymap))) {
+    keymap_defaults(-1);
+    return false;
+  }
+  return true;
+}
+
+
+Boolean
+keymap_setprefs (UInt32 appid, UInt16 prefid)
+{
+  UInt16 prefsize;
+  Int16 prefver;
+
+  prefsize = sizeof(keymap);
+  prefver = VERSION;
+  PrefSetAppPreferences(appid, prefid, prefver, &keymap, prefsize, true);
+  return true;
+}
+
+
+
 Boolean
 keymap_RemapEvent (
 
@@ -90,4 +147,331 @@
 
 		return true;
 	}
+}
+
+
+
+int
+keymap_snprint (unsigned char *buf, int maxlen, int len, unsigned char *data)
+{
+  int buflen;
+  int i;
+  int ch;
+
+  *buf = 0;
+  buflen = 0;
+
+  for (i = 0; (i < len) && (buflen < maxlen - 4); i++) {
+/* Worse-case required space is 4 chars, for \NNN form. */
+    ch = data[i];
+#if 0
+printf("CH[%d] = %d\n", len, ch);
+#endif /* 0 */
+    if (ch < 32) {
+      switch (ch) {
+        /* check for \x forms before using ^x form. */
+        case '\e':
+          buf[buflen++] = PREFIX_ESCAPE;
+          buf[buflen++] = 'e';
+          break;
+        case '\r':
+          buf[buflen++] = PREFIX_ESCAPE;
+          buf[buflen++] = 'r';
+          break;
+        case '\n':
+          buf[buflen++] = PREFIX_ESCAPE;
+          buf[buflen++] = 'n';
+          break;
+        case '\t':
+          buf[buflen++] = PREFIX_ESCAPE;
+          buf[buflen++] = 't';
+          break;
+        default:
+          buf[buflen++] = PREFIX_CONTROL;
+          buf[buflen++] = (ch + 'A' - 1);
+          break;
+      }
+    } else {
+      switch (ch) {
+        /* Check for special \x forms. */
+        case PREFIX_ESCAPE:
+          buf[buflen++] = PREFIX_ESCAPE;
+          buf[buflen++] = PREFIX_ESCAPE;
+          break;
+        case PREFIX_CONTROL:
+          buf[buflen++] = PREFIX_ESCAPE;
+          buf[buflen++] = PREFIX_CONTROL;
+          break;
+#if 0
+        case PREFIX_META:
+          buf[buflen++] = PREFIX_ESCAPE;
+          buf[buflen++] = PREFIX_META;
+#endif
+        default:
+          buf[buflen++] = ch;
+          break;
+      } //switch
+    } //if ch range
+  } //for i in len
+
+  buf[buflen] = 0;
+
+
+#if 0
+  for (i = 0; i < buflen; i++) {
+    printf("CHAR %d = %d\n", i, buf[i]);
+  }
+  printf("BUFFER = %s\n", buf);
+#endif /* 0 */
+
+
+  return buflen;
+}
+
+
+
+int
+keymap_setform (FormPtr frm)
+{
+	FieldPtr fldp;
+	MemHandle mh;
+	MemPtr mp;
+    int mlen;
+
+/* Given a shorthand field name, assign the field value stored in keymap at entry number `mapentry'. */
+#define SETFIELD(btn, mapentry) \
+  fldp = FrmGetObjectPtr(frm, FrmGetObjectIndex(frm, buttons##btn##CodeField));\
+  mlen = CODE_CHARS_MAX * 4; \
+  mh = MemHandleNew(mlen); \
+  mp = MemHandleLock(mh); \
+  keymap_snprint(mp, mlen, keymap[mapentry].byteCharsActuallyUsed, keymap[mapentry].a_byteMapTo); \
+  MemPtrUnlock(mp); \
+  FldSetText(fldp, mh, 0, 32);
+
+	SETFIELD(Datebook, eKeyHard1);
+	SETFIELD(Address, eKeyHard2);
+	SETFIELD(ToDoList, eKeyHard3);
+	SETFIELD(MemoPad, eKeyHard4);
+	SETFIELD(PageUp, eKeyPageUp);
+	SETFIELD(PageDn, eKeyPageDn);
+	SETFIELD(HotSync, eKeyCradle);
+	return 0;
+}
+
+
+
+
+
+
+
+
+
+
+
+struct parser_s {
+  char *buf;
+  int len;
+  int pos;
+
+  char token[16];
+  int tokenlen;
+  int tokentype;
+};
+
+typedef struct parser_s parser_t;
+
+
+
+int
+keymap_parse_control (parser_t *parser)
+{
+  int ch;
+  int ate;
+
+  ate = 0;
+  ch = parser->buf[parser->pos];
+  parser->tokenlen = 1;
+  ate = 1;
+  if (parser->pos >= parser->len) {
+    /* Nothing left to read. */
+    parser->token[0] = PREFIX_CONTROL;
+    return 0;
+  }
+  if (('A' <= ch) && (ch <= 'Z')) {
+    ch = CTL(ch);
+    parser->token[0] = ch;
+  } else if (('a' <= ch) && (ch <= 'z')) {
+    ch = CTL(ch - 32);
+    parser->token[0] = ch;
+  } else if (('[' <= ch) && (ch <= '_')) {
+    ch = CTL(ch);
+    parser->token[0] = ch;
+  } else if ((ch == ' ') || (ch == '@')) {
+    ch = 0;
+    parser->token[0] = ch;
+  } else {
+    parser->token[0] = PREFIX_CONTROL;
+    parser->token[1] = ch;
+    parser->tokenlen = 2;
+  }
+
+#if 0
+  printf("CONTROL CHARACTER: %d\n", parser->token[0]);
+#endif /* 0 */
+  return ate;
+}
+
+int
+keymap_parse_escape (parser_t *parser)
+{
+  int ch;
+  int ate;
+
+  ate = 0;
+  parser->tokenlen = 1;
+  if (parser->pos >= parser->len) {
+    /* Nothing left to read. */
+    parser->token[0] = PREFIX_ESCAPE;
+    return 0;
+  }
+  ch = parser->buf[parser->pos];
+  ate = 1;
+  switch (ch) {
+    case 'a': /* alert (^G). */
+      parser->token[0] = '\a';
+      break;
+    case 'b': /* backspace (^H). */
+      parser->token[0] = '\b';
+      break;
+    case 'e': /* escape (^[). */
+      parser->token[0] = '\e';
+      break;
+    case 'f': /* formfeed (^L). */
+      parser->token[0] = '\f';
+      break;
+    case 'n': /* newline (^J). */
+      parser->token[0] = '\n';
+      break;
+    case 'r': /* carriage return (^M). */
+      parser->token[0] = '\r';
+      break;
+    case 't': /* tab (^I). */
+      parser->token[0] = '\t';
+      break;
+    case 'v': /* vertical tab (^K). */
+      parser->token[0] = '\v';
+      break;
+    case PREFIX_ESCAPE: /* backslash (\). */
+      parser->token[0] = PREFIX_ESCAPE;
+      break;
+    case PREFIX_CONTROL: /* caret (^). */
+      parser->token[0] = PREFIX_CONTROL;
+      break;
+    case PREFIX_META: /* hash (#). */
+      parser->token[0] = PREFIX_META;
+      break;
+    default:
+      if (('0' <= ch) && (ch <= '9')) {
+        /* Parse as octal. */
+        /* Terminates on: third character interpreted; end of string; non-digit */
+        ate = 0;
+        parser->token[0] = 0;
+        while (ate < 3) {
+          parser->token[0] *= 8;
+          parser->token[0] += (ch - '0');
+          ate++;
+          ch = parser->buf[parser->pos + ate];
+          if ((ch < '0') || ('9' < ch))
+            break;
+          if (parser->pos + ate >= parser->len)
+            break;
+        }
+      } else {
+        parser->token[0] = PREFIX_ESCAPE;
+        parser->token[1] = ch;
+        parser->tokenlen = 2;
+        ate = 1;
+      }
+      break;
+  }
+#if 0
+  printf("ESCAPED CHARACTER: %d\n", parser->token[0]);
+#endif /* 0 */
+  return ate;
+}
+
+int
+keymap_parse (unsigned char *buf, int maxlen, parser_t *parser)
+{
+  unsigned ch;
+  int buflen;
+  int i;
+
+  *buf = 0;
+  buflen = 0;
+  while (parser->pos < parser->len) {
+    ch = parser->buf[parser->pos++];
+    switch (ch) {
+      case PREFIX_CONTROL:
+        parser->pos += keymap_parse_control(parser);
+        break;
+      case PREFIX_ESCAPE:
+        parser->pos += keymap_parse_escape(parser);
+        break;
+      default:
+        parser->token[0] = ch;
+        parser->tokenlen = 1;
+#if 0
+        printf("ASCII CHARACTER: %c\n", ch);
+#endif /* 0 */
+        break;
+    }
+
+    for (i = 0; (i < parser->tokenlen) && (buflen < maxlen); i++) {
+#if 0
+printf("parsed append %d\n", parsedlen);
+#endif /* 0 */
+      buf[buflen++] = parser->token[i];
+    }
+  } //while
+#if 0
+  printf("parse done\n");
+  for (i = 0; i < parsedlen; i++) {
+    printf("CHAR %d = %d\n", i, parsed[i]);
+  }
+#endif /* 0 */
+  return buflen;
+}
+
+
+
+
+/* Sets keymap according to field entries of buttonForm. */
+int
+keymap_getform (FormPtr frm)
+{
+	FieldPtr fldp;
+    int mlen;
+	parser_t parser_opaque;
+
+#define GETFIELD(btn, mapentry) \
+  fldp = FrmGetObjectPtr(frm, FrmGetObjectIndex(frm, buttons##btn##CodeField));\
+  mlen = CODE_CHARS_MAX * 4; \
+  parser_opaque.buf = FldGetTextPtr(fldp); \
+  parser_opaque.len = FldGetTextLength(fldp); \
+  parser_opaque.pos = 0; \
+  if (parser_opaque.len < 1) { \
+    keymap_defaults(mapentry); \
+  } else { \
+    keymap[mapentry].byteCharsActuallyUsed = keymap_parse(keymap[mapentry].a_byteMapTo, CODE_CHARS_MAX, &parser_opaque); \
+  }
+
+	GETFIELD(Datebook, eKeyHard1);
+	GETFIELD(Address, eKeyHard2);
+	GETFIELD(ToDoList, eKeyHard3);
+	GETFIELD(MemoPad, eKeyHard4);
+	GETFIELD(PageUp, eKeyPageUp);
+	GETFIELD(PageDn, eKeyPageDn);
+	GETFIELD(HotSync, eKeyCradle);
+	return 0;
 }
diff -ur vt100-orig/keymap.h vt100-new/keymap.h
--- vt100-orig/keymap.h	Tue Dec 30 04:22:45 1997
+++ vt100-new/keymap.h	Mon Apr  1 17:18:35 2002
@@ -1 +1,6 @@
 Boolean keymap_RemapEvent (EventPtr event);
+int keymap_defaults (int mapentry);
+Boolean keymap_getprefs (UInt32, UInt16);
+Boolean keymap_setprefs (UInt32, UInt16);
+int keymap_setform (FormPtr frm);
+int keymap_getform (FormPtr frm);
diff -ur vt100-orig/rsrc.h vt100-new/rsrc.h
--- vt100-orig/rsrc.h	Fri Mar  6 05:37:12 1998
+++ vt100-new/rsrc.h	Mon Apr  1 20:09:26 2002
@@ -36,6 +36,7 @@
 #define prefsBaudLabel 0x1203
 #define prefsLocalEchoCheck 0x1204
 #define prefsResetAutoOffCheck 0x1205
+#define prefsXonXoffCheck 0x1206
 
 #define prefsDataLabel 0x1210
 // cf. serSettingsFlagBitsPerChar5, ..., serSettingsFlagBitsPerChar8
diff -ur vt100-orig/term.c vt100-new/term.c
--- vt100-orig/term.c	Fri Jul  9 17:39:38 1999
+++ vt100-new/term.c	Mon Apr  1 20:49:06 2002
@@ -5,11 +5,18 @@
 #define BENCHno
 #define XON_XOFF
 
+#if 0
 #include <Common.h>
 #include <System/SysAll.h>
 #include <System/SerialMgr.h>
 #include <System/SysEvtMgr.h>
 #include <UI/UIAll.h>
+#endif
+
+#include <PalmOS.h>
+#include <PalmCompatibility.h>
+#include <PalmOSGlue.h>
+#include <SerialMgrOld.h>
 
 #ifdef BENCH
 #include <System/TimeMgr.h>
@@ -55,8 +62,10 @@
 
 enum { 
 	baud_1200, baud_2400, baud_4800, baud_9600, baud_19200,
+    baud_28800, baud_38400, baud_57600, baud_115200,
+    baud_230400, baud_460800,
 	BAUD_MAX };
-static int bauds[BAUD_MAX] = { 1200, 2400, 4800, 9600, 19200 };
+static UInt32 bauds[BAUD_MAX] = { 1200, 2400, 4800, 9600, 19200, 28800, 38400, 57600, 115200, 230400, 460800 };
 static int iCurBaud = baud_2400;
 static SerSettingsType serial_settings = { /* see <System/SerialMgr.h> */
 	2400,
@@ -104,6 +113,9 @@
 static void EventLoop(void);
 static int cursor_active;
 
+static void StartSerial(void);
+static void SetControlValueByRscId(FormPtr frm, Word objID, short Value);
+void std_interpret_char(struct virtscreen *, int);
 
 void RefreshRegion(int rx, int ry, int w, int h)
 {
@@ -162,7 +174,7 @@
     rect.topLeft.y = (top /* +1 */)*CELLHEIGHT;
 
     CursorOff();
-    WinScrollRectangle(&rect, up, CELLHEIGHT, &rect2);
+    WinScrollRectangle(&rect, winUp, CELLHEIGHT, &rect2);
     CursorOn();    
 }
 
@@ -288,7 +300,13 @@
     FormPtr frm;
     VoidHand FontBH;
     BitmapPtr FontBP;
+#ifndef ALLOW_ACCESS_TO_INTERNALS_OF_BITMAPS
+    UInt16 fontwidth, fontheight, fontrowbytes;
+#endif /* no struct-banging. */
     Word error;
+    UInt16 prefsize;
+    Int16 prefver;
+    UInt32 prefval;
 
     cursor_active = 1;    
     
@@ -297,8 +315,14 @@
     FontBH = DmGetResource(bitmapRsc, fontBitmap);
     FontBP = MemHandleLock(FontBH);
     
+#ifdef ALLOW_ACCESS_TO_INTERNALS_OF_BITMAPS
     FontWH = WinCreateOffscreenWindow(FontBP->width, FontBP->height,
                                       screenFormat, &error);
+#else /* no struct-banging. */
+    BmpGlueGetDimensions(FontBP, &fontwidth, &fontheight, &fontrowbytes);
+    FontWH = WinCreateOffscreenWindow(fontwidth, fontheight,
+                                      screenFormat, &error);
+#endif /* no struct-banging. */
     ErrFatalDisplayIf(error, "Error loading glyphs");
     WinSetDrawWindow(FontWH);
     WinDrawBitmap(FontBP, 0, 0);
@@ -319,6 +343,69 @@
     
     SetCurrentMenu(mainMenu);
 
+/* Set program state from stored prefs. */
+    /* Baud rate */
+    prefsize = sizeof(prefval);
+    prefver = PrefGetAppPreferences(CREATORID, 1, &prefval, &prefsize, true);
+    if (prefver != noPreferenceFound) {
+      iCurBaud = prefval;
+    }
+    serial_settings.baudRate = bauds[iCurBaud];
+    /* serial flags. */
+    prefsize = sizeof(prefval);
+    prefver = PrefGetAppPreferences(CREATORID, 2, &prefval, &prefsize, true);
+    if (prefver == VERSION) {
+      serial_settings.flags = prefval;
+    }
+    /* Local echo */
+    prefsize = sizeof(prefval);
+    prefver = PrefGetAppPreferences(CREATORID, 3, &prefval, &prefsize, true);
+    if (prefver == VERSION) {
+      local_echo = prefval;
+    }
+    /* Auto-off */
+    prefsize = sizeof(prefval);
+    prefver = PrefGetAppPreferences(CREATORID, 4, &prefval, &prefsize, true);
+    if (prefver == VERSION) {
+      tty_activity_resets_autooff = prefval;
+    }
+    /* Online */
+    prefsize = sizeof(prefval);
+    prefver = PrefGetAppPreferences(CREATORID, 5, &prefval, &prefsize, true);
+    if (prefver == VERSION) {
+      if (prefval) {
+        StartSerial();
+      }
+      online = prefval;
+    }
+    SetControlValueByRscId(frm, mainOnline, online);
+    /* Screen buffer.  Crazy shit. */
+    if (online) {
+      prefsize = sizeof(curscreen);
+      prefver = PrefGetAppPreferences(CREATORID, 6, &curscreen, &prefsize, false);
+       /* Don't want this saved across hard-reset restores. */
+      if (prefver == VERSION) {
+        prefsize = curscreen.rows * curscreen.columns;
+        prefver = PrefGetAppPreferences(CREATORID, 7, curscreen.data, &prefsize, false);
+        if (prefver == VERSION) {
+          curscreen.data_off_scr = curscreen.data;
+          curscreen.next_char_send = std_interpret_char;
+          CursorOff();
+          cursor_x = curscreen.xpos;
+          cursor_y = curscreen.ypos;
+          RefreshRegion(0, 0, curscreen.columns, curscreen.rows);
+          CursorOn();
+        } else {
+          init_virtscreen(&curscreen,screen,HEIGHT,WIDTH);
+        }
+      } else {
+        init_virtscreen(&curscreen,screen,HEIGHT,WIDTH);
+      }
+    }
+    /* Keymap preferences. */
+    keymap_getprefs(CREATORID, 8);
+
+
 #ifdef BENCH
     BenchMark();    
 #endif    
@@ -329,7 +416,7 @@
 #endif
 }
 
-#define SBUFSIZE (1024 * 6)
+#define SBUFSIZE (1024 * 8)
 #define SBUFSIZE_SYS SBUFSIZE+32 /* see the SerSetReceiveBuffer() docs */
 #define RECV_LOW_WATER (SBUFSIZE * 1 / 32)
 #define RECV_HIGH_WATER (SBUFSIZE * 1 / 8)
@@ -421,7 +508,17 @@
         if(SerOpen(SerialRefNum, 0, bauds[iCurBaud])){
             ErrDisplay("Cannot Open Serial Lib");
         }
-		else { /* See also <System/SerialMgr.h> */
+		else { /* See also <System/SerialMgr.h> */ /* <Core/System/SerialMgrOld.h> */
+            /* Maximal theoretical speed of 1Mbit (36*12*2400?) */
+            /* 19200 bps is fastest safe speed without CTS handshaking. */
+#if 0 /* WTF is CTS handshaking? */
+            if (bauds[iCurBaud] > 19200) {
+              serial_settings.flags |= (serSettingsFlagCTSAutoM | serSettingsFlagRTSAutoM);
+              serial_settings.ctsTimeout = serDefaultCTSTimeout;
+            } else {
+              serial_settings.flags &= ~serSettingsFlagCTSAutoM;
+            }
+#endif
 			SerSetSettings(SerialRefNum, &serial_settings);                
 			ErrFatalDisplayIf(
 				SerSetReceiveBuffer(
@@ -451,9 +548,43 @@
 
 static void StopApplication(void)
 { 
+    UInt16 prefsize;
+    Int16 prefver;
+    UInt32 prefval;
 #ifdef HW_CURSOR
     InsPtEnable(0);    
 #endif
+/* Store settings. */
+    prefver = VERSION;
+    prefsize = sizeof(prefval);
+
+    /* Baud rate. */
+    prefval = iCurBaud;
+    PrefSetAppPreferences(CREATORID, 1, prefver, &prefval, prefsize, true);
+    /* Serial flags. */
+    prefval = serial_settings.flags;
+    PrefSetAppPreferences(CREATORID, 2, prefver, &prefval, prefsize, true);
+    /* Local echo */
+    prefval = local_echo;
+    PrefSetAppPreferences(CREATORID, 3, prefver, &prefval, prefsize, true);
+    /* Auto-off */
+    prefval = tty_activity_resets_autooff;
+    PrefSetAppPreferences(CREATORID, 4, prefver, &prefval, prefsize, true);
+    /* Online */
+    prefval = online;
+    PrefSetAppPreferences(CREATORID, 5, prefver, &prefval, prefsize, true);
+
+    if (online) {
+      StopSerial();
+/* Save buffer. */
+      prefsize = sizeof(curscreen);
+      PrefSetAppPreferences(CREATORID, 6, prefver, &curscreen, prefsize, false);
+      prefsize = curscreen.num_bytes;
+      PrefSetAppPreferences(CREATORID, 7, prefver, curscreen.data, prefsize, false);
+    }
+    /* Keymap preferences. */
+    keymap_setprefs(CREATORID, 8);
+
         /* Release Glyph Bitmaps */
     WinDeleteWindow(FontWH, false);
 } 
@@ -526,7 +657,7 @@
 				Word idForm = (idItem & 0xff) << 8;
 					/* see the rsrc.h for the IDs conventions required here */
 				FormPtr frm = FrmInitForm(idForm);
-				ListPtr pBaudList;
+				ListPtr pBaudList = 0; /* Make gcc happy. */
 					/* init. in first switch, reused in the second */
 
 				/* We could have vectorized the form-specific init
@@ -547,6 +678,10 @@
 							tty_activity_resets_autooff);
 
 						SetControlValueByRscId(frm,
+							prefsXonXoffCheck,
+							serial_settings.flags & serSettingsFlagXonXoffM);
+
+						SetControlValueByRscId(frm,
 								prefsDataCommon | (serial_settings.flags 
 									& serSettingsFlagBitsPerCharM),
 							1);
@@ -558,6 +693,14 @@
 								prefsParityCommon | (serial_settings.flags 
 									& serSettingsFlagParityM),
 							1);
+						SetControlValueByRscId(frm,
+								prefsParityCommon | (serial_settings.flags 
+									& serSettingsFlagParityM),
+							1);
+						SetControlValueByRscId(frm,
+								prefsParityCommon | (serial_settings.flags 
+									& serSettingsFlagParityM),
+							1);
 
 						pBaudList = FrmGetObjectPtr(frm,
 							FrmGetObjectIndex(frm, prefsBaudList));
@@ -571,7 +714,8 @@
 						break;
 
 					case buttonsForm:
-
+						keymap_setform(frm);
+						break;
 					default:
 				}
 
@@ -592,6 +736,11 @@
 							iCurBaud = LstGetSelection(pBaudList);
 							serial_settings.baudRate = bauds[iCurBaud];
 							serial_settings.flags &= ~SELECTABLE_SERIAL_FLAGS_MASK;
+							if (FrmGetControlValue(frm,FrmGetObjectIndex(frm, prefsXonXoffCheck))) {
+								serial_settings.flags |= serSettingsFlagXonXoffM;
+							} else {
+								serial_settings.flags &= ~serSettingsFlagXonXoffM;
+							}
 							serial_settings.flags |= (
 									FrmGetObjectId(frm,
 										FrmGetControlGroupSelection(frm, 
@@ -611,6 +760,8 @@
 							break;
 
 						case buttonsForm:
+							keymap_getform(frm);
+							break;
 
 						default:
 					}
@@ -671,7 +822,7 @@
 						FrmHandleEvent(FrmGetActiveForm(), &event);
     } while (event.eType != appStopEvent);
 
-    if(online) StopSerial();
+//    if(online) StopSerial();
 }
 
 
diff -ur vt100-orig/vt100.c vt100-new/vt100.c
--- vt100-orig/vt100.c	Thu Mar  5 13:26:08 1998
+++ vt100-new/vt100.c	Mon Apr  1 00:10:36 2002
@@ -1,8 +1,13 @@
 /* vt100.c */
 /* vt100 engine copyright 1997, Daniel Marks */
 
+#if 0
 #include <Common.h>
 #include <System/SysAll.h>
+#endif /* 0 */
+
+#include <PalmOS.h>
+#include <PalmCompatibility.h>
 
 /*
   #include <stdio.h>
diff -ur vt100-orig/vt100.h vt100-new/vt100.h
--- vt100-orig/vt100.h	Tue Dec 30 04:28:10 1997
+++ vt100-new/vt100.h	Mon Apr  1 12:36:40 2002
@@ -1,6 +1,11 @@
 #ifndef _VT_100_H
 #define _VT_100_H
 
+#define CREATORID 'vt1x'
+#define PACKAGE "Pilot VT100"
+/* VERSION within 0x0000 .. 0x7FFF, for PalmOS Prefs database */
+#define VERSION 0x0001
+
 #define loc_in_virtscreen(cur,y,x) (((cur)->data)+(((y)*((cur)->columns))+(x)))
 #define MAX_ANSI_ELEMENTS 16
 #define char_to_virtscreen(cur,ch) (((cur)->next_char_send)((cur),(ch)))
diff -ur vt100-orig/vt100.rsc.in vt100-new/vt100.rsc.in
--- vt100-orig/vt100.rsc.in	Fri Aug 13 06:12:30 1999
+++ vt100-new/vt100.rsc.in	Mon Apr  1 20:17:54 2002
@@ -45,21 +45,22 @@
 	FIELD ID buttonsHotSyncCodeField AT (80 PREVBOTTOM+5 35 AUTO) FONT 0 UNDERLINED MAXCHARS CODE_CHARS_MAX
 	LABEL "HotSync:" ID buttonsHotSyncLabel AT (PREVLEFT-51 PREVTOP) FONT 1
 
-	BUTTON "OK" ID OkBtn AT (10 137 AUTO AUTO ) FONT 2 NONUSABLE
+	BUTTON "OK" ID OkBtn AT (10 137 AUTO AUTO ) FONT 2
 	BUTTON "Cancel" ID CancelBtn AT (PREVRIGHT+4 PREVTOP AUTO AUTO ) FONT 2
 	GRAFFITISTATEINDICATOR AT (140 PREVTOP+3)
 END
 
 // XXX To add: 
 //	* flow control
+/* FORM prefsForm 2 22 156 120 */
 FORM prefsForm 2 22 156 120
 MODAL
 BEGIN
 	TITLE "vt100: comm. settings"
 
-	POPUPTRIGGER "" ID prefsBaud AT (37 16 AUTO AUTO)
+	POPUPTRIGGER "" ID prefsBaud AT (37 16 AUTO AUTO) RIGHTANCHOR
 	LABEL "baud" ID prefsBaudLabel AT (PREVRIGHT PREVTOP) FONT 1
-	LIST "1200" "2400" "4800" "9600" "19200" ID prefsBaudList AT (PREVLEFT-30 PREVTOP 40 1 ) NONUSABLE VISIBLEITEMS 5
+	LIST "1200" "2400" "4800" "9600" "19200" "28800" "38400" "57600" "115200" "230400" "460800" ID prefsBaudList AT (PREVLEFT-30 PREVTOP 40 1 ) NONUSABLE VISIBLEITEMS 9
         POPUPLIST prefsBaud prefsBaudList
 
 	PUSHBUTTON "5" ID prefsData5 AT (5 PREVBOTTOM-PREVHEIGHT+13 AUTO AUTO) GROUP prefsDataGroup
@@ -77,8 +78,17 @@
 	PUSHBUTTON "2" ID prefsStop2 AT (PREVRIGHT+1 PREVTOP AUTO AUTO) GROUP prefsStopGroup
 	LABEL "stop bits" ID prefsStopLabel AT (PREVRIGHT+3 PREVTOP) FONT 1
 
-	CHECKBOX "local echo" ID prefsLocalEchoCheck AT (38 PREVBOTTOM+1 AUTO AUTO) FONT 1
+/*
 	CHECKBOX "I/O resets auto-off" ID prefsResetAutoOffCheck AT (38 PREVBOTTOM+1 AUTO AUTO) FONT 1
+*/
+	CHECKBOX "I/O resets auto-off" ID prefsResetAutoOffCheck AT (38 PREVBOTTOM+2 AUTO AUTO) FONT 1
+
+/*
+	CHECKBOX "local echo" ID prefsLocalEchoCheck AT (38 PREVBOTTOM+1 AUTO AUTO) FONT 1
+	CHECKBOX "XON/XOFF" ID prefsXonXoffCheck AT (38 PREVBOTTOM+1 AUTO AUTO) FONT 1
+*/
+	CHECKBOX "local echo" ID prefsLocalEchoCheck AT (2 PREVBOTTOM+1 AUTO AUTO) FONT 1
+	CHECKBOX "XON/XOFF" ID prefsXonXoffCheck AT (76 PREVTOP AUTO AUTO) FONT 1
 
 	BUTTON "OK" ID OkBtn AT (2 PREVBOTTOM+6 AUTO AUTO) FONT 0
 	BUTTON "Cancel" ID CancelBtn AT (PREVRIGHT+4 PREVTOP AUTO AUTO) FONT 0
