Saving/Restoring state into ~/.pynche file
diff --git a/Tools/pynche/ChipViewer.py b/Tools/pynche/ChipViewer.py
index ef70e95..fbf9aad 100644
--- a/Tools/pynche/ChipViewer.py
+++ b/Tools/pynche/ChipViewer.py
@@ -110,3 +110,6 @@
         colorname = self.__nearest.get_color()
         red, green, blue = self.__sb.colordb().find_byname(colorname)
         self.__sb.update_views(red, green, blue)
+
+    def save_options(self, optiondb):
+        pass
diff --git a/Tools/pynche/DetailsViewer.py b/Tools/pynche/DetailsViewer.py
index 35e4853..da9bbf9 100644
--- a/Tools/pynche/DetailsViewer.py
+++ b/Tools/pynche/DetailsViewer.py
@@ -63,6 +63,7 @@
 class DetailsViewer:
     def __init__(self, switchboard, parent=None):
         self.__sb = switchboard
+        optiondb = switchboard.optiondb()
         self.__red, self.__green, self.__blue = switchboard.current_rgb()
         # GUI
         root = self.__root = Toplevel(parent, class_='Pynche')
@@ -87,21 +88,21 @@
         self.__l1 = Label(frame, text='Move Sliders:')
         self.__l1.grid(row=1, column=0, sticky=E)
         self.__rvar = IntVar()
-        self.__rvar.set(4)
+        self.__rvar.set(optiondb.get('RSLIDER', 4))
         self.__radio1 = Checkbutton(frame, text='Red',
                                     variable=self.__rvar,
                                     command=self.__effect,
                                     onvalue=4, offvalue=0)
         self.__radio1.grid(row=1, column=1, sticky=W)
         self.__gvar = IntVar()
-        self.__gvar.set(2)
+        self.__gvar.set(optiondb.get('GSLIDER', 2))
         self.__radio2 = Checkbutton(frame, text='Green',
                                     variable=self.__gvar,
                                     command=self.__effect,
                                     onvalue=2, offvalue=0)
         self.__radio2.grid(row=2, column=1, sticky=W)
         self.__bvar = IntVar()
-        self.__bvar.set(1)
+        self.__bvar.set(optiondb.get('BSLIDER', 1))
         self.__radio3 = Checkbutton(frame, text='Blue',
                                     variable=self.__bvar,
                                     command=self.__effect,
@@ -115,7 +116,7 @@
         self.__l3 = Label(frame, text='At boundary:')
         self.__l3.grid(row=5, column=0, sticky=E)
         self.__boundvar = StringVar()
-        self.__boundvar.set(STOP)
+        self.__boundvar.set(optiondb.get('ATBOUND', STOP))
         self.__omenu = OptionMenu(frame, self.__boundvar,
                                   STOP, WRAP, RATIO, GRAV)
         self.__omenu.grid(row=5, column=1, sticky=W)
@@ -262,3 +263,9 @@
         self.__red = red
         self.__green = green
         self.__blue = blue
+
+    def save_options(self, optiondb):
+        optiondb['RSLIDER'] = self.__rvar.get()
+        optiondb['GSLIDER'] = self.__gvar.get()
+        optiondb['BSLIDER'] = self.__bvar.get()
+        optiondb['ATBOUND'] = self.__boundvar.get()
diff --git a/Tools/pynche/ListViewer.py b/Tools/pynche/ListViewer.py
index 8c8a6ee..9ba2a53 100644
--- a/Tools/pynche/ListViewer.py
+++ b/Tools/pynche/ListViewer.py
@@ -21,6 +21,7 @@
 class ListViewer:
     def __init__(self, switchboard, parent=None):
         self.__sb = switchboard
+        optiondb = switchboard.optiondb()
         self.__lastbox = None
         self.__dontcenter = 0
         # GUI
@@ -76,7 +77,7 @@
         #
         # Update on click
         self.__uoc = BooleanVar()
-        self.__uoc.set(1)
+        self.__uoc.set(optiondb.get('UPONCLICK', 1))
         self.__uocbtn = Checkbutton(root,
                                     text='Update on Click',
                                     variable=self.__uoc,
@@ -160,3 +161,6 @@
             ig, ig, ig, y2 = canvas.coords(self.__bboxes[-1])
             h = int(canvas['height']) * 0.5
             canvas.yview('moveto', (y1-h) / y2)
+
+    def save_options(self, optiondb):
+        optiondb['UPONCLICK'] = self.__uoc.get()
diff --git a/Tools/pynche/Main.py b/Tools/pynche/Main.py
index b86bea2..bb5329e 100644
--- a/Tools/pynche/Main.py
+++ b/Tools/pynche/Main.py
@@ -12,13 +12,26 @@
 tested on Solaris 2.6.  Feedback is greatly appreciated.  Send email to
 bwarsaw@python.org
 
-Usage: %(PROGRAM)s [-d file] [-h] [initialcolor]
+Usage: %(PROGRAM)s [-d file] [-i file] [-X] [-h] [initialcolor]
 
 Where:
     --database file
     -d file
         Alternate location of a color database file
 
+    --initfile file
+    -i file
+        Alternate location of the initialization file.  This file contains a
+        persistent database of the current Pynche options and color.  This
+        means that Pynche restores its option settings and current color when
+        it restarts, using this file (unless the -X option is used).  The
+        default is ~/.pynche
+
+    --ignore
+    -X
+        Ignore the initialization file when starting up.  Pynche will still
+        write the current option settings to this file when it quits.
+
     --help
     -h
         print this message
@@ -49,7 +62,7 @@
     # Solaris OpenWindows
     '/usr/openwin/lib/rgb.txt',
     # The X11R6.4 rgb.txt file
-    os.path.join(sys.path[0], 'rgb.txt'),
+    os.path.join(sys.path[0], 'X/rgb.txt'),
     # add more here
     ]
 
@@ -95,23 +108,29 @@
     try:
 	opts, args = getopt.getopt(
             sys.argv[1:],
-            'hd:',
-            ['database=', 'help'])
+            'hd:i:X',
+            ['database=', 'initfile=', 'ignore', 'help'])
     except getopt.error, msg:
 	usage(1, msg)
 
     if len(args) == 0:
-        initialcolor = 'grey50'
+        initialcolor = None
     elif len(args) == 1:
         initialcolor = args[0]
     else:
 	usage(1)
 
+    ignore = 0
+    initfile = os.path.expanduser('~/.pynche')
     for opt, arg in opts:
 	if opt in ('-h', '--help'):
 	    usage(0)
 	elif opt in ('-d', '--database'):
 	    RGB_TXT.insert(0, arg)
+        elif opt in ('-X', '--ignore'):
+            ignore = 1
+        elif opt in ('-i', '--initfile'):
+            initfile = arg
 
     # create the windows and go
     for f in RGB_TXT:
@@ -124,11 +143,8 @@
     else:
         usage(1, 'No color database file found, see the -d option.')
 
-    # get the initial color as components
-    red, green, blue = initial_color(initialcolor, colordb)
-
     # create all output widgets
-    s = Switchboard(colordb)
+    s = Switchboard(colordb, not ignore and initfile)
 
     # create the application window decorations
     app = PyncheWidget(__version__, s)
@@ -137,6 +153,20 @@
     s.add_view(StripViewer(s, parent))
     s.add_view(ChipViewer(s, parent))
     s.add_view(TypeinViewer(s, parent))
+
+    # get the initial color as components and set the color on all views.  if
+    # there was no initial color given on the command line, use the one that's 
+    # stored in the option database
+    if initialcolor is None:
+        optiondb = s.optiondb()
+        red = optiondb.get('RED')
+        green = optiondb.get('GREEN')
+        blue = optiondb.get('BLUE')
+        # but if there wasn't any stored in the database, use grey50
+        if red is None or blue is None or green is None:
+            red, green, blue = initial_color('grey50', colordb)
+    else:
+        red, green, blue = initial_color(initialcolor, colordb)
     s.update_views(red, green, blue)
 
     try:
@@ -144,6 +174,9 @@
     except KeyboardInterrupt:
 	pass
 
+    # save the option database
+    s.save_views(initfile)
+
 
 
 if __name__ == '__main__':
diff --git a/Tools/pynche/PyncheWidget.py b/Tools/pynche/PyncheWidget.py
index c4df038..4052357 100644
--- a/Tools/pynche/PyncheWidget.py
+++ b/Tools/pynche/PyncheWidget.py
@@ -60,7 +60,7 @@
         # Help menu
         #
         helpmenu = Menu(menubar, name='help', tearoff=0)
-	helpmenu.add_command(label='About...',
+	helpmenu.add_command(label='About Pynche...',
                              command=self.__popup_about,
                              underline=0)
         #
@@ -111,7 +111,7 @@
 Copyright (C) 1998 CNRI
 All rights reserved
 
-For information about Pynche contact
+For information contact
 author: Barry A. Warsaw
 email : bwarsaw@python.org''' % __version__)
 
diff --git a/Tools/pynche/StripViewer.py b/Tools/pynche/StripViewer.py
index 84fe741..7bbfcca 100644
--- a/Tools/pynche/StripViewer.py
+++ b/Tools/pynche/StripViewer.py
@@ -298,11 +298,14 @@
 class StripViewer:
     def __init__(self, switchboard, parent=None):
         self.__sb = switchboard
+        optiondb = switchboard.optiondb()
         # create a frame inside the parent
         self.__frame = Frame(parent) #, relief=GROOVE, borderwidth=2)
         self.__frame.grid(row=1, column=0, columnspan=2, sticky='EW')
-        uwd = BooleanVar()
-        hexp = BooleanVar()
+        uwd = self.__uwdvar = BooleanVar()
+        uwd.set(optiondb.get('UPWHILEDRAG', 0))
+        hexp = self.__hexpvar = BooleanVar()
+        hexp.set(optiondb.get('HEXSTRIP', 0))
         self.__reds = StripWidget(switchboard, self.__frame,
                                   generator=constant_cyan_generator,
                                   axis=0,
@@ -349,3 +352,7 @@
     def __togglehex(self, event=None):
         red, green, blue = self.__sb.current_rgb()
         self.update_yourself(red, green, blue)
+
+    def save_options(self, optiondb):
+        optiondb['UPWHILEDRAG'] = self.__uwdvar.get()
+        optiondb['HEXSTRIP'] = self.__hexpvar.get()
diff --git a/Tools/pynche/Switchboard.py b/Tools/pynche/Switchboard.py
index 4286b48..7ac3df1 100644
--- a/Tools/pynche/Switchboard.py
+++ b/Tools/pynche/Switchboard.py
@@ -12,13 +12,32 @@
       since this would cause it to get updated twice.
 """
 
+from types import DictType
+import marshal
+
 class Switchboard:
-    def __init__(self, colordb):
-        self.__views = []
+    def __init__(self, colordb, initfile):
         self.__colordb = colordb
+        self.__optiondb = {}
+        self.__views = []
         self.__red = 0
         self.__green = 0
         self.__blue = 0
+        # read the initialization file
+        fp = None
+        if initfile:
+            try:
+                try:
+                    fp = open(initfile)
+                    self.__optiondb = marshal.load(fp)
+                    if type(self.__optiondb) <> DictType:
+                        print 'Problem reading options from file:', initfile
+                        self.__optiondb = {}
+                except (IOError, EOFError):
+                    pass
+            finally:
+                if fp:
+                    fp.close()
 
     def add_view(self, view):
         self.__views.append(view)
@@ -38,3 +57,25 @@
 
     def colordb(self):
         return self.__colordb
+
+    def optiondb(self):
+        return self.__optiondb
+
+    def save_views(self, file):
+        # save the current color
+        self.__optiondb['RED'] = self.__red
+        self.__optiondb['GREEN'] = self.__green
+        self.__optiondb['BLUE'] = self.__blue
+        for v in self.__views:
+            v.save_options(self.__optiondb)
+        fp = None
+        try:
+            try:
+                fp = open(file, 'w')
+            except IOError:
+                print 'Cannot write options to file:', file
+            else:
+                marshal.dump(self.__optiondb, fp)
+        finally:
+            if fp:
+                fp.close()
diff --git a/Tools/pynche/TextViewer.py b/Tools/pynche/TextViewer.py
index 254e7e0..7e8cec5 100644
--- a/Tools/pynche/TextViewer.py
+++ b/Tools/pynche/TextViewer.py
@@ -21,6 +21,7 @@
 class TextViewer:
     def __init__(self, switchboard, parent=None):
         self.__sb = switchboard
+        optiondb = switchboard.optiondb()
         root = self.__root = Toplevel(parent, class_='Pynche')
         root.protocol('WM_DELETE_WINDOW', self.__withdraw)
         root.title('Pynche Text Window')
@@ -33,11 +34,20 @@
         # create the text widget
         #
         self.__text = Text(root, relief=SUNKEN,
-                           background='black',
-                           foreground='white',
+                           background=optiondb.get('TEXTBG', 'black'),
+                           foreground=optiondb.get('TEXTFG', 'white'),
                            width=35, height=15)
+        sfg = optiondb.get('TEXT_SFG')
+        if sfg:
+            self.__text.configure(selectforeground=sfg)
+        sbg = optiondb.get('TEXT_SBG')
+        if sbg:
+            self.__text.configure(selectbackground=sbg)
+        ibg = optiondb.get('TEXT_IBG')
+        if ibg:
+            self.__text.configure(insertbackground=ibg)
         self.__text.pack()
-        self.__text.insert(0.0, '''\
+        self.__text.insert(0.0, optiondb.get('TEXT', '''\
 Insert some stuff here and play
 with the buttons below to see
 how the colors interact in
@@ -45,14 +55,23 @@
 
 See how the selection can also
 be affected by tickling the buttons
-and choosing a color.''')
-        self.__text.tag_add(SEL, 6.0, END)
+and choosing a color.'''))
+        insert = optiondb.get('TEXTINS')
+        if insert:
+            self.__text.mark_set(INSERT, insert)
+        try:
+            start, end = optiondb.get('TEXTSEL', (6.0, END))
+            self.__text.tag_add(SEL, start, end)
+        except ValueError:
+            # selection wasn't set
+            pass
+        self.__text.focus_set()
         #
         # variables
         self.__trackp = BooleanVar()
-        self.__trackp.set(0)
+        self.__trackp.set(optiondb.get('TRACKP', 0))
         self.__which = IntVar()
-        self.__which.set(0)
+        self.__which.set(optiondb.get('WHICH', 0))
         #
         # track toggle
         self.__t = Checkbutton(root, text='Track color changes',
@@ -130,3 +149,15 @@
                 self.__text.configure(selectbackground=colorname)
             elif which == 5:
                 self.__text.configure(insertbackground=colorname)
+
+    def save_options(self, optiondb):
+        optiondb['TRACKP'] = self.__trackp.get()
+        optiondb['WHICH'] = self.__which.get()
+        optiondb['TEXT'] = self.__text.get(0.0, 'end - 1c')
+        optiondb['TEXTSEL'] = self.__text.tag_ranges(SEL)[0:2]
+        optiondb['TEXTINS'] = self.__text.index(INSERT)
+        optiondb['TEXTFG'] = self.__text['foreground']
+        optiondb['TEXTBG'] = self.__text['background']
+        optiondb['TEXT_SFG'] = self.__text['selectforeground']
+        optiondb['TEXT_SBG'] = self.__text['selectbackground']
+        optiondb['TEXT_IBG'] = self.__text['insertbackground']
diff --git a/Tools/pynche/TypeinViewer.py b/Tools/pynche/TypeinViewer.py
index 20fba88..13cb9c7 100644
--- a/Tools/pynche/TypeinViewer.py
+++ b/Tools/pynche/TypeinViewer.py
@@ -20,8 +20,11 @@
     def __init__(self, switchboard, parent=None):
         # non-gui ivars
         self.__sb = switchboard
+        optiondb = switchboard.optiondb()
         self.__hexp = BooleanVar()
+        self.__hexp.set(optiondb.get('HEXTYPE', 0))
         self.__uwtyping = BooleanVar()
+        self.__uwtyping.set(optiondb.get('UPWHILETYPE', 0))
         # create the gui
         self.__frame = Frame(parent) #, relief=GROOVE, borderwidth=2)
         self.__frame.grid(row=3, column=1, sticky='NS')
@@ -130,3 +133,7 @@
 
     def hexp_var(self):
         return self.__hexp
+
+    def save_options(self, optiondb):
+        optiondb['HEXTYPE'] = self.__hexp.get()
+        optiondb['UPWHILETYPE'] = self.__uwtyping.get()
diff --git a/Tools/pynche/__init__.py b/Tools/pynche/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tools/pynche/__init__.py