]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
removing more stdwin users
authorGuido van Rossum <guido@python.org>
Thu, 11 May 2000 14:43:52 +0000 (14:43 +0000)
committerGuido van Rossum <guido@python.org>
Thu, 11 May 2000 14:43:52 +0000 (14:43 +0000)
37 files changed:
Demo/sgi/audio_stdwin/README [deleted file]
Demo/sgi/audio_stdwin/jukebox.py [deleted file]
Demo/sgi/audio_stdwin/rec.py [deleted file]
Demo/sgi/audio_stdwin/vumeter.py [deleted file]
Demo/sgi/gl/glstdwin/fontchart.py [deleted file]
Demo/sgi/gl/glstdwin/glstdwdraw.py [deleted file]
Demo/sgi/gl/glstdwin/glstdwin.py [deleted file]
Demo/sgi/gl/glstdwin/glstdwmenu.py [deleted file]
Demo/sgi/gl/glstdwin/glstdwwin.py [deleted file]
Demo/sgi/gl/glstdwin/stdwingl.py [deleted file]
Demo/sgi/gl/glstdwin/tcolor.py [deleted file]
Demo/sgi/gl/glstdwin/tglsw.py [deleted file]
Demo/sgi/gl/glstdwin/tmenu.py [deleted file]
Demo/stdwin/FormTest.py [deleted file]
Demo/stdwin/README [deleted file]
Demo/stdwin/RadioGroups.py [deleted file]
Demo/stdwin/TestCSplit.py [deleted file]
Demo/stdwin/TestDirList.py [deleted file]
Demo/stdwin/TestFormSplit.py [deleted file]
Demo/stdwin/TestSched.py [deleted file]
Demo/stdwin/TestTextEdit.py [deleted file]
Demo/stdwin/clock.py [deleted file]
Demo/stdwin/ibrowse/README [deleted file]
Demo/stdwin/ibrowse/dir [deleted file]
Demo/stdwin/ibrowse/ib [deleted file]
Demo/stdwin/ibrowse/ib.py [deleted file]
Demo/stdwin/ibrowse/ibrowse [deleted file]
Demo/stdwin/ibrowse/ibrowse.py [deleted file]
Demo/stdwin/ibrowse/icache.py [deleted file]
Demo/stdwin/ibrowse/ifile.py [deleted file]
Demo/stdwin/ibrowse/itags.py [deleted file]
Demo/stdwin/jukebox.py [deleted file]
Demo/stdwin/lpwin.py [deleted file]
Demo/stdwin/microedit.py [deleted file]
Demo/stdwin/miniedit.py [deleted file]
Demo/stdwin/python.py [deleted file]
Demo/stdwin/wdiff.py [deleted file]

diff --git a/Demo/sgi/audio_stdwin/README b/Demo/sgi/audio_stdwin/README
deleted file mode 100644 (file)
index 6d96fe1..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-Three programs that provide a user interface based upon STDWIN to the
-audio device of the SGI 4D/25.  These scripts also demonstrate the power
-of a set of window interface classes implemented in Python that simplify
-the construction of all sorts of buttons, etc.
-
-XXX This hardware is already obsolete; see ../al for examples of audio
-XXX on the Indigo and 4D/35.
-
-jukebox                Browses a directory full of sound samples and lets you
-               play selected ones.  (Probably not fully functional, it
-               requires a conversion program.)
-
-rec            A tape recorder that lets you record a sound sample,
-               play it back, and save it to a file.  Various options to
-               set sampling rate, volume etc.  When idle it doubles
-               as a VU meter.
-
-vumeter                A VU meter that displays a history of the volume of
-               sound recently sampled from the microphone.
diff --git a/Demo/sgi/audio_stdwin/jukebox.py b/Demo/sgi/audio_stdwin/jukebox.py
deleted file mode 100755 (executable)
index 2aaaa83..0000000
+++ /dev/null
@@ -1,321 +0,0 @@
-#! /usr/bin/env python
-
-# JUKEBOX: browse directories full of sampled sound files.
-#
-# One or more "list windows" display the files and subdirectories of
-# the arguments.  Double-clicking on a subdirectory opens a new window
-# displaying its contents (and so on recursively).  Double clicking
-# on a file plays it as a sound file (assuming it is one).
-#
-# Playing is asynchronous: the application keeps listening to events
-# while the sample is playing, so you can change the volume (gain)
-# during playing, cancel playing or start a new sample right away.
-#
-# The control window displays the current output gain and a primitive
-# "stop button" to cancel the current play request.
-#
-# Sound files must currently be in Dik Winter's compressed Mac format.
-# Since decompression is costly, decompressed samples are saved in
-# /usr/tmp/@j* until the application is left.  The files are read
-# afresh each time, though.
-
-import audio
-import sunaudio
-import commands
-import getopt
-import path
-import posix
-import rand
-import stdwin
-from stdwinevents import *
-import string
-import sys
-
-from WindowParent import WindowParent
-from HVSplit import VSplit
-from Buttons import PushButton
-from Sliders import ComplexSlider
-
-# Pathnames
-
-HOME_BIN_SGI = '/ufs/guido/bin/sgi/'   # Directory where macsound2sgi lives
-DEF_DB = '/ufs/dik/sounds/Mac/HCOM'    # Default directory of sounds
-
-
-# Global variables
-
-class struct: pass             # Class to define featureless structures
-
-G = struct()                   # Holds writable global variables
-
-
-# Main program
-
-def main():
-       G.synchronous = 0       # If set, use synchronous audio.write()
-       G.debug = 0             # If set, print debug messages
-       G.gain = 75             # Output gain
-       G.rate = 3              # Sampling rate
-       G.busy = 0              # Set while asynchronous playing is active
-       G.windows = []          # List of open windows (except control)
-       G.mode = 'mac'          # Macintosh mode
-       G.tempprefix = '/usr/tmp/@j' + `rand.rand()` + '-'
-       #
-       optlist, args = getopt.getopt(sys.argv[1:], 'dg:r:sSa')
-       for optname, optarg in optlist:
-               if   optname == '-d':
-                       G.debug = 1
-               elif optname == '-g':
-                       G.gain = string.atoi(optarg)
-                       if not (0 < G.gain < 256):
-                               raise optarg.error, '-g gain out of range'
-               elif optname == '-r':
-                       G.rate = string.atoi(optarg)
-                       if not (1 <= G.rate <= 3):
-                               raise optarg.error, '-r rate out of range'
-               elif optname == '-s':
-                       G.synchronous = 1
-               elif optname == '-S':
-                       G.mode = 'sgi'
-               elif optname == '-a':
-                       G.mode = 'sun'
-       #
-       if not args:
-               args = [DEF_DB]
-       #
-       G.cw = opencontrolwindow()
-       for dirname in args:
-               G.windows.append(openlistwindow(dirname))
-       #
-       #
-       savegain = audio.getoutgain()
-       try:
-               # Initialize stdaudio
-               audio.setoutgain(0)
-               audio.start_playing('')
-               dummy = audio.wait_playing()
-               audio.setoutgain(0)
-               maineventloop()
-       finally:
-               audio.setoutgain(savegain)
-               audio.done()
-               clearcache()
-
-def maineventloop():
-       mouse_events = WE_MOUSE_DOWN, WE_MOUSE_MOVE, WE_MOUSE_UP
-       while G.windows:
-               type, w, detail = event = stdwin.getevent()
-               if w == G.cw.win:
-                       if type == WE_CLOSE:
-                               return
-                       G.cw.dispatch(event)
-               else:
-                       if type == WE_DRAW:
-                               w.drawproc(w, detail)
-                       elif type in mouse_events:
-                               w.mouse(w, type, detail)
-                       elif type == WE_CLOSE:
-                               w.close(w)
-                               del w, event
-                       else:
-                               if G.debug: print type, w, detail
-
-# Control window -- to set gain and cancel play operations in progress
-
-def opencontrolwindow():
-       cw = WindowParent().create('Jukebox', (0, 0))
-       v = VSplit().create(cw)
-       #
-       gain = ComplexSlider().define(v)
-       gain.setminvalmax(0, G.gain, 255)
-       gain.settexts('  ', '  ')
-       gain.sethook(gain_setval_hook)
-       #
-       stop = PushButton().definetext(v, 'Stop')
-       stop.hook = stop_hook
-       #
-       cw.realize()
-       return cw
-
-def gain_setval_hook(self):
-       G.gain = self.val
-       if G.busy: audio.setoutgain(G.gain)
-
-def stop_hook(self):
-       if G.busy:
-               audio.setoutgain(0)
-               dummy = audio.stop_playing()
-               G.busy = 0
-
-
-# List windows -- to display list of files and subdirectories
-
-def openlistwindow(dirname):
-       list = posix.listdir(dirname)
-       list.sort()
-       i = 0
-       while i < len(list):
-               if list[i] == '.' or list[i] == '..':
-                       del list[i]
-               else:
-                       i = i+1
-       for i in range(len(list)):
-               name = list[i]
-               if path.isdir(path.join(dirname, name)):
-                       list[i] = list[i] + '/'
-       width = maxwidth(list)
-       width = width + stdwin.textwidth(' ')   # XXX X11 stdwin bug workaround
-       height = len(list) * stdwin.lineheight()
-       stdwin.setdefwinsize(width, min(height, 500))
-       w = stdwin.open(dirname)
-       stdwin.setdefwinsize(0, 0)
-       w.setdocsize(width, height)
-       w.drawproc = drawlistwindow
-       w.mouse = mouselistwindow
-       w.close = closelistwindow
-       w.dirname = dirname
-       w.list = list
-       w.selected = -1
-       return w
-
-def maxwidth(list):
-       width = 1
-       for name in list:
-               w = stdwin.textwidth(name)
-               if w > width: width = w
-       return width
-
-def drawlistwindow(w, area):
-       d = w.begindrawing()
-       d.erase((0, 0), (1000, 10000))
-       lh = d.lineheight()
-       h, v = 0, 0
-       for name in w.list:
-               d.text((h, v), name)
-               v = v + lh
-       showselection(w, d)
-
-def hideselection(w, d):
-       if w.selected >= 0:
-               invertselection(w, d)
-
-def showselection(w, d):
-       if w.selected >= 0:
-               invertselection(w, d)
-
-def invertselection(w, d):
-       lh = d.lineheight()
-       h1, v1 = p1 = 0, w.selected*lh
-       h2, v2 = p2 = 1000, v1 + lh
-       d.invert(p1, p2)
-
-def mouselistwindow(w, type, detail):
-       (h, v), clicks, button = detail[:3]
-       d = w.begindrawing()
-       lh = d.lineheight()
-       if 0 <= v < lh*len(w.list):
-               i = v / lh
-       else:
-               i = -1
-       if w.selected <> i:
-               hideselection(w, d)
-               w.selected = i
-               showselection(w, d)
-       if type == WE_MOUSE_DOWN and clicks >= 2 and i >= 0:
-               name = path.join(w.dirname, w.list[i])
-               if name[-1:] == '/':
-                       if clicks == 2:
-                               G.windows.append(openlistwindow(name[:-1]))
-               else:
-                       playfile(name)
-
-def closelistwindow(w):
-       remove(G.windows, w)
-
-def remove(list, item):
-       for i in range(len(list)):
-               if list[i] == item:
-                       del list[i]
-                       break
-
-
-# Playing tools
-
-cache = {}
-
-def clearcache():
-       for x in cache.keys():
-               try:
-                       sts = posix.system('rm -f ' + cache[x])
-                       if sts:
-                               print cmd
-                               print 'Exit status', sts
-               except:
-                       print cmd
-                       print 'Exception?!'
-               del cache[x]
-
-def playfile(name):
-       if G.mode <> 'mac':
-               tempname = name
-       elif cache.has_key(name):
-               tempname = cache[name]
-       else:
-               tempname = G.tempprefix + `rand.rand()`
-               cmd = HOME_BIN_SGI + 'macsound2sgi'
-               cmd = cmd + ' ' + commands.mkarg(name)
-               cmd = cmd + ' >' + tempname
-               if G.debug: print cmd
-               sts = posix.system(cmd)
-               if sts:
-                       print cmd
-                       print 'Exit status', sts
-                       stdwin.fleep()
-                       return
-               cache[name] = tempname
-       fp = open(tempname, 'r')
-       try:
-               hdr = sunaudio.gethdr(fp)
-       except sunaudio.error, msg:
-               hdr = ()
-       if hdr:
-               data_size = hdr[0]
-               data = fp.read(data_size)
-               # XXX this doesn't work yet, need to convert from uLAW!!!
-               del fp
-       else:
-               del fp
-               data = readfile(tempname)
-       if G.debug: print len(data), 'bytes read from', tempname
-       if G.busy:
-               G.busy = 0
-               dummy = audio.stop_playing()
-       #
-       # Completely reset the audio device
-       audio.setrate(G.rate)
-       audio.setduration(0)
-       audio.setoutgain(G.gain)
-       #
-       if G.synchronous:
-               audio.write(data)
-               audio.setoutgain(0)
-       else:
-               try:
-                       audio.start_playing(data)
-                       G.busy = 1
-               except:
-                       stdwin.fleep()
-       del data
-
-def readfile(filename):
-       return readfp(open(filename, 'r'))
-
-def readfp(fp):
-       data = ''
-       while 1:
-               buf = fp.read(102400) # Reads most samples in one fell swoop
-               if not buf:
-                       return data
-               data = data + buf
-
-main()
diff --git a/Demo/sgi/audio_stdwin/rec.py b/Demo/sgi/audio_stdwin/rec.py
deleted file mode 100755 (executable)
index 76e924e..0000000
+++ /dev/null
@@ -1,268 +0,0 @@
-#! /usr/bin/env python
-
-import sys
-import audio
-import stdwin
-
-import string
-import getopt
-
-from stdwinevents import *
-from Buttons import *
-from Sliders import *
-#from Soundogram import Soundogram
-from VUMeter import VUMeter
-from WindowParent import WindowParent, MainLoop
-from HVSplit import HSplit, VSplit
-
-class TimeOutToggleButton(ToggleButton):
-       def define(self, parent):
-               self = ToggleButton.define(self, parent)
-               self.parent.need_timer(self)
-               self.timer_hook = 0
-               return self
-       def timer(self):
-               if self.timer_hook:
-                       self.timer_hook(self)
-
-K = 1024
-BUFSIZE = 30*8*K
-Rates = [0, 32*K, 16*K, 8*K]
-Magics = ['', '0032', '0016', '0008']
-
-class Struct: pass
-G = Struct()
-
-def main():
-       #
-       # Turn off scroll bars
-       #
-       stdwin.setdefscrollbars(0, 0)
-       #
-       # Set default state
-       #
-       G.gain = 60
-       G.rate = 3
-       G.nomuting = 0
-       G.savefile = '@rec'
-       #
-       # Set default values
-       #
-       G.data = ''
-       G.playing = 0
-       G.recording = 0
-       G.sogram = 0
-       #
-       # Parse options
-       #
-       optlist, args = getopt.getopt(sys.argv[1:], 'mdg:r:')
-       #
-       for optname, optarg in optlist:
-               if 0: # (So all cases start with elif)
-                       pass
-               elif optname == '-d':
-                       G.debug = 1
-               elif optname == '-g':
-                       G.gain = string.atoi(optarg)
-                       if not (0 < G.gain < 256):
-                               raise optarg.error, '-g gain out of range'
-               elif optname == '-m':
-                       G.nomuting = (not G.nomuting)
-               elif optname == '-r':
-                       G.rate = string.atoi(optarg)
-                       if not (1 <= G.rate <= 3):
-                               raise optarg.error, '-r rate out of range'
-       #
-       if args:
-               G.savefile = args[0]
-       #
-       # Initialize the sound package
-       #
-       audio.setoutgain(G.nomuting * G.gain)   # Silence the speaker
-       audio.setrate(G.rate)
-       #
-       # Create the WindowParent and VSplit
-       #
-       G.window = WindowParent().create('Recorder', (0, 0))
-       w = G.vsplit = VSplit().create(G.window)
-       #
-       # VU-meter
-       #
-       G.vubtn = VUMeter().define(w)
-       #
-       # Radiobuttons for rates
-       #
-       r1btn = RadioButton().definetext(w, '32 K/sec')
-       r1btn.on_hook = rate_hook
-       r1btn.rate = 1
-       #
-       r2btn = RadioButton().definetext(w, '16 K/sec')
-       r2btn.on_hook = rate_hook
-       r2btn.rate = 2
-       #
-       r3btn = RadioButton().definetext(w, '8 K/sec')
-       r3btn.on_hook = rate_hook
-       r3btn.rate = 3
-       #
-       radios = [r1btn, r2btn, r3btn]
-       r1btn.group = r2btn.group = r3btn.group = radios
-       for r in radios:
-               if r.rate == G.rate: r.select(1)
-       #
-       # Other controls
-       #
-       G.recbtn = TimeOutToggleButton().definetext(w, 'Record')
-       G.recbtn.on_hook = record_on_hook
-       G.recbtn.timer_hook = record_timer_hook
-       G.recbtn.off_hook = record_off_hook
-       #
-       G.mutebtn = CheckButton().definetext(w, 'Mute')
-       G.mutebtn.select(not G.nomuting)
-       G.mutebtn.hook = mute_hook
-       #
-       G.playbtn = TimeOutToggleButton().definetext(w, 'Playback')
-       G.playbtn.on_hook = play_on_hook
-       G.playbtn.timer_hook = play_timer_hook
-       G.playbtn.off_hook = play_off_hook
-       #
-       G.gainbtn = ComplexSlider().define(w)
-       G.gainbtn.settexts('  Volume: ', '  ')
-       G.gainbtn.setminvalmax(0, G.gain, 255)
-       G.gainbtn.sethook(gain_hook)
-       #
-       G.sizebtn = Label().definetext(w, `len(G.data)` + ' bytes')
-       #
-       #G.showbtn = PushButton().definetext(w, 'Sound-o-gram...')
-       #G.showbtn.hook = show_hook
-       #
-       G.savebtn = PushButton().definetext(w, 'Save...')
-       G.savebtn.hook = save_hook
-       #
-       G.quitbtn = PushButton().definetext(w, 'Quit')
-       G.quitbtn.hook = quit_hook
-       G.playbtn.enable(0)
-       G.savebtn.enable(0)
-       #G.showbtn.enable(0)
-       start_vu()
-       G.window.realize()
-       #
-       # Event loop
-       #
-       MainLoop()
-
-# XXX Disabled...
-def show_hook(self):
-       savetext = self.text
-       self.settext('Be patient...')
-       close_sogram()
-       stdwin.setdefwinsize(400, 300)
-       win = stdwin.open('Sound-o-gram')
-       G.sogram = Soundogram().define(win, G.data)
-       win.buttons = [G.sogram]
-       self.settext(savetext)
-
-def close_sogram():
-       if G.sogram:
-               # Break circular references
-               G.sogram.win.buttons[:] = []
-               del G.sogram.win
-               G.sogram = 0
-
-def mute_hook(self):
-       G.nomuting = (not self.selected)
-       audio.setoutgain(G.nomuting * G.gain)
-
-def rate_hook(self):
-       G.rate = self.rate
-       audio.setrate(G.rate)
-
-def record_on_hook(self):
-       stop_vu()
-       close_sogram()
-       audio.setrate(G.rate)
-       audio.setoutgain(G.nomuting * G.gain)
-       audio.start_recording(BUFSIZE)
-       G.recording = 1
-       G.playbtn.enable(0)
-       G.window.settimer(10 * BUFSIZE / Rates[G.rate])
-
-def record_timer_hook(self):
-       if G.recording:
-               if audio.poll_recording():
-                       self.hilite(0)
-                       record_off_hook(self)
-               else:
-                       self.parent.settimer(5)
-
-def record_off_hook(self):
-       if not G.recording:
-               return
-       G.data = audio.stop_recording()
-       G.recording = 0
-       G.sizebtn.settext(`len(G.data)` + ' bytes')
-       audio.setoutgain(G.nomuting * G.gain)
-       G.playbtn.enable((len(G.data) > 0))
-       G.savebtn.enable((len(G.data) > 0))
-       #G.showbtn.enable((len(G.data) > 0))
-       G.window.settimer(0)
-       start_vu()
-
-def play_on_hook(self):
-       stop_vu()
-       audio.setrate(G.rate)
-       audio.setoutgain(G.gain)
-       audio.start_playing(G.data)
-       G.playing = 1
-       G.recbtn.enable(0)
-       G.window.settimer(max(10 * len(G.data) / Rates[G.rate], 1))
-
-def play_timer_hook(self):
-       if G.playing:
-               if audio.poll_playing():
-                       self.hilite(0)
-                       play_off_hook(self)
-               else:
-                       self.parent.settimer(5)
-
-def play_off_hook(self):
-       if not G.playing:
-               return
-       x = audio.stop_playing()
-       G.playing = 0
-       audio.setoutgain(G.nomuting * G.gain)
-       G.recbtn.enable(1)
-       G.window.settimer(0)
-       start_vu()
-
-def gain_hook(self):
-       G.gain = self.val
-       if G.playing or G.nomuting: audio.setoutgain(G.gain)
-
-def save_hook(self):
-       if not G.data:
-               stdwin.fleep()
-       else:
-               prompt = 'Store sampled data on file: '
-               try:
-                       G.savefile = stdwin.askfile(prompt, G.savefile, 1)
-               except KeyboardInterrupt:
-                       return
-               try:
-                       fp = open(G.savefile, 'w')
-                       fp.write(Magics[G.rate] + G.data)
-               except:
-                       stdwin.message('Cannot create ' + file)
-
-def stop_vu():
-       G.vubtn.stop()
-
-def start_vu():
-       G.vubtn.start()
-
-def quit_hook(self):
-       G.window.delayed_destroy()
-
-try:
-       main()
-finally:
-       audio.setoutgain(0)
diff --git a/Demo/sgi/audio_stdwin/vumeter.py b/Demo/sgi/audio_stdwin/vumeter.py
deleted file mode 100755 (executable)
index e27c538..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-#! /usr/bin/env python
-
-import audio
-import stdwin
-
-from VUMeter import VUMeter
-from WindowParent import WindowParent
-import MainLoop
-
-NBUFS=20
-BUFSIZE = NBUFS*48
-SCALE=128
-
-class MyVUMeter(VUMeter):
-       def init_reactivity(self):
-               self.parent.need_mouse(self)
-       def mouse_down(self, detail):
-               if self.enabled:
-                       self.stop()
-               else:
-                       self.start()
-       def mouse_move(self, detail): pass
-       def mouse_up(self, detail): pass
-
-def main():
-       audio.setrate(3)
-       audio.setoutgain(0)
-       w = WindowParent().create('VU Meter', (200, 100))
-       v = MyVUMeter().define(w)
-       v.start()
-       w.realize()
-       while 1:
-               w.dispatch(stdwin.getevent())
-
-main()
diff --git a/Demo/sgi/gl/glstdwin/fontchart.py b/Demo/sgi/gl/glstdwin/fontchart.py
deleted file mode 100644 (file)
index 6b58f12..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-import stdwingl
-
-import stdwin
-from stdwinevents import *
-
-def main():
-       size = 12
-       w = stdwin.open('Font chart ' + `size`)
-       while 1:
-               type, window, detail = stdwin.getevent()
-               if type == WE_CLOSE:
-                       break
-               if type == WE_DRAW:
-                       width, height = w.getwinsize()
-                       d = w.begindrawing()
-                       d.setsize(size)
-                       h, v = 0, 0
-                       for c in range(32, 256):
-                               ch = chr(c)
-                               chw = d.textwidth(ch)
-                               if h + chw > width:
-                                       v = v + d.lineheight()
-                                       h = 0
-                                       if v >= height:
-                                               break
-                               d.text((h, v), ch)
-                               h = h + chw
-                       del d
-               if type == WE_MOUSE_UP:
-                       size = size + 1
-                       w.settitle('Font chart ' + `size`)
-                       w.change((0, 0), (2000, 2000))
-
-main()
diff --git a/Demo/sgi/gl/glstdwin/glstdwdraw.py b/Demo/sgi/gl/glstdwin/glstdwdraw.py
deleted file mode 100644 (file)
index 4ddc7a6..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-# Define drawing operations for GL stdwin
-
-import gl
-import fm
-from GL import LO_XOR, LO_SRC
-from glstdwin import MASK
-
-class DrawingObject:
-       #
-       def _init(self, win):
-               self.fg = win._fg
-               self.bg = win._bg
-               self.font = win._font
-               self.size = win._size
-               self.width, self.height = win._area[1]
-               gl.winset(win._gid)
-               gl.color(self.fg)
-               return self
-       #
-       def setfont(self, fontname):
-               self.font = fm.findfont(fontname).scalefont(self.size)
-       #
-       def setsize(self, size):
-               ratio = float(size) / float(self.size)
-               self.size = size
-               self.font = self.font.scalefont(ratio)
-       #
-       def setfgcolor(self, color):
-               self.fg = color
-               gl.color(self.fg)
-       #
-       def setbgcolor(self, color):
-               self.bg = color
-       #
-       def cliprect(self, area):
-               #print 'cliprect', area
-               (left, top), (right, bottom) = area
-               gl.scrmask(left, right, self.height-bottom, self.height-top)
-       #
-       def noclip(self):
-               #print 'noclip()'
-               gl.scrmask(0, self.width, 0, self.height)
-       #
-       def paint(self, ((left, top), (right, bottom))):
-               gl.rectf(left, top, right, bottom)
-       #
-       def box(self, ((left, top), (right, bottom))):
-               #print 'box', ((left, top), (right, bottom))
-               gl.rect(left, top, right, bottom)
-       #
-       def circle(self, (h, v), radius):
-               gl.circ(h, v, radius)
-       #
-       def elarc(self, center, (rh, rv), (a1, a2)):
-               pass # XXX
-       #
-       def erase(self, ((left, top), (right, bottom))):
-               #print 'erase', ((left, top), (right, bottom))
-               gl.color(self.bg)
-               gl.rectf(left, top, right, bottom)
-               gl.color(self.fg)
-       #
-       def invert(self, ((left, top), (right, bottom))):
-               #print 'invert', ((h0, v0), (h1, v1))
-               gl.logicop(LO_XOR)
-               gl.color(self.bg)
-               gl.rectf(left, top, right, bottom)
-               gl.color(self.fg)
-               gl.logicop(LO_SRC)
-       #
-       def line(self, (h0, v0), (h1, v1)):
-               #print 'line', ((h0, v0), (h1, v1))
-               gl.bgnline()
-               gl.v2i(h0, v0)
-               gl.v2i(h1, v1)
-               gl.endline()
-       #
-       def xorline(self, (h0, v0), (h1, v1)):
-               #print 'xorline', ((h0, v0), (h1, v1))
-               gl.logicop(LO_XOR)
-               gl.color(self.bg)
-               gl.bgnline()
-               gl.v2i(h0, v0)
-               gl.v2i(h1, v1)
-               gl.endline()
-               gl.color(self.fg)
-               gl.logicop(LO_SRC)
-       #
-       def point(self, (h, v)):
-               #print 'point', (h, v)
-               gl.bgnpoint()
-               gl.v2i(h, v)
-               gl.endpoint()
-       #
-       def text(self, (h, v), string):
-               #print 'text', ((h, v), string)
-               if h < 0:
-                       # If the point is outside the window
-                       # the whole string isn't drawn.
-                       # Skip the beginning of the string.
-                       # XXX What if the font is bigger than 20 pixels?
-                       i, n = 0, len(string)
-                       while h < -MASK and i < n:
-                               h = h + self.font.getstrwidth(string[i])
-                               i = i + 1
-                       string = string[i:]
-               gl.cmov2(h, v + self.baseline())
-               self.font.setfont()
-               fm.prstr(string)
-       #
-       def shade(self, (h, v), percent):
-               pass # XXX
-       #
-       def baseline(self):
-               (printermatched, fixed_width, xorig, yorig, xsize, ysize, \
-                       height, nglyphs) = self.font.getfontinfo()
-               return height - yorig
-       #
-       def lineheight(self):
-               (printermatched, fixed_width, xorig, yorig, xsize, ysize, \
-                       height, nglyphs) = self.font.getfontinfo()
-               return height
-       #
-       def textbreak(self, string, width):
-               # XXX Slooooow!
-               n = len(string)
-               nwidth = self.textwidth(string[:n])
-               while nwidth > width:
-                       n = n-1
-                       nwidth = self.textwidth(string[:n])
-               return n
-       #
-       def textwidth(self, string):
-               return self.font.getstrwidth(string)
-       #
diff --git a/Demo/sgi/gl/glstdwin/glstdwin.py b/Demo/sgi/gl/glstdwin/glstdwin.py
deleted file mode 100644 (file)
index b7d02c7..0000000
+++ /dev/null
@@ -1,400 +0,0 @@
-# GL STDWIN
-#
-# See stdwingl for a convenient hack to use this instead of built-in stdwin
-# without modifying your application, except for one line in the main file.
-#
-# Intrinsic differences with built-in stdwin (hard or impossible to fix):
-# - Need to call w.close() to close a window !!!
-# - Need to call m.close() to remove a menu !!!
-# - Doesn't enforce the existence of at most one drawing object
-# - No textedit package
-# - No X11 selections
-#
-# Not yet implemented:
-# - shade drawing
-# - elliptical arc drawing (need to play with transformation)
-# - more than one mouse button
-# - scroll bars (need to redo viewport handling to get this)
-# - partial redraws
-# - dialog boxes
-# - timer events
-# - cursors
-#
-# Extra features:
-# - color (for now, you need to know the colormap index)
-
-
-import gl
-import fm
-from GL import *
-from DEVICE import *
-from stdwinevents import *
-
-
-# Customizable constants
-#
-DEF_FONT = 'Times-Roman'               # Default font
-DEF_SIZE = 12                          # Default font size (points)
-MASK = 20                              # Viewport minus scrmask
-
-
-# A structure to hold global variables
-#
-class Struct: pass
-G = Struct()
-#
-G.queue = []                           # Pending STDWIN events
-G.drawqueue = []                       # Windows that need WE_REDRAW
-G.windowmap = {}                       # Map window id to window object
-G.windowmap['0'] = None                        # For convenience
-G.focus = None                         # Input focus
-G.fg = BLACK                           # Foreground color
-G.bg = WHITE                           # Background color
-G.def_size = 0, 0                      # Default window size
-G.def_pos = 0, 0                       # Default window position
-#
-G.size = DEF_SIZE
-G.font = fm.findfont(DEF_FONT).scalefont(G.size)
-
-
-# Initialize GL
-#
-gl.foreground()
-gl.noport()
-dummygid = gl.winopen('')
-
-# Ask for all sorts of events
-#
-# Both REDRAW (= resize and/or redraw!) and INPUTCHANGE are implicitly queued
-#qdevice(REDRAW)
-#qdevice(INPUTCHANGE)
-#
-# Keyboard
-gl.qdevice(KEYBD)
-gl.qdevice(LEFTARROWKEY)
-gl.qdevice(RIGHTARROWKEY)
-gl.qdevice(UPARROWKEY)
-gl.qdevice(DOWNARROWKEY)
-gl.qdevice(LEFTALTKEY)
-gl.qdevice(RIGHTALTKEY)
-#
-# Mouse
-gl.qdevice(LEFTMOUSE)
-#gl.qdevice(MIDDLEMOUSE)
-gl.qdevice(RIGHTMOUSE)                 # Menu button
-# NB MOUSEX, MOUSEY events are queued on button down
-#
-# Window close requests
-gl.qdevice(WINQUIT)
-gl.qdevice(WINSHUT)
-#
-# These aren't needed
-#gl.qdevice(TIMER0)
-#gl.qdevice(WINFREEZE)
-#gl.qdevice(WINTHAW)
-#gl.qdevice(REDRAWICONIC)
-
-
-# STDWIN: create a new window
-#
-def open(title):
-       h, v = G.def_pos
-       width, height = G.def_size
-       if h > 0 or v > 0:
-               # Choose arbitrary defaults
-               if h < 0: h = 10
-               if v < 0: v = 30
-               if width <= 0: width = 400
-               if height <= 0: height = 300
-               gl.prefposition(h, h+width, 1024-v, 1024-v-height)
-       elif width > 0 or height > 0:
-               if width <= 0: width = 400
-               if height <= 0: height = 300
-               gl.prefsize(width, height)
-       from glstdwwin import WindowObject
-       win = WindowObject()._init(title)
-       G.windowmap[`win._gid`] = win
-       return win
-
-
-# STDWIN: set default initial window position (0 means use default)
-#
-def setdefwinpos(h, v):
-       G.def_pos = h, v
-
-
-# STDWIN: set default window size (0 means use default)
-#
-def setdefwinsize(width, height):
-       G.def_size = width, height
-
-
-# STDWIN: beep or ring the bell
-#
-def fleep():
-       gl.ringbell()
-
-
-# STDWIN: set default foreground color
-#
-def setfgcolor(color):
-       G.fg = color
-
-
-# STDWIN: set default background color
-#
-def setbgcolor(color):
-       G.bg = color
-
-
-# STDWIN: get default foreground color
-#
-def getfgcolor():
-       return G.fgcolor
-
-
-# STDWIN: get default background color
-#
-def getbgcolor():
-       return G.bgcolor
-
-
-# Table mapping characters to key codes
-#
-key2code = key = {}
-key['A'] = AKEY
-key['B'] = BKEY
-key['C'] = CKEY
-key['D'] = DKEY
-key['E'] = EKEY
-key['F'] = FKEY
-key['G'] = GKEY
-key['H'] = HKEY
-key['I'] = IKEY
-key['J'] = JKEY
-key['K'] = KKEY
-key['L'] = LKEY
-key['M'] = MKEY
-key['N'] = NKEY
-key['O'] = OKEY
-key['P'] = PKEY
-key['Q'] = QKEY
-key['R'] = RKEY
-key['S'] = SKEY
-key['T'] = TKEY
-key['U'] = UKEY
-key['V'] = VKEY
-key['W'] = WKEY
-key['X'] = XKEY
-key['Y'] = YKEY
-key['Z'] = ZKEY
-key['0'] = ZEROKEY
-key['1'] = ONEKEY
-key['2'] = TWOKEY
-key['3'] = THREEKEY
-key['4'] = FOURKEY
-key['5'] = FIVEKEY
-key['6'] = SIXKEY
-key['7'] = SEVENKEY
-key['8'] = EIGHTKEY
-key['9'] = NINEKEY
-del key
-#
-code2key = {}
-codelist = []
-for key in key2code.keys():
-       code = key2code[key]
-       code2key[`code`] = key
-       codelist.append(code)
-del key
-
-
-# STDWIN: wait for the next event
-#
-commands = {}
-commands['\r'] = WC_RETURN
-commands['\b'] = WC_BACKSPACE
-commands['\t'] = WC_TAB
-#
-def getevent():
-       while 1:
-               #
-               # Get next event from the processed queue, if any
-               #
-               if G.queue:
-                       event = G.queue[0]
-                       del G.queue[0]
-                       #print 'getevent from queue -->', event
-                       return event
-               #
-               # Get next event from the draw queue, if any,
-               # but only if there is nothing in the system queue.
-               #
-               if G.drawqueue and not gl.qtest():
-                       win = G.drawqueue[0]
-                       del G.drawqueue[0]
-                       gl.winset(win._gid)
-                       gl.color(win._bg)
-                       gl.clear()
-                       event = WE_DRAW, win, win._area
-                       #print 'getevent from drawqueue -->', event
-                       return event
-               #
-               # Get next event from system queue, blocking if necessary
-               # until one is available.
-               # Some cases immediately return the event, others do nothing
-               # or append one or more events to the processed queue.
-               #
-               dev, val = gl.qread()
-               #
-               if dev == REDRAW:
-                       win = G.windowmap[`val`]
-                       old_area = win._area
-                       win._fixviewport()
-                       win._needredraw()
-                       if old_area <> win._area:
-                               #print 'getevent --> WE_SIZE'
-                               return WE_SIZE, win, None
-               elif dev == KEYBD:
-                       if val == 3:
-                               raise KeyboardInterrupt # Control-C in window
-                       character = chr(val)
-                       if commands.has_key(character):
-                               return WE_COMMAND, G.focus, commands[character]
-                       return WE_CHAR, G.focus, character
-               elif dev == LEFTARROWKEY:
-                       if val:
-                               return WE_COMMAND, G.focus, WC_LEFT
-               elif dev == RIGHTARROWKEY:
-                       if val:
-                               return WE_COMMAND, G.focus, WC_RIGHT
-               elif dev == UPARROWKEY:
-                       if val:
-                               return WE_COMMAND, G.focus, WC_UP
-               elif dev == DOWNARROWKEY:
-                       if val:
-                               return WE_COMMAND, G.focus, WC_DOWN
-               elif dev in (LEFTALTKEY, RIGHTALTKEY):
-                       if val:
-                               for code in codelist:
-                                       gl.qdevice(code)
-                       else:
-                               for code in codelist:
-                                       gl.unqdevice(code)
-               elif dev in codelist:
-                       if val:
-                               event = G.focus._doshortcut(code2key[`dev`])
-                               if event:
-                                       return event
-               elif dev == LEFTMOUSE:
-                       G.mousex = gl.getvaluator(MOUSEX)
-                       G.mousey = gl.getvaluator(MOUSEY)
-                       if val:
-                               type = WE_MOUSE_DOWN
-                               gl.qdevice(MOUSEX)
-                               gl.qdevice(MOUSEY)
-                       else:
-                               type = WE_MOUSE_UP
-                               gl.unqdevice(MOUSEX)
-                               gl.unqdevice(MOUSEY)
-                       return _mouseevent(type)
-               elif dev == MOUSEX:
-                       G.mousex = val
-                       return _mouseevent(WE_MOUSE_MOVE)
-               elif dev == MOUSEY:
-                       G.mousey = val
-                       return _mouseevent(WE_MOUSE_MOVE)
-               elif dev == RIGHTMOUSE:         # Menu button press/release
-                       if val:                 # Press
-                               event = G.focus._domenu()
-                               if event:
-                                       return event
-               elif dev == INPUTCHANGE:
-                       if G.focus:
-                               G.queue.append(WE_DEACTIVATE, G.focus, None)
-                       G.focus = G.windowmap[`val`]
-                       if G.focus:
-                               G.queue.append(WE_ACTIVATE, G.focus, None)
-               elif dev in (WINSHUT, WINQUIT):
-                       return WE_CLOSE, G.windowmap[`val`], None
-               else:
-                       print '*** qread() --> dev:', dev, 'val:', val
-
-# Helper routine to construct a mouse (up, move or down) event
-#
-def _mouseevent(type):
-       gl.winset(G.focus._gid)
-       orgx, orgy = gl.getorigin()
-       sizex, sizey = gl.getsize()
-       x = G.mousex - orgx
-       y = G.mousey - orgy
-       return type, G.focus, ((x, sizey-y), 1, 0, 0)
-
-
-
-
-# STDWIN: text measuring functions
-
-def baseline():
-       (printermatched, fixed_width, xorig, yorig, xsize, ysize, \
-               height, nglyphs) = G.font.getfontinfo()
-       return height - yorig
-
-def lineheight():
-       (printermatched, fixed_width, xorig, yorig, xsize, ysize, \
-                       height, nglyphs) = G.font.getfontinfo()
-       return height
-
-def textbreak(string, width):
-       # XXX Slooooow!
-       n = len(string)
-       nwidth = textwidth(string[:n])
-       while nwidth > width:
-               n = n-1
-               nwidth = textwidth(string[:n])
-       return n
-
-def textwidth(string):
-       return G.font.getstrwidth(string)
-
-
-# STDWIN: set default font and size
-
-def setfont(fontname):
-       G.font = fm.findfont(fontname).scalefont(G.size)
-
-def setsize(size):
-       ratio = float(size) / float(G.size)
-       G.size = size
-       G.font = G.font.scalefont(ratio)
-
-
-# Utility functions
-
-# Exclusive-or of two BYTES
-#
-def xor(x, y):
-       a = bits(x)
-       b = bits(y)
-       c = [0, 0, 0, 0, 0, 0, 0, 0]
-       for i in range(8):
-               c[i] = (a[i] + b[i]) % 2
-       return stib(c)
-
-# Return the bits of a byte as a list of 8 integers
-#
-def bits(x):
-       b = [0, 0, 0, 0, 0, 0, 0, 0]
-       for i in range(8):
-               x, b[i] = divmod(x, 2)
-       return b
-
-# Convert a list of 8 integers (0|1) to a byte
-#
-def stib(b):
-       x = 0
-       shift = 1
-       for i in range(8):
-               x = x + b[i]*shift
-               shift = shift*2
-       return x
diff --git a/Demo/sgi/gl/glstdwin/glstdwmenu.py b/Demo/sgi/gl/glstdwin/glstdwmenu.py
deleted file mode 100644 (file)
index dd6d90b..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-# Define menu operations for GL stdwin
-
-import gl
-from glstdwin import key2code
-
-class MenuObject:
-       #
-       def _init(self, win, title):
-               self._win = win
-               self._title = title
-               self._items = []
-               return self
-       #
-       def close(self):
-               self._win.remove(self)
-               del self._win
-       #
-       def additem(self, *args):
-               if len(args) == 2:
-                       text, shortcut = args
-               elif len(args) == 1:
-                       text, shortcut = args[0], None
-               else:
-                       raise TypeError, 'arg count'
-               self._items.append([text, shortcut, 1, 0])
-       #
-       def setitem(self, i, text):
-               self._items[i][0] = text
-       #
-       def enable(self, i, flag):
-               self._items[i][2] = flag
-       #
-       def check(self, i, flag):
-               self._items[i][3] = flag
-       #
-       def _makepup(self, firstitem):
-               pup = gl.newpup()
-               if self._title:
-                       gl.addtopup(pup, self._title + '%t', 0)
-               for item in self._items:
-                       text = item[0]
-                       if not item[2]: # Disabled
-                               text = ' ( ' + text + ' )%x-1'
-                       else:
-                               if item[3]: # Check mark
-                                       text = '-> ' + text
-                               else:
-                                       text = '    ' + text
-                               if key2code.has_key(item[1]):
-                                       text = text + '  [Alt-' + item[1] + ']'
-                               text = text + '%x' + `firstitem`
-                       gl.addtopup(pup, text, 0)
-                       firstitem = firstitem + 1
-               return pup
-       #
-       def _checkshortcut(self, char):
-               for i in range(len(self._items)):
-                       item = self._items[i]
-                       if item[2] and item[1] == char:
-                               return i
-               return -1
-       #
diff --git a/Demo/sgi/gl/glstdwin/glstdwwin.py b/Demo/sgi/gl/glstdwin/glstdwwin.py
deleted file mode 100644 (file)
index b880b9a..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-# Define window operations for STDWIN
-
-import gl
-from stdwinevents import *
-from glstdwin import G                 # Global variables
-from glstdwin import MASK              # Tunable constant
-
-class WindowObject:
-       #
-       def _init(self, title):
-               self._docsize = (0, 0)
-               self._fg = G.fg
-               self._bg = G.bg
-               self._title = title
-               self._font = G.font
-               self._size = G.size
-               self._menus = []
-               self._gid = gl.winopen(title)
-               gl.winconstraints() # To remove prefsize() effect
-               self._fixviewport()
-               self._needredraw()
-               return self
-       #
-       def close(self):
-               del G.windowmap[`self._gid`]
-               gl.winclose(self._gid)
-               self._gid = 0
-       #
-       def _needredraw(self):
-               if self in G.drawqueue:
-                       G.drawqueue.remove(self)
-               G.drawqueue.append(self)
-       #
-       def begindrawing(self):
-               from glstdwdraw import DrawingObject
-               return DrawingObject()._init(self)
-       #
-       def change(self, area):
-               self._needredraw()
-               # XXX Should record the area to be drawn?
-       #
-       def gettitle(self):
-               return self._title
-       #
-       def getdocsize(self):
-               return self._docsize
-       #
-       def getorigin(self):
-               return self._area[0]
-       #
-       def getwinsize(self):
-               return self._area[1]
-       #
-       def scroll(self, area, by):
-               # XXX ought to use gl.rectcopy()
-               if by <> (0, 0):
-                       self.change(area)
-       #
-       def setdocsize(self, docsize):
-               self._docsize = docsize
-       #
-       def setorigin(self, origin):
-               pass # XXX
-       #
-       def settimer(self, decisecs):
-               pass # XXX
-       #
-       def settitle(self, title):
-               self._title = title
-               gl.wintitle(title)
-       #
-       def show(self, area):
-               pass # XXX
-       #
-       def _fixviewport(self):
-               #
-               # Called after redraw or resize, and initially.
-               #
-               # Fix the coordinate system so that (0, 0) is top left,
-               # units are pixels, and positive axes point right and down.
-               #
-               # Make the viewport slightly larger than the window,
-               # and set the screenmask exactly to the window; this
-               # help fixing character clipping.
-               #
-               # Set self._area to the window rectangle in STDWIN coords.
-               #
-               gl.winset(self._gid)
-               gl.reshapeviewport()
-               x0, x1, y0, y1 = gl.getviewport()
-               width, height = x1-x0, y1-y0
-               gl.viewport(x0-MASK, x1+MASK, y0-MASK, y1+MASK)
-               gl.scrmask(x0, x1, y0, y1)
-               gl.ortho2(-MASK, width+MASK, height+MASK, -MASK)
-               self._area = (0, 0), (width, height)
-       #
-       def menucreate(self, title):
-               from glstdwmenu import MenuObject
-               menu = MenuObject()._init(self, title)
-               self._menus.append(menu)
-               return menu
-       #
-       def _domenu(self):
-               if not self._menus:
-                       return None
-               if len(self._menus) == 1:
-                       pup = self._menus[0]._makepup(0)
-                       val = gl.dopup(pup)
-                       gl.freepup(pup)
-                       if val < 0:
-                               return None
-                       return WE_MENU, self, (self._menus[0], val)
-               #
-               # More than one menu: use nested menus.
-               #
-               pups = []
-               firstitem = 0
-               for menu in self._menus:
-                       pups.append(menu._makepup(firstitem))
-                       firstitem = firstitem + 100
-               pup = gl.newpup()
-               for i in range(len(self._menus)):
-                       gl.addtopup(pup, self._menus[i]._title + '%m', pups[i])
-               val = gl.dopup(pup)
-               gl.freepup(pup)
-               for pup in pups:
-                       gl.freepup(pup)
-               if val < 0:
-                       return None
-               i_menu, i_item = divmod(val, 100)
-               return WE_MENU, self, (self._menus[i_menu], i_item)
-       #
-       def _doshortcut(self, char):
-               for menu in self._menus:
-                       i = menu._checkshortcut(char)
-                       if i >= 0:
-                               return WE_MENU, self, (menu, i)
-               return None
-       #
diff --git a/Demo/sgi/gl/glstdwin/stdwingl.py b/Demo/sgi/gl/glstdwin/stdwingl.py
deleted file mode 100644 (file)
index 4427593..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-# If you put 'import stdwin_gl' in front of the main program of a program
-# using stdwin (before it has a chance to import the real stdwin!),
-# it will use glstdwin and think it is stdwin.
-
-import sys
-if sys.modules.has_key('stdwin'):
-       raise RuntimeError, 'too late -- stdwin has already been imported'
-
-import glstdwin
-sys.modules['stdwin'] = glstdwin
diff --git a/Demo/sgi/gl/glstdwin/tcolor.py b/Demo/sgi/gl/glstdwin/tcolor.py
deleted file mode 100644 (file)
index d1c49e1..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-# Try colors -- display all 256 possible colors, with their color index
-
-import stdwingl
-
-import stdwin
-from stdwinevents import *
-
-NROWS = 16
-NCOLS = 16
-
-def main():
-       stdwin.setdefwinsize(NCOLS * stdwin.textwidth('12345'), \
-                               NROWS * stdwin.lineheight() * 3)
-       w = stdwin.open('TestColors')
-       #
-       while 1:
-               type, window, detail = stdwin.getevent()
-               if type == WE_CLOSE:
-                       print 'Bye.'
-                       break
-               elif type == WE_SIZE:
-                       w.change((0,0), (10000, 10000))
-               elif type == WE_DRAW:
-                       width, height = w.getwinsize()
-                       d = w.begindrawing()
-                       for row in range(NROWS):
-                               for col in range(NCOLS):
-                                       color = row*NCOLS + col
-                                       d.setfgcolor(color)
-                                       p = col*width/NCOLS, row*height/NROWS
-                                       q = (col+1)*width/NCOLS, \
-                                               (row+1)*height/NROWS
-                                       d.paint((p, q))
-                                       d.setfgcolor(0)
-                                       d.box((p, q))
-                                       d.text(p, `color`)
-                                       p = p[0] , p[1]+ d.lineheight()
-                                       d.setfgcolor(7)
-                                       d.text(p, `color`)
-                       del d
-       #
-
-main()
diff --git a/Demo/sgi/gl/glstdwin/tglsw.py b/Demo/sgi/gl/glstdwin/tglsw.py
deleted file mode 100644 (file)
index 8854e98..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-import sys
-
-if len(sys.argv) < 2:
-       import stdwingl
-       color = 1
-       needclose = 1
-else:
-       color = 0
-       needclose = 0
-
-import stdwin
-import time
-from stdwinevents import *
-from GL import BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE
-
-def main():
-       #
-       stdwin.setdefwinsize(300, 300)
-       stdwin.setdefwinpos(0, 0)
-       if color: stdwin.setbgcolor(YELLOW)
-       w1 = stdwin.open('Hello, world')
-       w1.box = (10, 10), (90, 90)
-       #
-       stdwin.setdefwinsize(0, 0)
-       stdwin.setdefwinpos(50, 50)
-       if color: stdwin.setbgcolor(GREEN)
-       w2 = stdwin.open('Second window')
-       w2.box = (10, 10), (90, 90)
-       #
-       while w1 or w2:
-               type, window, detail = stdwin.getevent()
-               if type == WE_DRAW:
-                       d = window.begindrawing()
-                       if window == w1:
-                               if color: d.setfgcolor(BLACK)
-                               d.box(((50, 50), (250, 250)))
-                               if color: d.setfgcolor(RED)
-                               d.cliprect(((50, 50), (250, 250)))
-                               d.paint(w1.box)
-                               d.noclip()
-                               if color: d.setfgcolor(BLUE)
-                               d.line((0, 0), w1.box[0])
-                       elif window == w2:
-                               if color: d.setfgcolor(WHITE)
-                               d.box(w2.box)
-                               if color: d.setfgcolor(BLACK)
-                               d.text(w2.box[0], 'Hello world')
-                       else:
-                               print 'Strange draw???', window, detail
-                       del d
-               elif type == WE_CLOSE:
-                       if needclose: window.close()
-                       if window == w1:
-                               w1 = None
-                       elif window == w2:
-                               w2 = None
-                       else:
-                               print 'weird close event???', window, detail
-               elif type in (WE_MOUSE_DOWN, WE_MOUSE_MOVE, WE_MOUSE_UP):
-                       h, v = detail[0]
-                       window.box = (h, v), (h+80, v+80)
-                       window.change(((0,0), (2000, 2000)))
-               elif type == WE_CHAR:
-                       print 'character', `detail`
-               else:
-                       print type, window, detail
-       #
-
-main()
-print 'Done.'
diff --git a/Demo/sgi/gl/glstdwin/tmenu.py b/Demo/sgi/gl/glstdwin/tmenu.py
deleted file mode 100644 (file)
index 233edae..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-# Test menus
-
-import stdwingl
-
-import stdwin
-from stdwinevents import *
-
-def main():
-       w = stdwin.open('TestMenus')
-       #
-       items1 = 'Aap', 'Noot', 'Mies'
-       m1 = w.menucreate('Menu-1')
-       for item in items1:
-               m1.additem(item, item[0])
-       #
-       items2 = 'Wim', 'Zus', 'Jet', 'Teun', 'Vuur'
-       m2 = w.menucreate('Menu-2')
-       for item in items2:
-               m2.additem(item, `len(item)`)
-       #
-       m1.enable(1, 0)
-       m2.check(1, 1)
-       #
-       while 1:
-               type, window, detail = stdwin.getevent()
-               if type == WE_CLOSE:
-                       break
-               elif type == WE_DRAW:
-                       d = w.begindrawing()
-                       d.box(((50,50), (100,100)))
-                       del d
-               elif type == WE_MENU:
-                       mp, i = detail
-                       if mp == m1:
-                               print 'Choice:', items1[i]
-                       elif mp == m2:
-                               print 'Choice:', items2[i]
-                       else:
-                               print 'Not one of my menus!'
-               elif type == WE_CHAR:
-                       print 'Character', `detail`
-       #
-
-main()
diff --git a/Demo/stdwin/FormTest.py b/Demo/stdwin/FormTest.py
deleted file mode 100755 (executable)
index 15e3b36..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#! /usr/bin/env python
-
-testlabels = 'Name', 'Address', 'City', 'Country', 'Comments'
-
-def main():
-       import stdwin
-       from WindowParent import WindowParent, MainLoop
-       from FormSplit import FormSplit
-       from Buttons import Label
-       from TextEdit import TextEdit
-       #
-       stdwin.setdefscrollbars(0, 0)
-       #
-       w = WindowParent().create('FormTest', (0, 0))
-       f = FormSplit().create(w)
-       #
-       h, v = 0, 0
-       for label in testlabels:
-               f.placenext(h, v)
-               lbl = Label().definetext(f, label)
-               f.placenext(h + 100, v)
-               txt = TextEdit().createboxed(f, (40, 2), (2, 2))
-               #txt = TextEdit().create(f, (40, 2))
-               v = v + 2*stdwin.lineheight() + 10
-       #
-       w.realize()
-       #
-       MainLoop()
-
-main()
diff --git a/Demo/stdwin/README b/Demo/stdwin/README
deleted file mode 100644 (file)
index 5291225..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-Contents of this directory:
-
-FormTest.py            Show how a form can be built to enter multiple fields
-RadioGroups.py         Show how to use multiple groups of radio buttons
-TestCSplit.py          Test CSplit  widget (a clock-like split)
-TestDirList.py         Test DirList widget (lists directory contents)
-TestFormSplit.py       Test FormSplit widget (arbitrary grouping)
-TestSched.py           Test WindowSched widget (event scheduling)
-TestTextEdit.py                Test TextEdit widget (probably doen't work any more)
-clock.py               A simple clock, with alarm
-jukebox.py             Play audio files (SGI only, needs SOX and SFPLAY)
-lpwin.py               Watch line printer queues
-microedit.py           The smallest window editor
-miniedit.py            A small multi-window editor
-python.py              A window interface to the Python interpreter
-wdiff.py               A window-based directory diff
-
-See ../ibrowse for another demo written using stdwin.
diff --git a/Demo/stdwin/RadioGroups.py b/Demo/stdwin/RadioGroups.py
deleted file mode 100755 (executable)
index 93b6a2d..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-#! /usr/bin/env python
-
-# radiogroups.py
-#
-# Demonstrate multiple groups of radio buttons
-
-import stdwin
-from Buttons import *
-from WindowParent import WindowParent, MainLoop
-from HVSplit import HSplit, VSplit
-
-def main():
-       #
-       # Create the widget hierarchy, top-down
-       #
-       # 1. Create the window
-       #
-       window = WindowParent().create('Radio Groups', (0, 0))
-       #
-       # 2. Create a horizontal split to contain the groups
-       #
-       topsplit = HSplit().create(window)
-       #
-       # 3. Create vertical splits, one for each group
-       #
-       group1 = VSplit().create(topsplit)
-       group2 = VSplit().create(topsplit)
-       group3 = VSplit().create(topsplit)
-       #
-       # 4. Create individual radio buttons, each in their own split
-       #
-       b11 = RadioButton().definetext(group1, 'Group 1 button 1')
-       b12 = RadioButton().definetext(group1, 'Group 1 button 2')
-       b13 = RadioButton().definetext(group1, 'Group 1 button 3')
-       #
-       b21 = RadioButton().definetext(group2, 'Group 2 button 1')
-       b22 = RadioButton().definetext(group2, 'Group 2 button 2')
-       b23 = RadioButton().definetext(group2, 'Group 2 button 3')
-       #
-       b31 = RadioButton().definetext(group3, 'Group 3 button 1')
-       b32 = RadioButton().definetext(group3, 'Group 3 button 2')
-       b33 = RadioButton().definetext(group3, 'Group 3 button 3')
-       #
-       # 5. Define the grouping for the radio buttons.
-       #    Note: this doesn't have to be the same as the
-       #    grouping is splits (although it usually is).
-       #    Also set the 'hook' procedure for each button
-       #
-       list1 = [b11, b12, b13]
-       list2 = [b21, b22, b23]
-       list3 = [b31, b32, b33]
-       #
-       for b in list1:
-               b.group = list1
-               b.on_hook = myhook
-       for b in list2:
-               b.group = list2
-               b.on_hook = myhook
-       for b in list3:
-               b.group = list3
-               b.on_hook = myhook
-       #
-       # 6. Select a default button in each group
-       #
-       b11.select(1)
-       b22.select(1)
-       b33.select(1)
-       #
-       # 6. Realize the window
-       #
-       window.realize()
-       #
-       # 7. Dispatch events until the window is closed
-       #
-       MainLoop()
-       #
-       # 8. Report final selections
-       #
-       print 'You selected the following choices:'
-       if b11.selected: print '1.1'
-       if b12.selected: print '1.2'
-       if b13.selected: print '1.3'
-       if b21.selected: print '2.1'
-       if b22.selected: print '2.2'
-       if b23.selected: print '2.3'
-       if b31.selected: print '3.1'
-       if b32.selected: print '3.2'
-       if b33.selected: print '3.3'
-
-
-# My 'hook' procedure
-# This is placed as 'hook' attribute on each button.
-# The example just prints the title of the selected button.
-#
-def myhook(self):
-       print 'Selected:', self.text
-
-main()
diff --git a/Demo/stdwin/TestCSplit.py b/Demo/stdwin/TestCSplit.py
deleted file mode 100755 (executable)
index 720b8c3..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-#! /usr/bin/env python
-
-# TestCSplit
-
-import stdwin
-from WindowParent import WindowParent, MainLoop
-from Buttons import PushButton
-
-def main(n):
-       from CSplit import CSplit
-       #
-       stdwin.setdefscrollbars(0, 0)
-       #
-       the_window = WindowParent().create('TestCSplit', (0, 0))
-       the_csplit = CSplit().create(the_window)
-       #
-       for i in range(n):
-               the_child = PushButton().define(the_csplit)
-               the_child.settext(`(i+n-1)%n+1`)
-       #
-       the_window.realize()
-       #
-       MainLoop()
-
-main(12)
diff --git a/Demo/stdwin/TestDirList.py b/Demo/stdwin/TestDirList.py
deleted file mode 100755 (executable)
index 321c2d9..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#! /usr/bin/env python
-
-# TestDirList
-
-from DirList import DirListWindow
-from WindowParent import MainLoop
-
-def main():
-       import sys
-       args = sys.argv[1:]
-       if not args:
-               args = ['.']
-               # Mac: args = [':']
-       for arg in args:
-               w = DirListWindow().create(arg)
-       MainLoop()
-
-main()
diff --git a/Demo/stdwin/TestFormSplit.py b/Demo/stdwin/TestFormSplit.py
deleted file mode 100755 (executable)
index e67c3f9..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-#! /usr/bin/env python
-
-# TestFormSplit
-
-import stdwin
-from WindowParent import WindowParent, MainLoop
-from Buttons import PushButton
-
-def main(n):
-       from FormSplit import FormSplit
-       #
-       stdwin.setdefscrollbars(1, 1)
-       #
-       the_window = WindowParent().create('TestFormSplit', (0, 0))
-       the_form = FormSplit().create(the_window)
-       #
-       for i in range(n):
-               if i % 3 == 0:
-                       the_form.placenext(i*40, 0)
-               the_child = PushButton().define(the_form)
-               the_child.settext('XXX-' + `i` + '-YYY')
-       #
-       the_window.realize()
-       #
-       MainLoop()
-
-main(6)
diff --git a/Demo/stdwin/TestSched.py b/Demo/stdwin/TestSched.py
deleted file mode 100755 (executable)
index 29274e6..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-#! /usr/bin/env python
-
-# TestSched
-
-import stdwin
-from WindowParent import WindowParent, MainLoop
-import WindowSched
-from Buttons import PushButton
-
-def my_ringer(child):
-       child.my_id = None
-       stdwin.fleep()
-
-def my_hook(child):
-       # schedule for the bell to ring in N seconds; cancel previous
-       if child.my_id:
-               WindowSched.cancel(child.my_id)
-       child.my_id = \
-               WindowSched.enter(child.my_number*1000, 0, my_ringer, (child,))
-
-def main(n):
-       from CSplit import CSplit
-       
-       window = WindowParent().create('TestSched', (0, 0))
-       csplit = CSplit().create(window)
-       
-       for i in range(n):
-               child = PushButton().define(csplit)
-               child.my_number = i
-               child.my_id = None
-               child.settext(`(i+n-1)%n+1`)
-               child.hook = my_hook
-       
-       window.realize()
-       
-       WindowSched.run()
-
-main(12)
diff --git a/Demo/stdwin/TestTextEdit.py b/Demo/stdwin/TestTextEdit.py
deleted file mode 100755 (executable)
index b15b049..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#! /usr/bin/env python
-
-# Test TextEdit widgets
-
-def main():
-       from TextEdit import TextEdit
-       from WindowParent import WindowParent, MainLoop
-       w = WindowParent().create('Test TextEdit', (0, 0))
-       t = TextEdit().create(w, (40, 4))
-       w.realize()
-       MainLoop()
-
-main()
diff --git a/Demo/stdwin/clock.py b/Demo/stdwin/clock.py
deleted file mode 100755 (executable)
index 90f1d22..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-#! /usr/bin/env python
-
-# 'clock' -- A simple alarm clock
-
-# The alarm can be set at 5 minute intervals on a 12 hour basis.
-# It is controlled with the mouse:
-# - Click and drag around the circle to set the alarm.
-# - Click far outside the circle to clear the alarm.
-# - Click near the center to set the alarm at the last time set.
-# The alarm time is indicated by a small triangle just outside the circle,
-# and also by a digital time at the bottom.
-# The indicators disappear when the alarm is not set.
-# When the alarm goes off, it beeps every minute for five minutes,
-# and the clock turns into inverse video.
-# Click or activate the window to turn the ringing off.
-
-import stdwin
-from stdwinevents import WE_MOUSE_DOWN, WE_MOUSE_MOVE, WE_MOUSE_UP, \
-       WE_TIMER, WE_DRAW, WE_SIZE, WE_CLOSE, WE_ACTIVATE
-import mainloop
-import time
-from math import sin, cos, atan2, pi, sqrt
-
-DEFWIDTH, DEFHEIGHT = 200, 200
-
-MOUSE_EVENTS = (WE_MOUSE_DOWN, WE_MOUSE_MOVE, WE_MOUSE_UP)
-ORIGIN = 0, 0
-FARAWAY = 2000, 2000
-EVERYWHERE = ORIGIN, FARAWAY
-
-
-def main():
-       win = makewindow()
-       del win
-       mainloop.mainloop()
-
-def makewindow():
-       stdwin.setdefwinsize(DEFWIDTH, DEFHEIGHT + stdwin.lineheight())
-       win = stdwin.open('clock')
-       setdimensions(win)
-       win.set = 1             # True when alarm is set
-       win.time = 11*60 + 40   # Time when alarm must go off
-       win.ring = 0            # True when alarm is ringing
-       win.dispatch = cdispatch
-       mainloop.register(win)
-       settimer(win)
-       return win
-
-def cdispatch(event):
-       type, win, detail = event
-       if type == WE_DRAW:
-               drawproc(win, detail)
-       elif type == WE_TIMER:
-               settimer(win)
-               drawproc(win, EVERYWHERE)
-       elif type in MOUSE_EVENTS:
-               mouseclick(win, type, detail)
-       elif type == WE_ACTIVATE:
-               if win.ring:
-                       # Turn the ringing off
-                       win.ring = 0
-                       win.begindrawing().invert(win.mainarea)
-       elif type == WE_SIZE:
-               win.change(EVERYWHERE)
-               setdimensions(win)
-       elif type == WE_CLOSE:
-               mainloop.unregister(win)
-               win.close()
-
-def setdimensions(win):
-       width, height = win.getwinsize()
-       height = height - stdwin.lineheight()
-       if width < height: size = width
-       else: size = height
-       halfwidth = width/2
-       halfheight = height/2
-       win.center = halfwidth, halfheight
-       win.radius = size*45/100
-       win.width = width
-       win.height = height
-       win.corner = width, height
-       win.mainarea = ORIGIN, win.corner
-       win.lineheight = stdwin.lineheight()
-       win.farcorner = width, height + win.lineheight
-       win.statusarea = (0, height), win.farcorner
-       win.fullarea = ORIGIN, win.farcorner
-
-def settimer(win):
-       now = time.time()
-       hours, minutes, seconds = win.times = calctime(now)
-       delay = 61 - seconds
-       win.settimer(10 * delay)
-       minutes = minutes + hours*60
-       if win.ring:
-               # Is it time to stop the alarm ringing?
-               since = (minutes - win.time + 720) % 720
-               if since >= 5:
-                       # Stop it now
-                       win.ring = 0
-               else:
-                       # Ring again, once every minute
-                       stdwin.fleep()
-       elif win.set and minutes == win.time:
-               # Start the alarm ringing
-               win.ring = 1
-               stdwin.fleep()
-
-def drawproc(win, area):
-       hours, minutes, seconds = win.times
-       d = win.begindrawing()
-       d.cliprect(area)
-       d.erase(EVERYWHERE)
-       d.circle(win.center, win.radius)
-       d.line(win.center, calcpoint(win, hours*30 + minutes/2, 0.6))
-       d.line(win.center, calcpoint(win, minutes*6, 1.0))
-       str = "%02d:%02d" % (hours, minutes)
-       p = (win.width - d.textwidth(str))/2, win.height * 3 / 4
-       d.text(p, str)
-       if win.set:
-               drawalarm(win, d)
-               drawalarmtime(win, d)
-       if win.ring:
-               d.invert(win.mainarea)
-
-def mouseclick(win, type, detail):
-       d = win.begindrawing()
-       if win.ring:
-               # First turn the ringing off
-               win.ring = 0
-               d.invert(win.mainarea)
-       h, v = detail[0]
-       ch, cv = win.center
-       x, y = h-ch, cv-v
-       dist = sqrt(x*x + y*y) / float(win.radius)
-       if dist > 1.2:
-               if win.set:
-                       drawalarm(win, d)
-                       erasealarmtime(win, d)
-                       win.set = 0
-       elif dist < 0.8:
-               if not win.set:
-                       win.set = 1
-                       drawalarm(win, d)
-                       drawalarmtime(win, d)
-       else:
-               # Convert to half-degrees (range 0..720)
-               alpha = atan2(y, x)
-               hdeg = alpha*360.0/pi
-               hdeg = 180.0 - hdeg
-               hdeg = (hdeg + 720.0) % 720.0
-               atime = 5*int(hdeg/5.0 + 0.5)
-               if atime <> win.time or not win.set:
-                       if win.set:
-                               drawalarm(win, d)
-                               erasealarmtime(win, d)
-                       win.set = 1
-                       win.time = atime
-                       drawalarm(win, d)
-                       drawalarmtime(win, d)
-
-def drawalarm(win, d):
-       p1 = calcpoint(win, float(win.time)/2.0, 1.02)
-       p2 = calcpoint(win, float(win.time)/2.0 - 4.0, 1.1)
-       p3 = calcpoint(win, float(win.time)/2.0 + 4.0, 1.1)
-       d.xorline(p1, p2)
-       d.xorline(p2, p3)
-       d.xorline(p3, p1)
-
-def erasealarmtime(win, d):
-       d.erase(win.statusarea)
-
-def drawalarmtime(win, d):
-       # win.time is in the range 0..720 with origin at 12 o'clock
-       # Convert to hours (0..12) and minutes (12*(0..60))
-       hh = win.time/60
-       mm = win.time%60
-       str = 'Alarm@%02d:%02d' % (hh, mm)
-       p1 = (win.width - d.textwidth(str))/2, win.height
-       d.text(p1, str)
-
-def calcpoint(win, degrees, size):
-       alpha = pi/2.0 - float(degrees) * pi/180.0
-       x, y = cos(alpha), sin(alpha)
-       h, v = win.center
-       r = float(win.radius)
-       return h + int(x*size*r), v - int(y*size*r)
-
-def calctime(now):
-       hours, minutes, seconds = time.localtime(now)[3:6]
-       hours = hours % 12
-       return hours, minutes, seconds
-
-main()
diff --git a/Demo/stdwin/ibrowse/README b/Demo/stdwin/ibrowse/README
deleted file mode 100644 (file)
index 22e4039..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-This directory contains a browser written in Python for "Info files"
-as used by the Emacs documentation system.  The browser requires that
-Python is built with the "stdwin" option and runs under X11 or the
-Mac window system.
-
-Now you can read Info files even if you can't spare the memory, time or
-disk space to run Emacs.  (I have used this extensively on a Macintosh
-with 1 Megabyte main memory and a 20 Meg harddisk.)
-
-You can give this to someone with great fear of complex computer
-systems, as long as they can use a mouse.
-
-Another reason to use this is to encourage the use of Info for on-line
-documentation of software that is not related to Emacs or GNU.
-(In particular, I plan to redo the Python and STDWIN documentation
-in texinfo.)
-
-The main program is in file "ib.py"; this accepts a file name and a
-node name as optional command line arguments, i.e., its usage is
-
-       python ib.py [file [node]]
-
-
-Configuration:
-
-- The pathname of the directory (or directories) containing
-the standard Info files should be set by editing the
-value assigned to INFOPATH in module ifile.py.
-
-- The default font should be set by editing the value of FONT
-in this module (ibrowse.py).
-
-- For fastest I/O, you may look at BLOCKSIZE and a few other
-constants in ifile.py.
diff --git a/Demo/stdwin/ibrowse/dir b/Demo/stdwin/ibrowse/dir
deleted file mode 100755 (executable)
index 21d1989..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
--*- Text -*-
-This is the file .../ibrowse/dir, which contains the topmost node of the
-Info hierarchy.  The first time you invoke Ibrowse you start off
-looking at that node, which is (dir)Top.  (This is a copy of the Info
-dir node, except that the reference to Info is replaced by one to Ibrowse.)
-\1f
-File: dir      Node: Top       This is the top of the INFO tree
-  This (the Directory node) gives a menu of major topics. 
-  Typing "d" returns here, "q" exits, "?" lists all INFO commands, "h" 
-  gives a primer for first-timers, "mTexinfo<Return>" visits Texinfo topic,
-  etc.
-  --- PLEASE ADD DOCUMENTATION TO THIS TREE. (See INFO topic first.) ---
-
-* Menu: The list of major topics begins on the next line.
-
-* Ibrowse: (ibrowse).  Documentation browsing system.
-
-* Emacs: (emacs).  The extensible self-documenting text editor.
-
-* VIP: (vip).   A VI-emulation for Emacs.
-
-* Texinfo: (texinfo).
-               With one source file, make either a printed manual
-               (through TeX) or an Info file (through texinfo).
-               Full documentation in this menu item.
-
-* Termcap: (termcap).
-               The termcap library, which enables application programs
-               to handle all types of character-display terminals.
-
-* Regex: (regex).
-               The GNU regular expression library.
-
-* Bison: (bison.info).
-               The GNU yacc-compatible parser generator.
-
-* GCC: (gcc.info).
-               The GNU C compiler.
-
-* G++: (g-whiz).
-               The GNU C++ compiler.
-
-* LibG++: (libg++).
-               The GNU C++ library.
-
-* GDB: (gdb.info).
-               The GNU debugger.
-
-* CPP: (cpp.info).
-               The GNU C preprocessor.
-
-* Lispref: (lispref).
-               The GNU Emacs Lisp reference manual.
-
-* Make: (make-info).
-               The GNU make program.
-
-* M4: (m4).
-               The GNU m4 program.
-
-* Gawk: (gawk-info).
-               GNU awk.
diff --git a/Demo/stdwin/ibrowse/ib b/Demo/stdwin/ibrowse/ib
deleted file mode 100755 (executable)
index 04cb790..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-: ${ARCH}=`arch`
-exec /ufs/guido/bin/$ARCH/python ib.py ${1+"$@"}
diff --git a/Demo/stdwin/ibrowse/ib.py b/Demo/stdwin/ibrowse/ib.py
deleted file mode 100755 (executable)
index ce6e16a..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#! /usr/bin/env python
-
-# Call ibrowse (the info file browser) under UNIX.
-
-import sys
-import ibrowse
-
-if len(sys.argv) > 1:
-       file = sys.argv[1]
-       if len(sys.argv) > 2:
-               if len(sys.argv) > 3:
-                       sys.stdout = sys.stderr
-                       print 'usage:', sys.argv[0], '[file [node]]'
-                       sys.exit(2)
-               else:
-                       node = sys.argv[2]
-       else:
-               node = ''
-       ibrowse.start('(' + file + ')' + node)
-else:
-       ibrowse.main()
diff --git a/Demo/stdwin/ibrowse/ibrowse b/Demo/stdwin/ibrowse/ibrowse
deleted file mode 100755 (executable)
index 8b0dcde..0000000
+++ /dev/null
@@ -1,719 +0,0 @@
-This file documents the ibrowse program.  -*-Text-*-
-The H command of ibrowse goes to the node Help in this file.
-\1f
-File: ibrowse  Node: Top       Up: (DIR)       Next: Expert
-
-Ibrowse is a program for reading documentation, which you are using now.
-** Ibrowse uses the file format of the Emacs Info program, and its
-** commands are similar, but not identical.
-
-To learn how to use Ibrowse, type the command "h".  It will bring you
-to a programmed instruction sequence.
-
-* Menu:
-
-* Expert::     Advanced Ibrowse commands: c, k, g, s, 1 - 9, arrows.
-* Add::                Describes how to add new nodes to the hierarchy.
-               Also tells what nodes look like.
-* Menus::      How to add to or create menus in Info nodes.
-* Cross-refs:: How to add cross-references to Info nodes.
-* Tags::       How to make tag tables for Info files.
-* Checking::   How to check the consistency of an Info file.
-* Texinfo: (texinfo).
-               How to generate an Info file and a printed manual
-               from the same source file.
-\1f\f
-File: ibrowse  Node: Summary                   Next: Help
-
-Ibrowse is a Python program for browsing through the Emacs Info
-documentation tree.  Documentation in Info is divided into "nodes",
-each of which discusses one topic and contains references to other
-nodes which discuss related topics.  Ibrowse has commands to follow the
-references and show you other nodes.
-
-h      Invoke the Ibrowse tutorial.
-?      Display this Summary node.
-q      Quit Ibrowse.
-w      Close current window.
-
-Selecting other nodes:
-n      Move to the "next" node of this node.
-p      Move to the "previous" node of this node.
-m      Pick menu item specified by name (or abbreviation).
-1-9    Pick first..ninth in node's menu.
-       Menu items select nodes that are "subsections" of this node.
-u      Move "up" from this node (i.e., from a subsection to a section).
-f      Follow a cross reference by name (or abbrev).  Type `l' to get back.
-l      Move back to the last node you were in.
-
-Moving within a node:
-Space  Scroll forward a full screen.     DEL, BS Scroll backward.
-b      Go to beginning of node.          
-
-Advanced commands:
-k      Clone current window (create an independent duplicate).
-c      Copy text selection to clipboard (for paste in another application).
-g      Move to node specified by name.
-       You may include a filename as well, as (FILENAME)NODENAME.
-d      Go to the main directory of Info files.
-t      Go to Top node of this file.
-s      Search through this Info file for node with specified regexp.
-\1f\f
-File: ibrowse  Node: Help-Small-Screen         Next: Help
-
-Since your terminal has an unusually small number of lines on its
-screen, it is necessary to give you special advice at the beginning.
-
-If you see the text "--All----" at near the bottom right corner of
-the screen, it means the entire text you are looking at fits on the
-screen.  If you see "--Top----" instead, it means that there is more
-text below that does not fit.  To move forward through the text and
-see another screen full, press the Space bar.  To move back up, press
-the key labeled Rubout or Delete or DEL.
-
-Here are 40 lines of junk, so you can try Spaces and Rubout and
-see what they do.  At the end are instructions of what you should do
-next.
-
-This is line 17
-This is line 18
-This is line 19
-This is line 20
-This is line 21
-This is line 22
-This is line 23
-This is line 24
-This is line 25
-This is line 26
-This is line 27
-This is line 28
-This is line 29
-This is line 30
-This is line 31
-This is line 32
-This is line 33
-This is line 34
-This is line 35
-This is line 36
-This is line 37
-This is line 38
-This is line 39
-This is line 40
-This is line 41
-This is line 42
-This is line 43
-This is line 44
-This is line 45
-This is line 46
-This is line 47
-This is line 48
-This is line 49
-This is line 50
-This is line 51
-This is line 52
-This is line 53
-This is line 54
-This is line 55
-This is line 56
-
-If you have managed to get here, go back to the beginning with
-Rubout, and come back here again, then you understand Space and
-Rubout.  So now type an "n"--just one character; don't type the
-quotes and don't type a Return afterward-- to get to the normal start
-of the course.
-\1f\f
-File: ibrowse  Node: Help      Next: Help-P    Previous: Help-Small-Screen
-
-You are talking to the program Ibrowse, for reading documentation.
-
-  Right now you are looking at one "Node" of Information.
-A node contains text describing a specific topic at a specific
-level of detail.  This node's topic is "how to use Ibrowse".
-
-  The top line of a node is its "header".  This node's header (look at
-it now) says that it is the node named "Help" in the file "ibrowse".
-It says that the Next node after this one is the node called "Help-P".
-An advanced Ibrowse command lets you go to any node whose name you know.
-
-  Besides a "Next", a node can have a "Previous" or an "Up".
-This node has a "Previous" but no "Up", as you can see.
-
-  Now it's time to move on to the Next node, named "Help-P".
-
->> Type "n" to move there.  Type just one character;
-   don't type the quotes and don't type a Return afterward.
-
-">>" in the margin means it is really time to try a command.
-\1f
-File: ibrowse  Node: Help-P    Next: Help-Page Previous: Help
-
-This node is called "Help-P".  The "Previous" node, as you see, is
-"Help", which is the one you just came from using the "N" command.
-Another "N" command now would take you to the Next node, "Help-Page".
-
->> But don't do that yet.  First, try the "p" command, which takes
-you to the Previous node.  When you get there, you can do an "n"
-again to return here.
-
-  This all probably seems insultingly simple so far, but DON'T be
-led into skimming.  Things will get more complicated soon.  Also,
-don't try a new command until you are told it's time to.  Otherwise,
-you may make Ibrowse skip past an important warning that was coming up.
-
->> Now do an "n" to get to the node "Help-Page" and learn more.
-\1f\f
-File: ibrowse  Node: Help-Page Next: Help-M    Previous: Help-P
-
-Space, Backspace, and B commands.
-
-  This node's header tells you that you are now at node "Help-Page", and
-that "P" would get you back to "Help-P".  The line starting "Space,"
-is a "Title", saying what the node is about (most nodes have titles).
-
-  This is a big node and it doesn't all fit on your display screen.
-You can tell that there is more that isn't visible because you
-the scroll bar on the side of the window has become active (gray).
-
-  The Space, Backspace and B commands exist to allow you to "move
-around" in a node that doesn't all fit on the screen at once.
-Space moves forward, to show what was below the bottom of the screen.
-Backspace moves backward, to show what was above the top of the screen
-(there isn't anything above the top until you have typed some spaces).
-
->> Now try typing a Space (afterward, type a Backspace to return here).
-
-  When you type the space, the two lines that were at the bottom of the 
-screen appear at the top, followed by more lines.  Backspace takes the
-two lines from the top and moves them to the bottom, USUALLY, but if
-there are not a full screen's worth of lines above them they may not
-make it all the way to the bottom.
-
-  If you type a Space when there is no more to see, it will ring the
-bell and otherwise do nothing.  The same goes for a Backspace when
-the header of the node is visible.
-
-  Of course you can use the mouse and directly move the scroll bar
-as well, but Ibrowse has keyboard commands for almost everything,
-including scrolling.  These keyboard commands are called "shortcuts",
-because it generally takes less effort to press a key on the
-keyboard than to move the mouse.  On the other hand, if you are
-an infrequent user of Ibrowse, you can do everything with the
-mouse that you can do with the keyboard.  Just look in the menus
-(I'm sure you must know how to use the menus on this system, or
-else you couldn't have gotten this far...).  In fact you'll see that
-the commands and shortcuts listed in the menus are the same as those
-described in this course.  You can use the shortcuts either with or
-without the "Command" or "Meta" key.
-
-  Two menus are always available: the "Ibrowse" menu contains commands
-pertaining to the Ibrowse program at large, while the "Navigation" menu
-contains commands that move around between nodes.  There may be other
-menus; these will be explained later.
-
-  To move back to the beginning of the node you are on, you can type
-a lot of Backspaces.  You can also type simply "b" for beginning.
->> Try that now.  (I have put in enough verbiage to make sure you are
-   not on the first screenful now).  Then come back, with Spaces.
-
-  You have just learned a considerable number of commands.  If you
-want to use one but have trouble remembering which, just pull down
-the menus to get a summary of commands and shortcuts.  Some additional
-shortcuts (not listed in the menus) are listed by the "Short help"
-command.  This brings up a dialog box which you can acknowledge
-by clicking the OK button or pressing the Return key.
-
-  From now on, you will encounter large nodes without warning, and
-will be expected to know how to use Space and Backspace to move
-around in them without being told.  Since you could change the
-size of the window used, it would be impossible to warn you anyway.
-
->> Now type "n" to see the description of the "m" command.
-\1f\f
-File: ibrowse  Node: Help-M    Next: Help-Adv  Previous: Help-Page
-
-Menus and the "m" command
-
-  With only the "n" and "p" commands for moving between nodes, nodes
-are restricted to a linear sequence.  Menus allow a branching
-structure.  A menu is a list of other nodes you can move to.  It is
-actually just part of the text of the node formatted specially so that
-Ibrowse can interpret it.  The beginning of a menu is always identified
-by a line which starts with "* Menu:".  A node contains a menu if and
-only if it has a line in it which starts that way.  The only menu you
-can use at any moment is the one in the node you are in.  To use a
-menu in any other node, you must move to that node first.
-
-  (There is an unfortunate confusion of terms here.  "Menu" may refer
-to one of the Ibrowse menus at the top, such as as the "Ibrowse" and
-"Navigation" menus explained in the previous node, or to the menu in
-a node.  Where confusion is possible, these will be disambiguated by
-calling them "Ibrowse menus" or "node menu".)
-
-  After the start of the menu, each line that starts with a "*"
-identifies one subtopic.  The line will usually contain a brief name
-for the subtopic (followed by a ":"), the name of the node that talks
-about that subtopic, and optionally some further description of the
-subtopic.  Lines in the menu that don't start with a "*" have no
-special meaning - they are only for the human reader's benefit and do
-not define additional subtopics.  Here is an example:
-* Foo: FOO's Node      This tells about FOO
-The subtopic name is Foo, and the node describing it is "FOO's Node".
-The rest of the line is just for the reader's Information.
-[[ But this line is not a real menu item, simply because there is
-no line above it which starts with "* Menu:".]]
-
-  When you use a menu to go to another node (in a way that will be
-described soon), what you specify is the subtopic name, the first
-thing in the menu line.  Ibrowse uses it to find the menu line, extracts
-the node name from it, and goes to that node.  The reason that there
-is both a subtopic name and a node name is that the node name must be
-meaningful to the computer and may therefore have to be ugly looking.
-The subtopic name can be chosen just to be convenient for the user to
-specify.  Often the node name is convenient for the user to specify
-and so both it and the subtopic name are the same.  There is an
-abbreviation for this:
-* Foo::   This tells about FOO
-This means that the subtopic name and node name are the same; they are
-both "Foo".
-
->>  Now use Spaces to find the menu in this node, then come back to
-the front with a "b".  As you see, a menu is actually visible
-in its node.  If you can't find a menu in a node by looking at it,
-then the node doesn't have a menu and the "m" command is not available.
-
-  (Actually, a quicker way to see if there is a node menu, is to look
-for an Ibrowse menu at the top named "Menu".)
-
-  The command to go to one of the subnodes is "m" - but DON'T DO IT
-YET!  Before you use "m", you must understand the difference between
-commands and arguments.  So far, you have learned several commands
-that do not need arguments.  When you type one, Ibrowse processes it and
-is instantly ready for another command.  The "m" command is different:
-it is incomplete without the NAME OF THE SUBTOPIC.  Once you have
-typed "m", Ibrowse wants to read the subtopic name.
-
-  Thanks to modern user interface technology, this will be obvious:
-you are prompted for the subtopic name in a dialog box.  When you are
-finished typing the name, press Return or click the OK button.  You can
-cancel the dialog box by clicking the Cancel button.  The first subtopic
-is provided as a default choice, so if you want to go there, you can
-just press Return.
-
-  You can abbreviate the subtopic name.  If the abbreviation is not
-unique, the first matching subtopic is chosen.  Some menus will put
-the shortest possible abbreviation for each subtopic name in capital
-letters, so you can see how much you need to type.  It does not
-matter whether you use upper case or lower case when you type the
-subtopic.  You should not put any spaces at the end, or inside of the
-item name, except for one space where a space appears in the item in
-the menu.
-
-  Here is a menu to give you a chance to practice.
-
-* Menu:           The menu starts here.
-
-This menu gives you three ways of going to one place, Help-FOO.
-
-* Foo: Help-FOO        A node you can visit for fun
-* Bar: Help-FOO        Strange!  two ways to get to the same place.
-* Help-FOO::           And yet another!
-
->> Now type just an "m" and see what happens. (Read ahead before
->> trying this out, as the dialog box will probably cover these
->> instructions!)
-
-  Now you are "inside" an "m" command.  Commands can't be used now;
-the next thing you will type must be the name of a subtopic.
-
-  You can change your mind about doing the "m" by clicking the Cancel
-button.
->> Try that now;  notice the dialog box disappear.
->> Then type another "m".
-
->> Now type "BAR", the item name.  Don't type Return yet.
-
-  While you are typing the item name, you can use the Backspace
-key to cancel one character at a time if you make a mistake.
->> Type one to cancel the "R".  You could type another "R" to
-replace it.  You don't have to, since "BA" is a valid abbreviation.
->> Now you are ready to go.  Type a Return.
-
-  After visiting Help-FOO, you should return here (it will tell how).
-
->> Type "n" to see more commands.
-\1f
-File: ibrowse  Node: Help-FOO  Up: Help-M
-
-The "u" command
-
-  Congratulations!  This is the node Help-FOO.  Unlike the other
-nodes you have seen, this one has an "Up": "Help-M", the node you
-just came from via the "m" command.  This is the usual convention--
-the nodes you reach from a menu have Ups that lead back to the menu.
-Menus move Down in the tree, and Up moves Up.  Previous, on the other
-hand, is usually used to "stay on the same level but go backwards".
-
-  You can go back to the node Help-M by typing the command
-"u" for "Up".  That will put you at the FRONT of the node - to get
-back to where you were reading you will have to type some Spaces.
-
->> Now type "u" to move back up to Help-M.
-\1f\f
-File: ibrowse  Node: Help-Adv  Next: Help-Q    Previous: Help-M
-
-Some advanced Ibrowse commands
-
-  The course is almost over, so please stick with it to the end.
-
-  If you have been moving around to different nodes and wish to
-retrace your steps, the "l" command ("l" for "last") will do that, one
-node at a time.  If you have been following directions, an "l" command
-now will get you back to Help-M.  Another "l" command would undo the "u"
-and get you back to Help-FOO.  Another "l" would undo the M and get you
-back to Help-M.
-
->> Try typing three "l"'s, pausing in between to see what each "l" does.
-Then follow directions again and you will end up back here.
-
-  Note the difference between "l" and "p":  "l" moves to where YOU
-last were, whereas "p" always moves to the node which the header says
-is the "Previous" node (from this node, to Help-M).
-
-  The "d" command gets you instantly to the Directory node.
-This node, which is the first one you saw when you entered Ibrowse,
-has a menu which leads (directly, or indirectly through other menus),
-to all the nodes that exist.
-
->> Try doing a "d", then do an "l" to return here (yes, DO return).
-
-  Sometimes, in Ibrowse documentation, you will see a cross reference.
-Cross references look like this: *Note Cross: Help-Cross.  That is a
-real, live cross reference which is named "Cross" and points at the
-node named "Help-Cross".
-
-  If you wish to follow a cross reference, you must use the "f"
-command.  The "f" prompts for the cross reference name (in this case,
-"Cross") with a dialog box.
-
->> Type "f", followed by "Cross", and a Return.
-
-  The "f" command allows abbreviations just like "m".
-
-  To get a list of all the cross references in the current node,
-look in the Ibrowse menu at the top labeled "Footnotes".  This menu is
-only present if there are cross references in the current node, and
-can be used to directly follow a cross reference, just like the "Menu"
-menu is another way to choose an item of the node's menu.
-
->> Now type "n" to see the last node of the course.
-\1f
-File: ibrowse  Node: Help-Cross
-
-  This is the node reached by the cross reference named "Cross".
-
-  While this node is specifically intended to be reached by a cross
-reference, most cross references lead to nodes that "belong" someplace
-else far away in the structure of Ibrowse.  So you can't expect the
-footnote to have a Next, Previous or Up pointing back to where you
-came from.  In general, the "l" (el) command is the only way to get
-back there.
-
->> Type "l" to return to the node where the cross reference was.
-\1f
-File: ibrowse  Node: Help-Q    Previous: Help-Adv      Up: Top
-
-  To get out of Ibrowse, type "q" for "Quit".  All Ibrowse windows
-will be closed (on UNIX, only those managed by the same process).
-To close just one window, use the standard method of closing windows
-on your system; you can also use "w".
-
-  This is the end of the course on using Ibrowse.  There are some other
-commands that are not essential or meant for experienced users;  they
-are useful, and you can find them by looking in the directory for
-documentation on Ibrowse.  Finding them will be a good exercise in using
-Ibrowse in the usual manner.
-
->> Close this window and find back the window where you typed "h"
-   to enter this tutorial.
-   Then type "d" to go to the Ibrowse directory node if necessary,
-   and choose the "Ibrowse" menu item, to get to the node about
-   Ibrowse and see what other help is available.
-\1f\f
-File: ibrowse,  Node: Expert,  Up: Top,  Previous: Top,  Next: Add
-
-Some Advanced Ibrowse Commands ("c", "k", "g", "s", "1" - "9", arrows).
-
-The "c" command lets you copy text from the window to the clipboard.
-You must first select the text to be copied with the mouse.
-
-The "k" command means "klone" (we are running out of letters now...).
-It creates a new Ibrowse window, showing the same node as the current.
-You can then make an excursion in the new window to different nodes or
-files, while the old window keeps showing the original node.  Each
-window has its own history for use by the "l" command.
-
-If you know a node's name, you can go there with the "g" command.
-This prompts for a node name with a dialog box.  Entering, "Top"
-would go to the node called Top in this file (its directory node).
-Pressing "g" again and entering "Expert" would come back here.
-
-Unlike "m", "g" does not allow the use of abbreviations.
-
-To go to a node in another file, you can include the filename in the
-node name by putting it at the front, in parentheses.  Thus,
-"(dir)Top" would go to the Ibrowse Directory node, which is
-node Top in the file dir.
-
-The node name "*" specifies the whole file.  So you can look at all
-of the current file by typing "*" or all of any other file
-with "(FILENAME)*".
-
-File names are converted to lower case before they are tried; this
-is necessary to be compatible with Emacs Info.  (File names are
-generally relative to the Info directory, but needn't be.)
-
-The "s" command allows you to search a whole file for a regular
-expression.  Unlike the corresponding Emacs Info command, it will
-not search beyond the end of the current node.
-
-Regular expressions are like in UNIX egrep; if you don't know what
-regular expressions are, limit your search strings to letters, digits
-and spaces.  Searches in Ibrowse are case-sensitive; searching for
-"foo" will not find "Foo" or "FOO"!
-
-A description of regular expressions as they occur in Emacs is
-available.  (*Note Emacs Regular Expressions: (regex)syntax.)
-Ibrowse regular expressions are slightly different: the meaning
-of \( \| \) is swapped with that of ( | ), and there are no
-escapes to handle "words" specially.
-
-Searching starts after the current focus position.  The "B" command
-resets the focus to the beginning of the file, but space and backspace
-leave it unchanged (so they may render the focus invisible).
-
-If you grudge the system each character of type-in it requires,
-you might like to use the commands "1", "2", "3", through "9".
-They are short for the first nine entries of the node menu.
-
-The left, right and up arrow keys are duplicates of "p", "n" and "u".
-
-The down arrow key, as well as the Return key, goes to the first item
-of the node's menu if there is one, else it executes "n".  This is a
-quick way to visit all nodes in a tree in pre-order: use Return to go
-down and right as far as possible, then use "u" and "n" to go right
-at the next higher level.
-\1f\f
-File: ibrowse,  Node: Add,  Up: Top,  Previous: Expert,  Next: Menus
-
-To add a new topic to the list in the directory, you must
- 1) enter the Emacs text editor.  *Note Emacs: (emacs).
- 2) create a node, in some file, to document that topic.
- 3) put that topic in the menu in the directory.  *Note Menu: Menus.
-
-  The new node can live in an existing documentation file, or in a new
-one.  It must have a ^_ character before it (invisible to the user;
-this node has one but you can't see it), and it ends with either a ^_,
-or the end of file.  A nice way to make a node boundary be a
-page boundary as well is to put a ^L RIGHT AFTER the ^_.
-
-  The ^_ starting a node must be followed by a newline or a ^L newline,
-after which comes the node's header line.  The header line must give
-the node's name (by which Ibrowse will find it), and state the names of
-the Next, Previous, and Up nodes (if there are any).  As you can see,
-this node's Up node is the node Top, which points at all the
-documentation for Ibrowse.  The Next node is "Menus".
-
-  The keywords "Node", "Previous", "Up" and "Next",  may appear in
-any order, anywhere in the header line, but the recommended order is
-the one in this sentence.  Each keyword must be followed by a colon,
-spaces and tabs, and then the appropriate name.  The name may be
-terminated with a tab, a comma, or a newline.  A space does not end
-it; node names may contain spaces.  The case of letters in the names
-is insignificant.  "Previous" can be abbreviated to "Prev".
-
-  A node name has two forms.  A node in the current file is named by
-what appears after the "Node: " in that node's first line.  For
-example, this node's name is "Add".  A node in another file is named
-by "(FILENAME)NODE-WITHIN-FILE", as in "(ibrowse)Add" for this node.
-If the file name is relative, it is taken starting from the standard
-Info file directory of your site.  The name "(FILENAME)Top" can be
-abbreviated to just "(FILENAME)".  By convention, the name "Top" is
-used for the "highest" node in any single file - the node whose "Up"
-points out of the file.  The Directory node is "(dir)".  The Top node
-of a document file listed in the Directory should have an "Up: (dir)"
-in it.
-
-  The node name "*" is special: it refers to the entire file.  Thus,
-g* will show you the whole current file.  The use of the node * is to
-make it possible to make old-fashioned, unstructured files into nodes
-of the tree.  Footnotes and node menus appearing in a file are disabled
-when it is viewed in this way.
-
-  The "Node:" name, in which a node states its own name, must not
-contain a filename, since Ibrowse when searching for a node does not
-expect one to be there.  The Next, Previous and Up names may contain
-them.  In this node, since the Up node is in the same file, it was not
-necessary to use one. 
-
-  Note that the nodes in this file have a File name in the header
-line.  The File names are ignored by Ibrowse, but they serve as
-comments to help identify the node for the user.
-\1f\f
-File: ibrowse, Node: Menus, Previous: Add, Up: Top, Next: Cross-refs
-
-How to Create Menus:
-
-  Any node in the Ibrowse hierarchy may have a MENU--a list of subnodes. 
-The "m" command searches the current node's menu for the topic which it
-reads from the terminal.
-
-  A menu begins with a line starting with "* Menu:".  The rest of the
-line is a comment.  After the starting line, every line that begins
-with a "* " lists a single topic.  The name of the topic--the arg
-that the user must give to the "m" command to select this topic--
-comes right after the star and space, and is followed by 
-a colon, spaces and tabs, and the name of the node which discusses
-that topic.  The node name, like node names following Next,
-Previous and Up, may be terminated with a tab, comma, or newline;
-it may also be terminated with a period.
-
-  If the node name and topic name are the same, than rather than
-giving the name twice, the abbreviation "* NAME::" may be used
-(and should be used, whenever possible, as it reduces the visual
-clutter in the menu).
-
-  It is considerate to choose the topic names so that they differ
-from each other very near the beginning--this allows the user to type
-short abbreviations.  In a long menu, it is a good idea to capitalize
-the beginning of each item name which is the minimum acceptable
-abbreviation for it (a long menu is more than 5 or so entries).
-
-  The node's listed in a node's menu are called its "subnodes", and
-it is their "superior".  They should each have an "Up:" pointing at
-the superior.  It is often useful to arrange all or most of the
-subnodes in a sequence of Next's/Previous's so that someone who
-wants to see them all need not keep revisiting the Menu.
-
-  The Info Directory is simply the menu of the node "(dir)Top"--that
-is, node Top in file .../info/dir.  You can put new entries in that
-menu just like any other menu.  The Info Directory is NOT the same as
-the file directory called "info".  It happens that many of Ibrowse's
-files live on that file directory, but they don't have to; and files
-on that directory are not automatically listed in the Info Directory
-node.
-
-  The Ibrowse program uses a second directory called .../ibrowse,
-which contains versions of the "dir" and "info" files adapted to
-Ibrowse (the latter renamed to "ibrowse", obviously).  It searches
-any file first in the "ibrowse", then in the "info" directory.
-(Actually, the search path is configurable.)
-
-  Also, although the Info node graph is claimed to be a "hierarchy",
-in fact it can be ANY directed graph.  Shared structures and pointer
-cycles are perfectly possible, and can be used if they are
-appropriate to the meaning to be expressed.  There is no need for all
-the nodes in a file to form a connected structure.  In fact, this
-file has two connected components.  You are in one of them, which is
-under the node Top;  the other contains the node Help which the "h"
-command goes to.  In fact, since there is no garbage collector,
-nothing terrible happens if a substructure is not pointed to, but
-such a substructure will be rather useless since nobody will ever
-find out that it exists.
-\1f
-File: ibrowse, Node: Cross-refs, Previous: Menus, Up: Top, Next: Tags
-
-Creating Cross References:
-
-  A cross reference can be placed anywhere in the text, unlike a menu
-item which must go at the front of a line.  A cross reference looks
-like a menu item except that it has "*note" instead of "*".  It CANNOT
-be terminated by a ")", because ")"'s are so often part of node names.
-If you wish to enclose a cross reference in parentheses, terminate it
-with a period first.  Here are two examples of cross references pointers:
-
-     *Note details: commands.  (See *note 3: Full Proof.)
-
-They are just examples.  The places they "lead to" don't really exist!
-\1f
-File: ibrowse,  Node: Tags,  Previous: Cross-refs,  Up: Top,  Next: Checking
-
-Tag Tables for Info Files:
-
-  You can speed up the access to nodes of a large Info file by giving
-it a tag table.  Unlike the tag table for a program, the tag table for
-an Info file lives inside the file itself and will automatically be
-used whenever Ibrowse reads in the file.
-
-  To make a tag table, go to a node in the file using Emacs Info and type
-M-x Info-tagify.  Then you must use C-x C-s to save the file.
-
-  Once the Info file has a tag table, you must make certain it is up
-to date.  If, as a result of deletion of text, any node moves back
-more than a thousand characters in the file from the position
-recorded in the tag table, Ibrowse will no longer be able to find that
-node.  To update the tag table, use the Info-tagify command again.
-
-  An Info file tag table appears at the end of the file and looks like
-this:
-
-^_^L
-Tag Table:
-File: ibrowse, Node: Cross-refs\7f21419
-File: ibrowse,  Node: Tags\7f22145
-^_
-End Tag Table
-
-Note that it contains one line per node, and this line contains
-the beginning of the node's header (ending just after the node name),
-a rubout (DEL) character, and the character position in the file of the
-beginning of the node.  The words "Tag Table" may occur in lower case
-as well.
-
-It is also possible for an extra level of indirection to be present.
-In this case, the first line of the Tag table contains the string
-"(Indirect)", and preceding the tag table is another "pseudo node"
-whose header reads "Indirect:".  Each following line has the form
-"filename: offset", meaning that nodes at that offset or larger (but
-less than the offset in the next line) really occur in the file named
-here, and that the file's offset should be subtracted from the node's
-offset.  (Indirect tables are created by texinfo for large files.
-*Note Texinfo: (texinfo).  *Note Splitting files: (texinfo)Splitting.)
-\1f
-File: ibrowse,  Node: Checking,  Previous: Tags,  Up: Top
-
-Checking an Info File:
-
-  When creating an Info file, it is easy to forget the name of a node
-when you are making a pointer to it from another node.  If you put in
-the wrong name for a node, this will not be detected until someone
-tries to go through the pointer using Ibrowse.  Verification of the Info
-file is an automatic process which checks all pointers to nodes and
-reports any pointers which are invalid.  Every Next, Previous, and Up
-is checked, as is every menu item and every cross reference.  In addition,
-any Next which doesn't have a Previous pointing back is reported.
-Only pointers within the file are checked, because checking pointers
-to other files would be terribly slow.  But those are usually few.
-
-  To check an Info file, do M-x Info-validate while looking at any
-node of the file with Emacs Info.
-\1f\f
-Tag table:
-Node: Top\7f117
-Node: Summary\7f952
-Node: Help-Small-Screen\7f997
-Node: Help\7f2628
-Node: Help-P\7f3588
-Node: Help-Page\7f4348
-Node: Help-M\7f7763
-Node: Help-FOO\7f13183
-Node: Help-Adv\7f13887
-Node: Help-Cross\7f15923
-Node: Help-Q\7f16443
-Node: Expert\7f17326
-Node: Add\7f20280
-Node: Menus\7f23273
-Node: Cross-refs\7f26394
-Node: Tags\7f27050
-Node: Checking\7f28966
-\1f
-End tag table
diff --git a/Demo/stdwin/ibrowse/ibrowse.py b/Demo/stdwin/ibrowse/ibrowse.py
deleted file mode 100755 (executable)
index eec5eb7..0000000
+++ /dev/null
@@ -1,617 +0,0 @@
-# Browser for "Info files" as used by the Emacs documentation system.
-#
-# Now you can read Info files even if you can't spare the memory, time or
-# disk space to run Emacs.  (I have used this extensively on a Macintosh
-# with 1 Megabyte main memory and a 20 Meg harddisk.)
-#
-# You can give this to someone with great fear of complex computer
-# systems, as long as they can use a mouse.
-#
-# Another reason to use this is to encourage the use of Info for on-line
-# documentation of software that is not related to Emacs or GNU.
-# (In particular, I plan to redo the Python and STDWIN documentation
-# in texinfo.)
-
-
-# NB: this is not a self-executing script.  You must startup Python,
-# import ibrowse, and call ibrowse.main().  On UNIX, the script 'ib'
-# runs the browser.
-
-
-# Configuration:
-#
-# - The pathname of the directory (or directories) containing
-#   the standard Info files should be set by editing the
-#   value assigned to INFOPATH in module ifile.py.
-#
-# - The default font should be set by editing the value of FONT
-#   in this module (ibrowse.py).
-#
-# - For fastest I/O, you may look at BLOCKSIZE and a few other
-#   constants in ifile.py.
-
-
-# This is a fairly large Python program, split in the following modules:
-#
-# ibrowse.py   Main program and user interface.
-#              This is the only module that imports stdwin.
-#
-# ifile.py     This module knows about the format of Info files.
-#              It is imported by all of the others.
-#
-# itags.py     This module knows how to read prebuilt tag tables,
-#              including indirect ones used by large texinfo files.
-#
-# icache.py    Caches tag tables and visited nodes.
-
-
-# XXX There should really be a different tutorial, as the user interface
-# XXX differs considerably from Emacs...
-
-
-import sys
-import regexp
-import stdwin
-from stdwinevents import *
-import string
-from ifile import NoSuchFile, NoSuchNode
-import icache
-
-
-# Default font.
-# This should be an acceptable argument for stdwin.setfont();
-# on the Mac, this can be a pair (fontname, pointsize), while
-# under X11 it should be a standard X11 font name.
-# For best results, use a constant width font like Courier;
-# many Info files contain tabs that don't align with other text
-# unless all characters have the same width.
-#
-#FONT = ('Monaco', 9)          # Mac
-FONT = '-schumacher-clean-medium-r-normal--14-140-75-75-c-70-iso8859-1'        # X11
-
-
-# Try not to destroy the list of windows when reload() is used.
-# This is useful during debugging, and harmless in production...
-#
-try:
-       dummy = windows
-       del dummy
-except NameError:
-       windows = []
-
-
-# Default main function -- start at the '(dir)' node.
-#
-def main():
-       start('(dir)')
-
-
-# Start at an arbitrary node.
-# The default file is 'ibrowse'.
-#
-def start(ref):
-       stdwin.setdefscrollbars(0, 1)
-       stdwin.setfont(FONT)
-       stdwin.setdefwinsize(76*stdwin.textwidth('x'), 22*stdwin.lineheight())
-       makewindow('ibrowse', ref)
-       mainloop()
-
-
-# Open a new browser window.
-# Arguments specify the default file and a node reference
-# (if the node reference specifies a file, the default file is ignored).
-#
-def makewindow(file, ref):
-       win = stdwin.open('Info file Browser, by Guido van Rossum')
-       win.mainmenu = makemainmenu(win)
-       win.navimenu = makenavimenu(win)
-       win.textobj = win.textcreate((0, 0), win.getwinsize())
-       win.file = file
-       win.node = ''
-       win.last = []
-       win.pat = ''
-       win.dispatch = idispatch
-       win.nodemenu = None
-       win.footmenu = None
-       windows.append(win)
-       imove(win, ref)
-
-# Create the 'Ibrowse' menu for a new browser window.
-#
-def makemainmenu(win):
-       mp = win.menucreate('Ibrowse')
-       mp.callback = []
-       additem(mp, 'New window (clone)',       'K', iclone)
-       additem(mp, 'Help (tutorial)',          'H', itutor)
-       additem(mp, 'Command summary',          '?', isummary)
-       additem(mp, 'Close this window',        'W', iclose)
-       additem(mp, '', '', None)
-       additem(mp, 'Copy to clipboard',        'C', icopy)
-       additem(mp, '', '', None)
-       additem(mp, 'Search regexp...',         'S', isearch)
-       additem(mp, '', '', None)
-       additem(mp, 'Reset node cache',         '',  iresetnodecache)
-       additem(mp, 'Reset entire cache',       '',  iresetcache)
-       additem(mp, '', '', None)
-       additem(mp, 'Quit',                     'Q', iquit)
-       return mp
-
-# Create the 'Navigation' menu for a new browser window.
-#
-def makenavimenu(win):
-       mp = win.menucreate('Navigation')
-       mp.callback = []
-       additem(mp, 'Menu item...',             'M', imenu)
-       additem(mp, 'Follow reference...',      'F', ifollow)
-       additem(mp, 'Go to node...',            'G', igoto)
-       additem(mp, '', '', None)
-       additem(mp, 'Next node in tree',        'N', inext)
-       additem(mp, 'Previous node in tree',    'P', iprev)
-       additem(mp, 'Up in tree',               'U', iup)
-       additem(mp, 'Last visited node',        'L', ilast)
-       additem(mp, 'Top of tree',              'T', itop)
-       additem(mp, 'Directory node',           'D', idir)
-       return mp
-
-# Add an item to a menu, and a function to its list of callbacks.
-# (Specifying all in one call is the only way to keep the menu
-# and the list of callbacks in synchrony.)
-#
-def additem(mp, text, shortcut, function):
-       if shortcut:
-               mp.additem(text, shortcut)
-       else:
-               mp.additem(text)
-       mp.callback.append(function)
-
-
-# Stdwin event processing main loop.
-# Return when there are no windows left.
-# Note that windows not in the windows list don't get their events.
-#
-def mainloop():
-       while windows:
-               event = stdwin.getevent()
-               if event[1] in windows:
-                       try:
-                               event[1].dispatch(event)
-                       except KeyboardInterrupt:
-                               # The user can type Control-C (or whatever)
-                               # to leave the browser without closing
-                               # the window.  Mainly useful for
-                               # debugging.
-                               break
-                       except:
-                               # During debugging, it was annoying if
-                               # every mistake in a callback caused the
-                               # whole browser to crash, hence this
-                               # handler.  In a production version
-                               # it may be better to disable this.
-                               #
-                               msg = sys.exc_type
-                               if sys.exc_value:
-                                       val = sys.exc_value
-                                       if type(val) <> type(''):
-                                               val = `val`
-                                       msg = msg + ': ' + val
-                               msg = 'Oops, an exception occurred: ' + msg
-                               event = None
-                               stdwin.message(msg)
-               event = None
-
-
-# Handle one event.  The window is taken from the event's window item.
-# This function is placed as a method (named 'dispatch') on the window,
-# so the main loop will be able to handle windows of a different kind
-# as well, as long as they are all placed in the list of windows.
-#
-def idispatch(event):
-       type, win, detail = event
-       if type == WE_CHAR:
-               if not keybindings.has_key(detail):
-                       detail = string.lower(detail)
-               if keybindings.has_key(detail):
-                       keybindings[detail](win)
-                       return
-               if detail in '0123456789':
-                       i = eval(detail) - 1
-                       if i < 0: i = len(win.menu) + i
-                       if 0 <= i < len(win.menu):
-                               topic, ref = win.menu[i]
-                               imove(win, ref)
-                               return
-               stdwin.fleep()
-               return
-       if type == WE_COMMAND:
-               if detail == WC_LEFT:
-                       iprev(win)
-               elif detail == WC_RIGHT:
-                       inext(win)
-               elif detail == WC_UP:
-                       iup(win)
-               elif detail == WC_DOWN:
-                       idown(win)
-               elif detail == WC_BACKSPACE:
-                       ibackward(win)
-               elif detail == WC_RETURN:
-                       idown(win)
-               else:
-                       stdwin.fleep()
-               return
-       if type == WE_MENU:
-               mp, item = detail
-               if mp == None:
-                       pass # A THINK C console menu was selected
-               elif mp in (win.mainmenu, win.navimenu):
-                       mp.callback[item](win)
-               elif mp == win.nodemenu:
-                       topic, ref = win.menu[item]
-                       imove(win, ref)
-               elif mp == win.footmenu:
-                       topic, ref = win.footnotes[item]
-                       imove(win, ref)
-               return
-       if type == WE_SIZE:
-               win.textobj.move((0, 0), win.getwinsize())
-               (left, top), (right, bottom) = win.textobj.getrect()
-               win.setdocsize(0, bottom)
-               return
-       if type == WE_CLOSE:
-               iclose(win)
-               return
-       if not win.textobj.event(event):
-               pass
-
-
-# Paging callbacks
-
-def ibeginning(win):
-       win.setorigin(0, 0)
-       win.textobj.setfocus(0, 0) # To restart searches
-
-def iforward(win):
-       lh = stdwin.lineheight() # XXX Should really use the window's...
-       h, v = win.getorigin()
-       docwidth, docheight = win.getdocsize()
-       width, height = win.getwinsize()
-       if v + height >= docheight:
-               stdwin.fleep()
-               return
-       increment = max(lh, ((height - 2*lh) / lh) * lh)
-       v = v + increment
-       win.setorigin(h, v)
-
-def ibackward(win):
-       lh = stdwin.lineheight() # XXX Should really use the window's...
-       h, v = win.getorigin()
-       if v <= 0:
-               stdwin.fleep()
-               return
-       width, height = win.getwinsize()
-       increment = max(lh, ((height - 2*lh) / lh) * lh)
-       v = max(0, v - increment)
-       win.setorigin(h, v)
-
-
-# Ibrowse menu callbacks
-
-def iclone(win):
-       stdwin.setdefwinsize(win.getwinsize())
-       makewindow(win.file, win.node)
-
-def itutor(win):
-       # The course looks best at 76x22...
-       stdwin.setdefwinsize(76*stdwin.textwidth('x'), 22*stdwin.lineheight())
-       makewindow('ibrowse', 'Help')
-
-def isummary(win):
-       stdwin.setdefwinsize(76*stdwin.textwidth('x'), 22*stdwin.lineheight())
-       makewindow('ibrowse', 'Summary')
-
-def iclose(win):
-       #
-       # Remove the window from the windows list so the mainloop
-       # will notice if all windows are gone.
-       # Delete the textobj since it constitutes a circular reference
-       # to the window which would prevent it from being closed.
-       # (Deletion is done by assigning None to avoid crashes
-       # when closing a half-initialized window.)
-       #
-       if win in windows:
-               windows.remove(win)
-       win.textobj = None
-
-def icopy(win):
-       focustext = win.textobj.getfocustext()
-       if not focustext:
-               stdwin.fleep()
-       else:
-               stdwin.rotatecutbuffers(1)
-               stdwin.setcutbuffer(0, focustext)
-               # XXX Should also set the primary selection...
-
-def isearch(win):
-       try:
-               pat = stdwin.askstr('Search pattern:', win.pat)
-       except KeyboardInterrupt:
-               return
-       if not pat:
-               pat = win.pat
-               if not pat:
-                       stdwin.message('No previous pattern')
-                       return
-       try:
-               cpat = regexp.compile(pat)
-       except regexp.error, msg:
-               stdwin.message('Bad pattern: ' + msg)
-               return
-       win.pat = pat
-       f1, f2 = win.textobj.getfocus()
-       text = win.text
-       match = cpat.match(text, f2)
-       if not match:
-               stdwin.fleep()
-               return
-       a, b = match[0]
-       win.textobj.setfocus(a, b)
-
-
-def iresetnodecache(win):
-       icache.resetnodecache()
-
-def iresetcache(win):
-       icache.resetcache()
-
-def iquit(win):
-       for win in windows[:]:
-               iclose(win)
-
-
-# Navigation menu callbacks
-
-def imenu(win):
-       ichoice(win, 'Menu item (abbreviated):', win.menu, whichmenuitem(win))
-
-def ifollow(win):
-       ichoice(win, 'Follow reference named (abbreviated):', \
-               win.footnotes, whichfootnote(win))
-
-def igoto(win):
-       try:
-               choice = stdwin.askstr('Go to node (full name):', '')
-       except KeyboardInterrupt:
-               return
-       if not choice:
-               stdwin.message('Sorry, Go to has no default')
-               return
-       imove(win, choice)
-
-def inext(win):
-       prev, next, up = win.header
-       if next:
-               imove(win, next)
-       else:
-               stdwin.fleep()
-
-def iprev(win):
-       prev, next, up = win.header
-       if prev:
-               imove(win, prev)
-       else:
-               stdwin.fleep()
-
-def iup(win):
-       prev, next, up = win.header
-       if up:
-               imove(win, up)
-       else:
-               stdwin.fleep()
-
-def ilast(win):
-       if not win.last:
-               stdwin.fleep()
-       else:
-               i = len(win.last)-1
-               lastnode, lastfocus = win.last[i]
-               imove(win, lastnode)
-               if len(win.last) > i+1:
-                       # The move succeeded -- restore the focus
-                       win.textobj.setfocus(lastfocus)
-               # Delete the stack top even if the move failed,
-               # else the whole stack would remain unreachable
-               del win.last[i:] # Delete the entry pushed by imove as well!
-
-def itop(win):
-       imove(win, '')
-
-def idir(win):
-       imove(win, '(dir)')
-
-
-# Special and generic callbacks
-
-def idown(win):
-       if win.menu:
-               default = whichmenuitem(win)
-               for topic, ref in win.menu:
-                       if default == topic:
-                               break
-               else:
-                       topic, ref = win.menu[0]
-               imove(win, ref)
-       else:
-               inext(win)
-
-def ichoice(win, prompt, list, default):
-       if not list:
-               stdwin.fleep()
-               return
-       if not default:
-               topic, ref = list[0]
-               default = topic
-       try:
-               choice = stdwin.askstr(prompt, default)
-       except KeyboardInterrupt:
-               return
-       if not choice:
-               return
-       choice = string.lower(choice)
-       n = len(choice)
-       for topic, ref in list:
-               topic = string.lower(topic)
-               if topic[:n] == choice:
-                       imove(win, ref)
-                       return
-       stdwin.message('Sorry, no topic matches ' + `choice`)
-
-
-# Follow a reference, in the same window.
-#
-def imove(win, ref):
-       savetitle = win.gettitle()
-       win.settitle('Looking for ' + ref + '...')
-       #
-       try:
-               file, node, header, menu, footnotes, text = \
-                       icache.get_node(win.file, ref)
-       except NoSuchFile, file:
-               win.settitle(savetitle)
-               stdwin.message(\
-               'Sorry, I can\'t find a file named ' + `file` + '.')
-               return
-       except NoSuchNode, node:
-               win.settitle(savetitle)
-               stdwin.message(\
-               'Sorry, I can\'t find a node named ' + `node` + '.')
-               return
-       #
-       win.settitle('Found (' + file + ')' + node + '...')
-       #
-       if win.file and win.node:
-               lastnode = '(' + win.file + ')' + win.node
-               win.last.append((lastnode, win.textobj.getfocus()))
-       win.file = file
-       win.node = node
-       win.header = header
-       win.menu = menu
-       win.footnotes = footnotes
-       win.text = text
-       #
-       win.setorigin(0, 0) # Scroll to the beginnning
-       win.textobj.settext(text)
-       win.textobj.setfocus(0, 0)
-       (left, top), (right, bottom) = win.textobj.getrect()
-       win.setdocsize(0, bottom)
-       #
-       if win.footmenu: win.footmenu.close()
-       if win.nodemenu: win.nodemenu.close()
-       win.footmenu = None
-       win.nodemenu = None
-       #
-       win.menu = menu
-       if menu:
-               win.nodemenu = win.menucreate('Menu')
-               digit = 1
-               for topic, ref in menu:
-                       if digit < 10:
-                               win.nodemenu.additem(topic, `digit`)
-                       else:
-                               win.nodemenu.additem(topic)
-                       digit = digit + 1
-       #
-       win.footnotes = footnotes
-       if footnotes:
-               win.footmenu = win.menucreate('Footnotes')
-               for topic, ref in footnotes:
-                       win.footmenu.additem(topic)
-       #
-       win.settitle('(' + win.file + ')' + win.node)
-
-
-# Find menu item at focus
-#
-findmenu = regexp.compile('^\* [mM]enu:').match
-findmenuitem = regexp.compile( \
-       '^\* ([^:]+):[ \t]*(:|\([^\t]*\)[^\t,\n.]*|[^:(][^\t,\n.]*)').match
-#
-def whichmenuitem(win):
-       if not win.menu:
-               return ''
-       match = findmenu(win.text)
-       if not match:
-               return ''
-       a, b = match[0]
-       i = b
-       f1, f2 = win.textobj.getfocus()
-       lastmatch = ''
-       while i < len(win.text):
-               match = findmenuitem(win.text, i)
-               if not match:
-                       break
-               (a, b), (a1, b1), (a2, b2) = match
-               if a > f1:
-                       break
-               lastmatch = win.text[a1:b1]
-               i = b
-       return lastmatch
-
-
-# Find footnote at focus
-#
-findfootnote = \
-       regexp.compile('\*[nN]ote ([^:]+):[ \t]*(:|[^:][^\t,\n.]*)').match
-#
-def whichfootnote(win):
-       if not win.footnotes:
-               return ''
-       i = 0
-       f1, f2 = win.textobj.getfocus()
-       lastmatch = ''
-       while i < len(win.text):
-               match = findfootnote(win.text, i)
-               if not match:
-                       break
-               (a, b), (a1, b1), (a2, b2) = match
-               if a > f1:
-                       break
-               lastmatch = win.text[a1:b1]
-               i = b
-       return lastmatch
-
-
-# Now all the "methods" are defined, we can initialize the table
-# of key bindings.
-#
-keybindings = {}
-
-# Window commands
-
-keybindings['k'] = iclone
-keybindings['h'] = itutor
-keybindings['?'] = isummary
-keybindings['w'] = iclose
-
-keybindings['c'] = icopy
-
-keybindings['s'] = isearch
-
-keybindings['q'] = iquit
-
-# Navigation commands
-
-keybindings['m'] = imenu
-keybindings['f'] = ifollow
-keybindings['g'] = igoto
-
-keybindings['n'] = inext
-keybindings['p'] = iprev
-keybindings['u'] = iup
-keybindings['l'] = ilast
-keybindings['d'] = idir
-keybindings['t'] = itop
-
-# Paging commands
-
-keybindings['b'] = ibeginning
-keybindings['.'] = ibeginning
-keybindings[' '] = iforward
diff --git a/Demo/stdwin/ibrowse/icache.py b/Demo/stdwin/ibrowse/icache.py
deleted file mode 100755 (executable)
index 0629bf9..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-# Cache management for info file processing.
-# The function get_node() is the standard interface;
-# its signature is the same as ifile.get_node() but it uses
-# the cache and supports indirect tag tables.
-
-
-import string
-import ifile
-from ifile import NoSuchNode, NoSuchFile
-import itags
-
-
-# Special hack to save the cache when using reload().
-# This can just be "cache = {}" in a production version.
-#
-try:
-       dummy = cache
-       del dummy
-except NameError:
-       cache = {}
-
-
-# Clear the entire cache.
-#
-def resetcache():
-       for key in cache.keys():
-               del cache[key]
-
-
-# Clear the node info from the cache (the most voluminous data).
-#
-def resetnodecache():
-       for key in cache.keys():
-               tags, nodes = cache[key]
-               cache[key] = tags, {}
-
-
-# Get a node.
-#
-def get_node(curfile, ref):
-       file, node = ifile.parse_ref(curfile, ref)
-       file = string.lower(file)
-       node = string.lower(node)
-       if node == '*':
-               # Don't cache whole file references;
-               # reading the data is faster than displaying it anyway.
-               return ifile.get_whole_file(file) # May raise NoSuchFile
-       if not cache.has_key(file):
-               cache[file] = get_tags(file), {} # May raise NoSuchFile
-       tags, nodes = cache[file]
-       if not nodes.has_key(node):
-               if not tags.has_key(node):
-                       raise NoSuchNode, ref
-               file1, offset, line = tags[node]
-               if not file1:
-                       file1 = file
-               file1, node1, header, menu, footnotes, text = \
-                       ifile.get_file_node(file1, offset, node)
-               nodes[node] = file, node1, header, menu, footnotes, text
-       return nodes[node]
-
-
-# Get the tag table for a file.
-# Either construct one or get the one found in the file.
-# Raise NoSuchFile if the file isn't found.
-#
-def get_tags(file):
-       f = ifile.try_open(file) # May raise NoSuchFile
-       tags = itags.get_tags(f)
-       if not tags:
-               ###print 'Scanning file...'
-               f.seek(0)
-               tags = ifile.make_tags(f)
-       return tags
diff --git a/Demo/stdwin/ibrowse/ifile.py b/Demo/stdwin/ibrowse/ifile.py
deleted file mode 100755 (executable)
index 9447164..0000000
+++ /dev/null
@@ -1,328 +0,0 @@
-# Tools for info file processing.
-
-# XXX Need to be more careful with reading ahead searching for nodes.
-
-
-import regexp
-import string
-
-
-# Exported exceptions.
-#
-NoSuchFile = 'no such file'
-NoSuchNode = 'no such node'
-
-
-# The search path for info files; this is site-specific.
-# Directory names should end in a partname delimiter,
-# so they can simply be concatenated to a relative pathname.
-#
-#INFOPATH = ['', ':Info.Ibrowse:', ':Info:']   # Mac
-INFOPATH = ['', '/usr/local/emacs/info/']      # X11 on UNIX
-
-
-# Tunable constants.
-#
-BLOCKSIZE = 512                        # Qty to align reads to, if possible
-FUZZ = 2*BLOCKSIZE             # Qty to back-up before searching for a node
-CHUNKSIZE = 4*BLOCKSIZE                # Qty to read at once when reading lots of data
-
-
-# Regular expressions used.
-# Note that it is essential that Python leaves unrecognized backslash
-# escapes in a string so they can be seen by regexp.compile!
-#
-findheader = regexp.compile('\037\014?\n(.*\n)').match
-findescape = regexp.compile('\037').match
-parseheader = regexp.compile('[nN]ode:[ \t]*([^\t,\n]*)').match
-findfirstline = regexp.compile('^.*\n').match
-findnode = regexp.compile('[nN]ode:[ \t]*([^\t,\n]*)').match
-findprev = regexp.compile('[pP]rev[ious]*:[ \t]*([^\t,\n]*)').match
-findnext = regexp.compile('[nN]ext:[ \t]*([^\t,\n]*)').match
-findup = regexp.compile('[uU]p:[ \t]*([^\t,\n]*)').match
-findmenu = regexp.compile('^\* [mM]enu:').match
-findmenuitem = regexp.compile( \
-       '^\* ([^:]+):[ \t]*(:|\([^\t]*\)[^\t,\n.]*|[^:(][^\t,\n.]*)').match
-findfootnote = regexp.compile( \
-       '\*[nN]ote ([^:]+):[ \t]*(:|[^:][^\t,\n.]*)').match
-parsenoderef = regexp.compile('^\((.*)\)(.*)$').match
-
-
-# Get a node and all information pertaining to it.
-# This doesn't work if there is an indirect tag table,
-# and in general you are better off using icache.get_node() instead.
-# Functions get_whole_file() and get_file_node() provide part
-# functionality used by icache.
-# Raise NoSuchFile or NoSuchNode as appropriate.
-#
-def get_node(curfile, ref):
-       file, node = parse_ref(curfile, ref)
-       if node == '*':
-               return get_whole_file(file)
-       else:
-               return get_file_node(file, 0, node)
-#
-def get_whole_file(file):
-       f = try_open(file) # May raise NoSuchFile
-       text = f.read()
-       header, menu, footnotes = ('', '', ''), [], []
-       return file, '*', header, menu, footnotes, text
-#
-def get_file_node(file, offset, node):
-       f = try_open(file) # May raise NoSuchFile
-       text = find_node(f, offset, node) # May raise NoSuchNode
-       node, header, menu, footnotes = analyze_node(text)
-       return file, node, header, menu, footnotes, text
-
-
-# Parse a node reference into a file (possibly default) and node name.
-# Possible reference formats are: "NODE", "(FILE)", "(FILE)NODE".
-# Default file is the curfile argument; default node is Top.
-# A node value of '*' is a special case: the whole file should
-# be interpreted (by the caller!) as a single node.
-#
-def parse_ref(curfile, ref):
-       match = parsenoderef(ref)
-       if not match:
-               file, node = curfile, ref
-       else:
-               (a, b), (a1, b1), (a2, b2) = match
-               file, node = ref[a1:b1], ref[a2:b2]
-       if not file:
-               file = curfile # (Is this necessary?)
-       if not node:
-               node = 'Top'
-       return file, node
-
-
-# Extract node name, links, menu and footnotes from the node text.
-#
-def analyze_node(text):
-       #
-       # Get node name and links from the header line
-       #
-       match = findfirstline(text)
-       if match:
-               (a, b) = match[0]
-               line = text[a:b]
-       else:
-               line = ''
-       node = get_it(text, findnode)
-       prev = get_it(text, findprev)
-       next = get_it(text, findnext)
-       up = get_it(text, findup)
-       #
-       # Get the menu items, if there is a menu
-       #
-       menu = []
-       match = findmenu(text)
-       if match:
-               (a, b) = match[0]
-               while 1:
-                       match = findmenuitem(text, b)
-                       if not match:
-                               break
-                       (a, b), (a1, b1), (a2, b2) = match
-                       topic, ref = text[a1:b1], text[a2:b2]
-                       if ref == ':':
-                               ref = topic
-                       menu.append((topic, ref))
-       #
-       # Get the footnotes
-       #
-       footnotes = []
-       b = 0
-       while 1:
-               match = findfootnote(text, b)
-               if not match:
-                       break
-               (a, b), (a1, b1), (a2, b2) = match
-               topic, ref = text[a1:b1], text[a2:b2]
-               if ref == ':':
-                       ref = topic
-               footnotes.append((topic, ref))
-       #
-       return node, (prev, next, up), menu, footnotes
-#
-def get_it(line, matcher):
-       match = matcher(line)
-       if not match:
-               return ''
-       else:
-               (a, b), (a1, b1) = match
-               return line[a1:b1]
-
-
-# Find a node in an open file.
-# The offset (from the tags table) is a hint about the node's position.
-# Pass zero if there is no tags table.
-# Raise NoSuchNode if the node isn't found.
-# NB: This seeks around in the file.
-#
-def find_node(f, offset, node):
-       node = string.lower(node) # Just to be sure
-       #
-       # Position a little before the given offset,
-       # so we may find the node even if it has moved around
-       # in the file a little.
-       #
-       offset = max(0, ((offset-FUZZ) / BLOCKSIZE) * BLOCKSIZE)
-       f.seek(offset)
-       #
-       # Loop, hunting for a matching node header.
-       #
-       while 1:
-               buf = f.read(CHUNKSIZE)
-               if not buf:
-                       break
-               i = 0
-               while 1:
-                       match = findheader(buf, i)
-                       if match:
-                               (a,b), (a1,b1) = match
-                               start = a1
-                               line = buf[a1:b1]
-                               i = b
-                               match = parseheader(line)
-                               if match:
-                                       (a,b), (a1,b1) = match
-                                       key = string.lower(line[a1:b1])
-                                       if key == node:
-                                               # Got it!  Now read the rest.
-                                               return read_node(f, buf[start:])
-                       elif findescape(buf, i):
-                               next = f.read(CHUNKSIZE)
-                               if not next:
-                                       break
-                               buf = buf + next
-                       else:
-                               break
-       #
-       # If we get here, we didn't find it.  Too bad.
-       #
-       raise NoSuchNode, node
-
-
-# Finish off getting a node (subroutine for find_node()).
-# The node begins at the start of buf and may end in buf;
-# if it doesn't end there, read additional data from f.
-#
-def read_node(f, buf):
-       i = 0
-       match = findescape(buf, i)
-       while not match:
-               next = f.read(CHUNKSIZE)
-               if not next:
-                       end = len(buf)
-                       break
-               i = len(buf)
-               buf = buf + next
-               match = findescape(buf, i)
-       else:
-               # Got a match
-               (a, b) = match[0]
-               end = a
-       # Strip trailing newlines
-       while end > 0 and buf[end-1] == '\n':
-               end = end-1
-       buf = buf[:end]
-       return buf
-
-
-# Read reverse starting at offset until the beginning of a node is found.
-# Then return a buffer containing the beginning of the node,
-# with f positioned just after the buffer.
-# The buffer will contain at least the full header line of the node;
-# the caller should finish off with read_node() if it is the right node.
-# (It is also possible that the buffer extends beyond the node!)
-# Return an empty string if there is no node before the given offset.
-#
-def backup_node(f, offset):
-       start = max(0, ((offset-CHUNKSIZE) / BLOCKSIZE) * BLOCKSIZE)
-       end = offset
-       while start < end:
-               f.seek(start)
-               buf = f.read(end-start)
-               i = 0
-               hit = -1
-               while 1:
-                       match = findheader(buf, i)
-                       if match:
-                               (a,b), (a1,b1) = match
-                               hit = a1
-                               i = b
-                       elif end < offset and findescape(buf, i):
-                               next = f.read(min(offset-end, BLOCKSIZE))
-                               if not next:
-                                       break
-                               buf = buf + next
-                               end = end + len(next)
-                       else:
-                               break
-               if hit >= 0:
-                       return buf[hit:]
-               end = start
-               start = max(0, end - CHUNKSIZE)
-       return ''
-
-
-# Make a tag table for the given file by scanning the file.
-# The file must be open for reading, and positioned at the beginning
-# (or wherever the hunt for tags must begin; it is read till the end).
-#
-def make_tags(f):
-       tags = {}
-       while 1:
-               offset = f.tell()
-               buf = f.read(CHUNKSIZE)
-               if not buf:
-                       break
-               i = 0
-               while 1:
-                       match = findheader(buf, i)
-                       if match:
-                               (a,b), (a1,b1) = match
-                               start = offset+a1
-                               line = buf[a1:b1]
-                               i = b
-                               match = parseheader(line)
-                               if match:
-                                       (a,b), (a1,b1) = match
-                                       key = string.lower(line[a1:b1])
-                                       if tags.has_key(key):
-                                               print 'Duplicate node:',
-                                               print key
-                                       tags[key] = '', start, line
-                       elif findescape(buf, i):
-                               next = f.read(CHUNKSIZE)
-                               if not next:
-                                       break
-                               buf = buf + next
-                       else:
-                               break
-       return tags
-
-
-# Try to open a file, return a file object if succeeds.
-# Raise NoSuchFile if the file can't be opened.
-# Should treat absolute pathnames special.
-#
-def try_open(file):
-       for dir in INFOPATH:
-               try:
-                       return open(dir + file, 'r')
-               except IOError:
-                       pass
-       raise NoSuchFile, file
-
-
-# A little test for the speed of make_tags().
-#
-TESTFILE = 'texinfo-1'
-def test_make_tags():
-       import time
-       f = try_open(TESTFILE)
-       t1 = time.millitimer()
-       tags = make_tags(f)
-       t2 = time.millitimer()
-       print 'Making tag table for', `TESTFILE`, 'took', t2-t1, 'msec.'
diff --git a/Demo/stdwin/ibrowse/itags.py b/Demo/stdwin/ibrowse/itags.py
deleted file mode 100755 (executable)
index 7cddcfa..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-# Utility module for 'icache.py': interpret tag tables and indirect nodes.
-
-# (This module is a bit chatty when confronted with the unexpected.)
-
-
-import regexp
-import string
-import ifile
-
-
-# Get the tag table of an open file, as a dictionary.
-# Seeks around in the file; after reading, the position is undefined.
-# Return an empty tag table if none is found.
-#
-def get_tags(f):
-       #
-       # First see if the last "node" is the end of tag table marker.
-       #
-       f.seek(0, 2) # Seek to EOF
-       end = f.tell()
-       buf = ifile.backup_node(f, end)
-       if not labelmatch(buf, 0, 'end tag table\n'):
-               return {} # No succes
-       #
-       # Next backup to the previous "node" -- the tag table itself.
-       #
-       ###print 'Getting prebuilt tag table...'
-       end = f.tell() - len(buf)
-       buf = ifile.backup_node(f, end)
-       label = 'tag table:\n'
-       if not labelmatch(buf, 0, label):
-               print 'Weird: end tag table marker but no tag table?'
-               print 'Node begins:', `buf[:50]`
-               return {}
-       #
-       # Now read the whole tag table.
-       #
-       end = f.tell() - len(buf) # Do this first!
-       buf = ifile.read_node(f, buf)
-       #
-       # First check for an indirection table.
-       #
-       indirlist = []
-       if labelmatch(buf, len(label), '(indirect)\n'):
-               indirbuf = ifile.backup_node(f, end)
-               if not labelmatch(indirbuf, 0, 'indirect:\n'):
-                       print 'Weird: promised indirection table not found'
-                       print 'Node begins:', `indirbuf[:50]`
-                       # Carry on.  Things probably won't work though.
-               else:
-                       indirbuf = ifile.read_node(f, indirbuf)
-                       indirlist = parse_indirlist(indirbuf)
-       #
-       # Now parse the tag table.
-       #
-       findtag = regexp.compile('^(.*[nN]ode:[ \t]*(.*))\177([0-9]+)$').match
-       i = 0
-       tags = {}
-       while 1:
-               match = findtag(buf, i)
-               if not match:
-                       break
-               (a,b), (a1,b1), (a2,b2), (a3,b3) = match
-               i = b
-               line = buf[a1:b1]
-               node = string.lower(buf[a2:b2])
-               offset = eval(buf[a3:b3]) # XXX What if it overflows?
-               if tags.has_key(node):
-                       print 'Duplicate key in tag table:', `node`
-               file, offset = map_offset(offset, indirlist)
-               tags[node] = file, offset, line
-       #
-       return tags
-
-
-# Return true if buf[i:] begins with a label, after lower case conversion.
-# The label argument must be in lower case.
-#
-def labelmatch(buf, i, label):
-       return string.lower(buf[i:i+len(label)]) == label
-
-
-# Parse the indirection list.
-# Return a list of (filename, offset) pairs ready for use.
-#
-def parse_indirlist(buf):
-       list = []
-       findindir = regexp.compile('^(.+):[ \t]*([0-9]+)$').match
-       i = 0
-       while 1:
-               match = findindir(buf, i)
-               if not match:
-                       break
-               (a,b), (a1,b1), (a2,b2) = match
-               file = buf[a1:b1]
-               offset = eval(buf[a2:b2]) # XXX What if this gets overflow?
-               list.append((file, offset))
-               i = b
-       return list
-
-
-# Map an offset through the indirection list.
-# Return (filename, new_offset).
-# If the list is empty, return the given offset and an empty file name.
-#
-def map_offset(offset, indirlist):
-       if not indirlist:
-               return '', offset
-       #
-       # XXX This could be done more elegant.
-       #
-       filex, offx = indirlist[0]
-       for i in range(len(indirlist)):
-               file1, off1 = indirlist[i]
-               if i+1 >= len(indirlist):
-                       file2, off2 = '', 0x7fffffff
-               else:
-                       file2, off2 = indirlist[i+1]
-               if off1 <= offset < off2:
-                       # Add offx+2 to compensate for extra header.
-                       # No idea whether this is always correct.
-                       return file1, offset-off1 + offx+2
-       #
-       # XXX Shouldn't get here.
-       #
-       print 'Oops, map_offset fell through'
-       return '', offset # Not likely to get good results
diff --git a/Demo/stdwin/jukebox.py b/Demo/stdwin/jukebox.py
deleted file mode 100755 (executable)
index e3c9db8..0000000
+++ /dev/null
@@ -1,413 +0,0 @@
-#! /usr/bin/env python
-
-# XXX This only works on SGIs running IRIX 4.0 or higher
-
-# JUKEBOX: browse directories full of sampled sound files.
-#
-# One or more "list windows" display the files and subdirectories of
-# the arguments.  Double-clicking on a subdirectory opens a new window
-# displaying its contents (and so on recursively).  Double clicking
-# on a file plays it as a sound file (assuming it is one).
-#
-# Playing is asynchronous: the application keeps listening for events
-# while the sample is playing, so you can cancel playing or start a
-# new sample right away.  Synchronous playing is available through the
-# -s option.
-#
-# The control window displays a "stop button" that cancel the current
-# play request.
-#
-# Most sound file formats recognized by SOX or SFPLAY are recognized.
-# Since conversion is costly, converted files are cached in
-# /usr/tmp/@j* until the user quits or changes the sampling rate via
-# the Rate menu.
-
-import commands
-import getopt
-import os
-from stat import *
-import rand
-import stdwin
-from stdwinevents import *
-import sys
-import tempfile
-import sndhdr
-
-from WindowParent import WindowParent
-from Buttons import PushButton
-
-# Pathnames
-
-DEF_DB = '/usr/local/sounds'           # Default directory of sounds
-SOX = '/usr/local/bin/sox'             # Sound format conversion program
-SFPLAY = '/usr/sbin/sfplay'            # Sound playing program
-
-
-# Global variables
-
-class struct: pass             # Class to define featureless structures
-
-G = struct()                   # Holds writable global variables
-
-
-# Main program
-
-def main():
-       G.synchronous = 0       # If set, use synchronous audio.write()
-       G.debug = 0             # If set, print debug messages
-       G.busy = 0              # Set while asynchronous playing is active
-       G.windows = []          # List of open windows, except control
-       G.mode = ''             # File type (default any that sfplay knows)
-       G.rate = 0              # Sampling rate (default " " " ")
-       G.tempprefix = tempfile.mktemp()
-       #
-       try:
-               optlist, args = getopt.getopt(sys.argv[1:], 'dr:st:')
-       except getopt.error, msg:
-               sys.stdout = sys.stderr
-               print msg
-               print 'usage: jukebox [-d] [-s] [-t type] [-r rate]'
-               print '  -d        debugging (-dd event debugging)'
-               print '  -s        synchronous playing'
-               print '  -t type   file type'
-               print '  -r rate   sampling rate'
-               sys.exit(2)
-       #
-       for optname, optarg in optlist:
-               if   optname == '-d':
-                       G.debug = G.debug + 1
-               elif optname == '-r':
-                       G.rate = int(eval(optarg))
-               elif optname == '-s':
-                       G.synchronous = 1
-               elif optname == '-t':
-                       G.mode = optarg
-       #
-       if G.debug:
-               for name in G.__dict__.keys():
-                       print 'G.' + name, '=', `G.__dict__[name]`
-       #
-       if not args:
-               args = [DEF_DB]
-       #
-       G.cw = opencontrolwindow()
-       for dirname in args:
-               G.windows.append(openlistwindow(dirname))
-       #
-       #
-       try:
-               maineventloop()
-       finally:
-               clearcache()
-               killchild()
-
-# Entries in Rate menu:
-rates = ['default', '7350', \
-       '8000', '11025', '16000', '22050', '32000', '41000', '48000']
-
-def maineventloop():
-       mouse_events = WE_MOUSE_DOWN, WE_MOUSE_MOVE, WE_MOUSE_UP
-       while G.windows:
-               try:
-                       type, w, detail = event = stdwin.getevent()
-               except KeyboardInterrupt:
-                       killchild()
-                       continue
-               if w == G.cw.win:
-                       if type == WE_CLOSE:
-                               return
-                       if type == WE_TIMER:
-                               checkchild()
-                               if G.busy:
-                                       G.cw.win.settimer(1)
-                       elif type == WE_MENU:
-                               menu, item = detail
-                               if menu is G.ratemenu:
-                                       clearcache()
-                                       if item == 0:
-                                               G.rate = 0
-                                       else:
-                                               G.rate = eval(rates[item])
-                                       for i in range(len(rates)):
-                                               menu.check(i, (i == item))
-                       else:
-                               G.cw.dispatch(event)
-               else:
-                       if type == WE_DRAW:
-                               w.drawproc(w, detail)
-                       elif type in mouse_events:
-                               w.mouse(w, type, detail)
-                       elif type == WE_CLOSE:
-                               w.close(w)
-                               del w, event
-                       else:
-                               if G.debug > 1: print type, w, detail
-
-def checkchild():
-       if G.busy:
-               waitchild(1)
-
-def killchild():
-       if G.busy:
-               os.kill(G.busy, 9)
-               waitchild(0)
-
-def waitchild(options):
-       pid, sts = os.waitpid(G.busy, options)
-       if pid == G.busy:
-               G.busy = 0
-               G.stop.enable(0)
-
-
-# Control window -- to set gain and cancel play operations in progress
-
-def opencontrolwindow():
-       stdwin.setdefscrollbars(0, 0)
-       cw = WindowParent().create('Jukebox', (0, 0))
-       #
-       stop = PushButton().definetext(cw, '        Stop        ')
-       stop.hook = stop_hook
-       stop.enable(0)
-       G.stop = stop
-       #
-       cw.realize()
-       #
-       G.ratemenu = cw.win.menucreate('Rate')
-       for r in rates:
-               G.ratemenu.additem(r)
-       if G.rate == 0:
-               G.ratemenu.check(0, 1)
-       else:
-               for i in len(range(rates)):
-                       if rates[i] == `G.rate`:
-                               G.ratemenu.check(i, 1)
-       #
-       return cw
-
-def stop_hook(self):
-       killchild()
-
-
-# List windows -- to display list of files and subdirectories
-
-def openlistwindow(dirname):
-       list = os.listdir(dirname)
-       list.sort()
-       i = 0
-       while i < len(list):
-               if list[i][0] == '.':
-                       del list[i]
-               else:
-                       i = i+1
-       for i in range(len(list)):
-               fullname = os.path.join(dirname, list[i])
-               if os.path.isdir(fullname):
-                       info = '/'
-               else:
-                       try:
-                               size = os.stat(fullname)[ST_SIZE]
-                               info = `(size + 1023)/1024` + 'k'
-                       except IOError:
-                               info = '???'
-                       info = '(' + info + ')'
-               list[i] = list[i], info
-       width = maxwidth(list)
-       # width = width + stdwin.textwidth(' ') # XXX X11 stdwin bug workaround
-       height = len(list) * stdwin.lineheight()
-       stdwin.setdefwinsize(width, min(height, 500))
-       stdwin.setdefscrollbars(0, 1)
-       w = stdwin.open(dirname)
-       stdwin.setdefwinsize(0, 0)
-       w.setdocsize(width, height)
-       w.drawproc = drawlistwindow
-       w.mouse = mouselistwindow
-       w.close = closelistwindow
-       w.dirname = dirname
-       w.list = list
-       w.selected = -1
-       return w
-
-def maxwidth(list):
-       width = 1
-       for name, info in list:
-               w = stdwin.textwidth(name + '  ' + info)
-               if w > width: width = w
-       return width
-
-def drawlistwindow(w, area):
-##     (left, top), (right, bottom) = area
-       d = w.begindrawing()
-       d.erase((0, 0), (1000, 10000))
-       lh = d.lineheight()
-       h, v = 0, 0
-       for name, info in w.list:
-               if info == '/':
-                       text = name + '/'
-               else:
-                       text = name + '  ' + info
-               d.text((h, v), text)
-               v = v + lh
-       showselection(w, d)
-       d.close()
-
-def hideselection(w, d):
-       if w.selected >= 0:
-               invertselection(w, d)
-
-def showselection(w, d):
-       if w.selected >= 0:
-               invertselection(w, d)
-
-def invertselection(w, d):
-       lh = d.lineheight()
-       h1, v1 = p1 = 0, w.selected*lh
-       h2, v2 = p2 = 1000, v1 + lh
-       d.invert(p1, p2)
-
-def mouselistwindow(w, type, detail):
-       (h, v), clicks, button = detail[:3]
-       d = w.begindrawing()
-       lh = d.lineheight()
-       if 0 <= v < lh*len(w.list):
-               i = v / lh
-       else:
-               i = -1
-       if w.selected <> i:
-               hideselection(w, d)
-               w.selected = i
-               showselection(w, d)
-       d.close()
-       if type == WE_MOUSE_DOWN and clicks >= 2 and i >= 0:
-               setcursors('watch')
-               name, info = w.list[i]
-               fullname = os.path.join(w.dirname, name)
-               if info == '/':
-                       if clicks == 2:
-                               G.windows.append(openlistwindow(fullname))
-               else:
-                       playfile(fullname)
-               setcursors('cross')
-
-def closelistwindow(w):
-       G.windows.remove(w)
-
-def setcursors(cursor):
-       for w in G.windows:
-               w.setwincursor(cursor)
-       G.cw.win.setwincursor(cursor)
-
-
-# Playing tools
-
-cache = {}
-
-def clearcache():
-       for x in cache.keys():
-               cmd = 'rm -f ' + cache[x]
-               if G.debug: print cmd
-               sts = os.system(cmd)
-               if sts:
-                       print cmd
-                       print 'Exit status', sts
-               del cache[x]
-
-validrates = (8000, 11025, 16000, 22050, 32000, 44100, 48000)
-
-def playfile(filename):
-       killchild()
-       try:
-               tuple = sndhdr.what(filename)
-       except IOError, msg:
-               print 'Can\'t open', filename, msg
-               stdwin.fleep()
-               return
-       raw = 0
-       if tuple:
-               mode, rate = tuple[:2]
-               if rate == 0:
-                       rate = G.rate
-                       if rate == 0:
-                               rate = 8000
-       else:
-               mode = G.mode
-               rate = G.rate
-       if G.debug: print 'mode =', mode, 'rate =', rate
-       if mode in ('au', 'aiff', 'wav', 'aifc', 'ul', 'ub', 'sb') and \
-                 rate in validrates:
-               tempname = filename
-               if mode in ('ul', 'ub', 'sb'):
-                       raw = 1
-       elif cache.has_key(filename):
-               tempname = cache[filename]
-       else:
-               tempname = G.tempprefix + `rand.rand()` + '.aiff'
-               cmd = SOX
-               if G.debug:
-                       cmd = cmd + ' -V'
-               if mode <> '':
-                       cmd = cmd + ' -t ' + mode
-               cmd = cmd + ' ' + commands.mkarg(filename)
-               cmd = cmd + ' -t aiff'
-               if rate not in validrates:
-                       rate = 32000
-               if rate:
-                       cmd = cmd + ' -r ' + `rate`
-               cmd = cmd + ' ' + tempname
-               if G.debug: print cmd
-               sts = os.system(cmd)
-               if sts:
-                       print cmd
-                       print 'Exit status', sts
-                       stdwin.fleep()
-                       try:
-                               os.unlink(tempname)
-                       except:
-                               pass
-                       return
-               cache[filename] = tempname
-       if raw:
-               pid = sfplayraw(tempname, tuple)
-       else:
-               pid = sfplay(tempname, [])
-       if G.synchronous:
-               sts = os.wait(pid, 0)
-       else:
-               G.busy = pid
-               G.stop.enable(1)
-               G.cw.win.settimer(1)
-
-def sfplayraw(filename, tuple):
-       args = ['-i']
-       type, rate, channels, frames, bits = tuple
-       if type == 'ul':
-               args.append('mulaw')
-       elif type == 'ub':
-               args = args + ['integer', '8', 'unsigned']
-       elif type == 'sb':
-               args = args + ['integer', '8', '2scomp']
-       else:
-               print 'sfplayraw: warning: unknown type in', tuple
-       if channels > 1:
-               args = args + ['channels', `channels`]
-       if not rate:
-               rate = G.rate
-       if rate:
-               args = args + ['rate', `rate`]
-       args.append('end')
-       return sfplay(filename, args)
-
-def sfplay(filename, args):
-       if G.debug:
-               args = ['-p'] + args
-       args = [SFPLAY, '-r'] + args + [filename]
-       if G.debug: print 'sfplay:', args
-       pid = os.fork()
-       if pid == 0:
-               # Child
-               os.execv(SFPLAY, args)
-               # NOTREACHED
-       else:
-               # Parent
-               return pid
-
-main()
diff --git a/Demo/stdwin/lpwin.py b/Demo/stdwin/lpwin.py
deleted file mode 100755 (executable)
index 519b428..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-#! /usr/bin/env python
-
-# Watch line printer queues (only works with BSD 4.3 lpq).
-#
-# This brings up a window containing one line per printer argument.
-#
-# Each line gives a small summary of the printer's status and queue.
-# The status tries to give as much relevant information as possible,
-# and gives extra info if you have jobs in the queue.
-#
-# The line's background color gives a hint at the status: navajo white
-# for idle, green if your job is now printing, yellow/orange for
-# small/large queue, red for errors.
-#
-# To reduce the duration of the unresponsive time while it is waiting
-# for an lpq subprocess to finish, it polls one printer every
-# delay/len(printers) seconds.  A tiny dot indicates the last printer
-# updated.  Hit the mouse button in the window to update the next one.
-#
-# To do:
-# - add an argument to override the default delay
-# - add arguments to override the default colors
-# - better heuristic for small/large queue (and more colors!)
-# - mouse clicks should update the printer clicked in
-# - better visual appearance, e.g., boxes around the lines?
-
-import posix
-import sys
-import time
-import string
-
-import stdwin
-from stdwinevents import *
-import mainloop
-
-# Default parameters
-DEF_PRINTER = 'oce' # This is CWI specific!
-DEF_DELAY = 10
-
-# Color assignments
-c_unknown = stdwin.fetchcolor('white')
-c_idle = stdwin.fetchcolor('navajo white')
-c_ontop = stdwin.fetchcolor('green')
-c_smallqueue = stdwin.fetchcolor('yellow')
-c_bigqueue = stdwin.fetchcolor('orange')
-c_error = stdwin.fetchcolor('red')
-
-def main():
-       delay = DEF_DELAY
-       #
-       try:
-               thisuser = posix.environ['LOGNAME']
-       except:
-               thisuser = posix.environ['USER']
-       #
-       printers = sys.argv[1:]
-       if printers:
-               # Strip '-P' from printer names just in case
-               # the user specified it...
-               for i in range(len(printers)):
-                       if printers[i][:2] == '-P':
-                               printers[i] = printers[i][2:]
-       else:
-               if posix.environ.has_key('PRINTER'):
-                       printers = [posix.environ['PRINTER']]
-               else:
-                       printers = [DEF_PRINTER]
-       #
-       width = stdwin.textwidth('in')*20
-       height = len(printers) * stdwin.lineheight() + 5
-       stdwin.setdefwinsize(width, height)
-       stdwin.setdefscrollbars(0, 0)
-       #
-       win = stdwin.open('lpwin')
-       #
-       win.printers = printers
-       win.colors = [c_unknown] * len(printers)
-       win.texts = printers[:]
-       win.next = 0
-       win.delay = DEF_DELAY
-       win.thisuser = thisuser
-       win.dispatch = lpdispatch
-       #
-       win.settimer(1)
-       #
-       mainloop.register(win)
-       mainloop.mainloop()
-
-def lpdispatch(event):
-       type, win, detail = event
-       if type == WE_CLOSE or type == WE_CHAR and detail in ('q', 'Q'):
-               mainloop.unregister(win)
-       elif type == WE_DRAW:
-               drawproc(win)
-       elif type == WE_TIMER:
-               update(win)
-               win.change((0,0), (10000, 10000))
-       elif type == WE_MOUSE_UP:
-               win.settimer(1)
-
-def drawproc(win):
-       d = win.begindrawing()
-       offset = d.textwidth('.')
-       h, v = 0, 0
-       for i in range(len(win.printers)):
-               text = win.texts[i]
-               color = win.colors[i]
-               d.setbgcolor(color)
-               d.erase((h, v), (h+10000, v+d.lineheight()))
-               if (i+1) % len(win.printers) == win.next and color <> c_unknown:
-                       d.text((h, v), '.')
-               d.text((h+offset, v), text)
-               v = v + d.lineheight()
-
-def update(win):
-       i = win.next
-       win.next = (i+1) % len(win.printers)
-       win.texts[i], win.colors[i] = makestatus(win.printers[i], win.thisuser)
-       win.settimer(int(win.delay * 10.0 / len(win.printers)))
-
-def makestatus(name, thisuser):
-       pipe = posix.popen('lpq -P' + name + ' 2>&1', 'r')
-       lines = []
-       users = {}
-       aheadbytes = 0
-       aheadjobs = 0
-       userseen = 0
-       totalbytes = 0
-       totaljobs = 0
-       color = c_unknown
-       while 1:
-               line = pipe.readline()
-               if not line: break
-               fields = string.split(line)
-               n = len(fields)
-               if len(fields) >= 6 and fields[n-1] == 'bytes':
-                       rank = fields[0]
-                       user = fields[1]
-                       job = fields[2]
-                       files = fields[3:-2]
-                       bytes = eval(fields[n-2])
-                       if user == thisuser:
-                               userseen = 1
-                               if aheadjobs == 0:
-                                       color = c_ontop
-                       elif not userseen:
-                               aheadbytes = aheadbytes + bytes
-                               aheadjobs = aheadjobs + 1
-                       totalbytes = totalbytes + bytes
-                       totaljobs = totaljobs + 1
-                       if color == c_unknown:
-                               color = c_smallqueue
-                       elif color == c_smallqueue:
-                               color = c_bigqueue
-                       if users.has_key(user):
-                               ujobs, ubytes = users[user]
-                       else:
-                               ujobs, ubytes = 0, 0
-                       ujobs = ujobs + 1
-                       ubytes = ubytes + bytes
-                       users[user] = ujobs, ubytes
-               else:
-                       if fields and fields[0] <> 'Rank':
-                               line = string.strip(line)
-                               if line == 'no entries':
-                                       line = name + ': idle'
-                                       if color == c_unknown:
-                                               color = c_idle
-                               elif line[-22:] == ' is ready and printing':
-                                       line = line[:-22]
-                               else:
-                                       line = name + ': ' + line
-                                       color = c_error
-                               lines.append(line)
-       #
-       if totaljobs:
-               line = `(totalbytes+1023)/1024` + ' K'
-               if totaljobs <> len(users):
-                       line = line + ' (' + `totaljobs` + ' jobs)'
-               if len(users) == 1:
-                       line = line + ' for ' + users.keys()[0]
-               else:
-                       line = line + ' for ' + `len(users)` + ' users'
-                       if userseen:
-                               if aheadjobs == 0:
-                                 line =  line + ' (' + thisuser + ' first)'
-                               else:
-                                 line = line + ' (' + `(aheadbytes+1023)/1024`
-                                 line = line + ' K before ' + thisuser + ')'
-               lines.append(line)
-       #
-       sts = pipe.close()
-       if sts:
-               lines.append('lpq exit status ' + `sts`)
-               color = c_error
-       return string.joinfields(lines, ': '), color
-
-main()
diff --git a/Demo/stdwin/microedit.py b/Demo/stdwin/microedit.py
deleted file mode 100755 (executable)
index 1091676..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-#! /usr/bin/env python
-
-# A minimal single-window text editor using STDWIN's text objects.
-#
-# Usage: microedit file
-#
-# This is not intended as a real application but as an introduction
-# to STDWIN programming in Python, especially text objects.
-# Once you understand microedit.py, study miniedit.py to learn
-# about multiple windows and menus, cut and paste, etc.
-
-
-import sys
-import stdwin
-from stdwinevents import *
-
-
-# Main program
-#
-def main():
-       #
-       # Get the filename argument and read its contents as one very
-       # large string.
-       # An exception will terminate the program if there is no argument
-       # or if the file could not be read...
-       #
-       filename = sys.argv[1]
-       fp = open(filename, 'r')
-       contents = fp.read()
-       del fp                          # Close the file
-       #
-       # Create the window, using the filename as window title
-       #
-       window = stdwin.open(filename)
-       #
-       # Add a simple File menu to the window with two items
-       #
-       filemenu = window.menucreate('File')
-       filemenu.additem('Save', 'S')   # Item 0 (shortcut Meta-S)
-       filemenu.additem('Save As...')  # Item 1
-       #
-       # Create a text object occupying the entire window
-       # and fill it with the file's contents
-       #
-       corner = window.getwinsize()    # (width, height)
-       area = (0, 0), corner           # Rectangle as large as the window
-       text = window.textcreate(area)
-       text.settext(contents)
-       del contents                    # Get rid of contents object
-       fix_textsize(window, text)      # Set document size accordingly
-       #
-       # Main event loop -- stop if a close request comes in.
-       #
-       # STDWIN applications should regularly call stdwin.getevent()
-       # otherwise the windows won't function as expected.
-       #
-       while 1:
-               #
-               # Get the next event
-               #
-               type, w, detail = e = stdwin.getevent()
-               #
-               # Event decoding switch
-               #
-               if type == WE_CLOSE:
-                       break           # Stop (no check for saved file!)
-               elif type == WE_SIZE:
-                       #
-                       # The window was resized --
-                       # let the text object recompute the line breaks
-                       # and change the document size accordingly,
-                       # so scroll bars will work
-                       #
-                       fix_textsize(window, text)
-               elif type == WE_MENU:
-                       #
-                       # Execute a file menu request (our only menu)
-                       #
-                       menu, item = detail
-                       if item == 0:
-                               #
-                               # "Save": save to the current filename
-                               #
-                               dummy = save_file(window, text, filename)
-                       elif item == 1:
-                               #
-                               # "Save As": ask a new filename, save to it,
-                               # and make it the current filename
-                               #
-                               # NB: askfile raises KeyboardInterrupt
-                               # if the user cancels the dialog, hence
-                               # the try statement
-                               #
-                               try:
-                                       newfile = stdwin.askfile( \
-                                               'Save as:', filename, 1)
-                               except KeyboardInterrupt:
-                                       newfile = ''
-                               if newfile:
-                                       if save_file(window, text, newfile):
-                                               filename = newfile
-                                               window.settitle(filename)
-               elif text.event(e):
-                       #
-                       # The text object has handled the event.
-                       # Fix the document size if necessary.
-                       # Note: this sometimes fixes the size
-                       # unnecessarily, e.g., for arrow keys.
-                       #
-                       if type in (WE_CHAR, WE_COMMAND):
-                               fix_docsize(window, text)
-
-
-# Save the window's contents to the filename.
-# If the open() fails, put up a warning message and return 0;
-# if the save succeeds, return 1.
-#
-def save_file(window, text, filename):
-       #
-       # Open the file for writing, handling exceptions
-       #
-       try:
-               fp = open(filename, 'w')
-       except RuntimeError:
-               stdwin.message('Cannot create ' + filename)
-               return 0
-       #
-       # Get the contents of the text object as one very long string
-       #
-       contents = text.gettext()
-       #
-       # Write the contents to the file
-       #
-       fp.write(contents)
-       #
-       # The file is automatically closed when this routine returns
-       #
-       return 1
-
-
-# Change the size of the text object to fit in the window,
-# and then fix the window's document size to fit around the text object.
-#
-def fix_textsize(window, text):
-       #
-       # Compute a rectangle as large as the window
-       #
-       corner = window.getwinsize()    # (width, height)
-       area = (0, 0), (corner)
-       #
-       # Move the text object to this rectangle.
-       # Note: text.move() ignores the bottom coordinate!
-       #
-       text.move(area)
-       #
-       # Now fix the document size accordingly
-       #
-       fix_docsize(window, text)
-
-
-# Fix the document size, after the text has changed
-#
-def fix_docsize(window, text):
-       #
-       # Get the actual rectangle occupied by the text object.
-       # This has the same left, top and right, but a different bottom.
-       #
-       area = text.getrect()
-       #
-       # Compute the true height of the text object
-       #
-       origin, corner = area
-       width, height = corner
-       #
-       # Set the document height to the text object's height.
-       # The width is zero since we don't want a horizontal scroll bar.
-       #
-       window.setdocsize(0, height)
-
-
-# Once all functions are defined, call main()
-#
-main()
diff --git a/Demo/stdwin/miniedit.py b/Demo/stdwin/miniedit.py
deleted file mode 100755 (executable)
index 9a11c2d..0000000
+++ /dev/null
@@ -1,356 +0,0 @@
-#! /usr/bin/env python
-
-# A miniature multi-window editor using STDWIN's text objects.
-#
-# Usage: miniedit [file] ...
-#
-# The user interface is similar to that of the miniedit demo application
-# in C that comes with STDWIN.
-#
-# XXX need to comment the functions
-# XXX Not yet implemented:
-#      disabling menu entries for inapplicable actions
-#      Find operations
-
-
-import sys
-import stdwin
-from stdwinevents import *
-
-
-# Constant: list of WE_COMMAND events that (may) change the text buffer
-# so we can decide whether to set the 'changed' flag.
-# Note that it is possible for such a command to fail (a backspace
-# at the beginning of the buffer) but we'll set the changed flag anyway
-# -- it's too complicated to check this condition right now.
-#
-changing = [WC_RETURN, WC_TAB, WC_BACKSPACE]
-
-
-# The list of currently open windows;
-# this is maintained so we can stop when there are no windows left
-#
-windows = []
-
-
-# A note on window data attributes (set by open_window):
-#
-# w.textobject the window's text object
-# w.changed    true when the window's text is changed
-# w.filename   filename connected to the window; '' if none
-
-
-# Main program
-#
-def main():
-       #
-       # Set a reasonable default window size.
-       # If we are using a fixed-width font this will open a 80x24 window;
-       # for variable-width fonts we approximate this based on an average
-       #
-       stdwin.setdefwinsize(40*stdwin.textwidth('in'), 24*stdwin.lineheight())
-       #
-       # Create global menus (as local variables)
-       #
-       filemenu = make_file_menu(stdwin)
-       editmenu = make_edit_menu(stdwin)
-       findmenu = make_find_menu(stdwin)
-       #
-       # Get the list of files from the command line (maybe none)
-       #
-       files = sys.argv[1:]
-       #
-       # Open any files -- errors will be reported but do won't stop us
-       #
-       for filename in files:
-               open_file(filename)
-       #
-       # If there were no files, or none of them could be opened,
-       # put up a dialog asking for a filename
-       #
-       if not windows:
-               try:
-                       open_dialog(None)
-               except KeyboardInterrupt:
-                       pass            # User cancelled
-       #
-       # If the dialog was cancelled, create an empty new window
-       #
-       if not windows:
-               new_window(None)
-       #
-       # Main event loop -- stop when we have no open windows left
-       #
-       while windows:
-               #
-               # Get the next event -- ignore interrupts
-               #
-               try:
-                       type, window, detail = event = stdwin.getevent()
-               except KeyboardInterrupt:
-                       type, window, detail = event = WE_NONE, None, None
-               #
-               # Event decoding switch
-               #
-               if not window:
-                       pass            # Ignore such events
-               elif type == WE_MENU:
-                       #
-                       # Execute menu operation
-                       #
-                       menu, item = detail
-                       try:
-                               menu.actions[item](window)
-                       except KeyboardInterrupt:
-                               pass    # User cancelled
-               elif type == WE_CLOSE:
-                       #
-                       # Close a window
-                       #
-                       try:
-                               close_dialog(window)
-                       except KeyboardInterrupt:
-                               pass    # User cancelled
-               elif type == WE_SIZE:
-                       #
-                       # A window was resized --
-                       # let the text object recompute the line breaks
-                       # and change the document size accordingly,
-                       # so scroll bars will work
-                       #
-                       fix_textsize(window)
-               elif window.textobject.event(event):
-                       #
-                       # The event was eaten by the text object --
-                       # set the changed flag if not already set
-                       #
-                       if type == WE_CHAR or \
-                          type == WE_COMMAND and detail in changing:
-                               window.changed = 1
-                               fix_docsize(window)
-               #
-               # Delete all objects that may still reference the window
-               # in the event -- this is needed otherwise the window
-               # won't actually be closed and may receive further
-               # events, which will confuse the event decoder
-               #
-               del type, window, detail, event
-
-
-def make_file_menu(object):
-       menu = object.menucreate('File')
-       menu.actions = []
-       additem(menu, 'New',            'N', new_window)
-       additem(menu, 'Open..',         'O', open_dialog)
-       additem(menu, '',               '',  None)
-       additem(menu, 'Save',           'S', save_dialog)
-       additem(menu, 'Save As..',      '',  save_as_dialog)
-       additem(menu, 'Save a Copy..',  '',  save_copy_dialog)
-       additem(menu, 'Revert',         'R', revert_dialog)
-       additem(menu, 'Quit',           'Q', quit_dialog)
-       return menu
-
-
-def make_edit_menu(object):
-       menu = object.menucreate('Edit')
-       menu.actions = []
-       additem(menu, 'Cut',            'X', do_cut)
-       additem(menu, 'Copy',           'C', do_copy)
-       additem(menu, 'Paste',          'V', do_paste)
-       additem(menu, 'Clear',          'B', do_clear)
-       additem(menu, 'Select All',     'A', do_select_all)
-       return menu
-
-
-def make_find_menu(object):
-       menu = object.menucreate('Find')
-       menu.actions = []
-       # XXX
-       return menu
-
-
-def additem(menu, text, shortcut, function):
-       if shortcut:
-               menu.additem(text, shortcut)
-       else:
-               menu.additem(text)
-       menu.actions.append(function)
-
-
-def open_dialog(current_ignored):
-       filename = stdwin.askfile('Open file:', '', 0)
-       open_file(filename)
-
-
-def open_file(filename):
-       try:
-               fp = open(filename, 'r')
-       except RuntimeError:
-               stdwin.message(filename + ': cannot open')
-               return                  # Error, forget it
-       try:
-               contents = fp.read()
-       except RuntimeError:
-               stdwin.message(filename + ': read error')
-               return                  # Error, forget it
-       del fp                          # Close the file
-       open_window(filename, filename, contents)
-
-
-def new_window(current_ignored):
-       open_window('', 'Untitled', '')
-
-
-def open_window(filename, title, contents):
-       try:
-               window = stdwin.open(title)
-       except RuntimeError:
-               stdwin.message('cannot open new window')
-               return                  # Error, forget it
-       window.textobject = window.textcreate((0, 0), window.getwinsize())
-       window.textobject.settext(contents)
-       window.changed = 0
-       window.filename = filename
-       fix_textsize(window)
-       windows.append(window)
-
-
-def quit_dialog(window):
-       for window in windows[:]:
-               close_dialog(window)
-
-
-def close_dialog(window):
-       if window.changed:
-               prompt = 'Save changes to ' + window.gettitle() + ' ?'
-               if stdwin.askync(prompt, 1):
-                       save_dialog(window)
-                       if window.changed:
-                               return  # Save failed (not) cancelled
-       windows.remove(window)
-       del window.textobject
-
-
-def save_dialog(window):
-       if not window.filename:
-               save_as_dialog(window)
-               return
-       if save_file(window, window.filename):
-               window.changed = 0
-
-
-def save_as_dialog(window):
-       prompt = 'Save ' + window.gettitle() + ' as:'
-       filename = stdwin.askfile(prompt, window.filename, 1)
-       if save_file(window, filename):
-               window.filename = filename
-               window.settitle(filename)
-               window.changed = 0
-
-
-def save_copy_dialog(window):
-       prompt = 'Save a copy of ' + window.gettitle() + ' as:'
-       filename = stdwin.askfile(prompt, window.filename, 1)
-       void = save_file(window, filename)
-
-
-def save_file(window, filename):
-       try:
-               fp = open(filename, 'w')
-       except RuntimeError:
-               stdwin.message(filename + ': cannot create')
-               return 0
-       contents = window.textobject.gettext()
-       try:
-               fp.write(contents)
-       except RuntimeError:
-               stdwin.message(filename + ': write error')
-               return 0
-       return 1
-
-
-def revert_dialog(window):
-       if not window.filename:
-               stdwin.message('This window has no file to revert from')
-               return
-       if window.changed:
-               prompt = 'Really read ' + window.filename + ' back from file?'
-               if not stdwin.askync(prompt, 1):
-                       return
-       try:
-               fp = open(window.filename, 'r')
-       except RuntimeError:
-               stdwin.message(filename + ': cannot open')
-               return
-       contents = fp.read()
-       del fp                          # Close the file
-       window.textobject.settext(contents)
-       window.changed = 0
-       fix_docsize(window)
-
-
-def fix_textsize(window):
-       corner = window.getwinsize()
-       area = (0, 0), (corner)
-       window.textobject.move(area)
-       fix_docsize(window)
-
-
-def fix_docsize(window):
-       area = window.textobject.getrect()
-       origin, corner = area
-       width, height = corner
-       window.setdocsize(0, height)
-
-
-def do_cut(window):
-       selection = window.textobject.getfocustext()
-       if not selection:
-               stdwin.fleep()          # Nothing to cut
-       elif not window.setselection(WS_PRIMARY, selection):
-               stdwin.fleep()          # Window manager glitch...
-       else:
-               stdwin.rotatecutbuffers(1)
-               stdwin.setcutbuffer(0, selection)
-               window.textobject.replace('')
-               window.changed = 1
-               fix_docsize(window)
-
-
-def do_copy(window):
-       selection = window.textobject.getfocustext()
-       if not selection:
-               stdwin.fleep()          # Nothing to cut
-       elif not window.setselection(WS_PRIMARY, selection):
-               stdwin.fleep()          # Window manager glitch...
-       else:
-               stdwin.rotatecutbuffers(1)
-               stdwin.setcutbuffer(0, selection)
-
-
-def do_paste(window):
-       selection = stdwin.getselection(WS_PRIMARY)
-       if not selection:
-               selection = stdwin.getcutbuffer(0)
-       if not selection:
-               stdwin.fleep()          # Nothing to paste
-       else:
-               window.textobject.replace(selection)
-               window.changed = 1
-               fix_docsize(window)
-
-def do_clear(window):
-       first, last = window.textobject.getfocus()
-       if first == last:
-               stdwin.fleep()          # Nothing to clear
-       else:
-               window.textobject.replace('')
-               window.changed = 1
-               fix_docsize(window)
-
-
-def do_select_all(window):
-       window.textobject.setfocus(0, 0x7fffffff) # XXX Smaller on the Mac!
-
-
-main()
diff --git a/Demo/stdwin/python.py b/Demo/stdwin/python.py
deleted file mode 100755 (executable)
index 8a3dfce..0000000
+++ /dev/null
@@ -1,449 +0,0 @@
-#! /usr/bin/env python
-
-# A STDWIN-based front end for the Python interpreter.
-#
-# This is useful if you want to avoid console I/O and instead
-# use text windows to issue commands to the interpreter.
-#
-# It supports multiple interpreter windows, each with its own context.
-#
-# BUGS AND CAVEATS:
-#
-# This was written long ago as a demonstration, and slightly hacked to
-# keep it up-to-date, but never as an industry-strength alternative
-# interface to Python.  It should be rewritten using more classes, and
-# merged with something like wdb.
-#
-# Although this supports multiple windows, the whole application
-# is deaf and dumb when a command is running in one window.
-#
-# Interrupt is (ab)used to signal EOF on input requests.
-#
-# On UNIX (using X11), interrupts typed in the window will not be
-# seen until the next input or output operation.  When you are stuck
-# in an infinite loop, try typing ^C in the shell window where you
-# started this interpreter.  (On the Mac, interrupts work normally.)
-
-
-import sys
-import stdwin
-from stdwinevents import *
-import rand
-import mainloop
-import os
-
-
-# Stack of windows waiting for [raw_]input().
-# Element [0] is the top.
-# If there are multiple windows waiting for input, only the
-# one on top of the stack can accept input, because the way
-# raw_input() is implemented (using recursive mainloop() calls).
-#
-inputwindows = []
-
-
-# Exception raised when input is available
-#
-InputAvailable = 'input available for raw_input (not an error)'
-
-
-# Main program -- create the window and call the mainloop
-#
-def main():
-       # Hack so 'import python' won't load another copy
-       # of this if we were loaded though 'python python.py'.
-       # (Should really look at sys.argv[0]...)
-       if 'inputwindows' in dir(sys.modules['__main__']) and \
-                       sys.modules['__main__'].inputwindows is inputwindows:
-               sys.modules['python'] = sys.modules['__main__']
-       #
-       win = makewindow()
-       mainloop.mainloop()
-
-
-# Create a new window
-#
-def makewindow():
-       # stdwin.setdefscrollbars(0, 1) # Not in Python 0.9.1
-       # stdwin.setfont('monaco') # Not on UNIX! and not Python 0.9.1
-       # width, height = stdwin.textwidth('in')*40, stdwin.lineheight()*24
-       # stdwin.setdefwinsize(width, height)
-       win = stdwin.open('Python interpreter ready')
-       win.editor = win.textcreate((0,0), win.getwinsize())
-       win.globals = {}                # Dictionary for user's globals
-       win.command = ''                # Partially read command
-       win.busy = 0                    # Ready to accept a command
-       win.auto = 1                    # [CR] executes command
-       win.insertOutput = 1            # Insert output at focus
-       win.insertError = 1             # Insert error output at focus
-       win.setwincursor('ibeam')
-       win.filename = ''               # Empty if no file for this window
-       makefilemenu(win)
-       makeeditmenu(win)
-       win.dispatch = pdispatch        # Event dispatch function
-       mainloop.register(win)
-       return win
-
-
-# Make a 'File' menu
-#
-def makefilemenu(win):
-       win.filemenu = mp = win.menucreate('File')
-       mp.callback = []
-       additem(mp, 'New', 'N', do_new)
-       additem(mp, 'Open...', 'O', do_open)
-       additem(mp, '', '',  None)
-       additem(mp, 'Close', 'W', do_close)
-       additem(mp, 'Save', 'S', do_save)
-       additem(mp, 'Save as...', '', do_saveas)
-       additem(mp, '', '', None)
-       additem(mp, 'Quit', 'Q', do_quit)
-
-
-# Make an 'Edit' menu
-#
-def makeeditmenu(win):
-       win.editmenu = mp = win.menucreate('Edit')
-       mp.callback = []
-       additem(mp, 'Cut', 'X', do_cut)
-       additem(mp, 'Copy', 'C', do_copy)
-       additem(mp, 'Paste', 'V', do_paste)
-       additem(mp, 'Clear', '',  do_clear)
-       additem(mp, '', '', None)
-       win.iauto = len(mp.callback)
-       additem(mp, 'Autoexecute', '', do_auto)
-       mp.check(win.iauto, win.auto)
-       win.insertOutputNum = len(mp.callback)
-       additem(mp, 'Insert Output', '', do_insertOutputOption)
-       win.insertErrorNum = len(mp.callback)
-       additem(mp, 'Insert Error', '', do_insertErrorOption)
-       additem(mp, 'Exec', '\r', do_exec)
-
-
-# Helper to add a menu item and callback function
-#
-def additem(mp, text, shortcut, handler):
-       if shortcut:
-               mp.additem(text, shortcut)
-       else:
-               mp.additem(text)
-       mp.callback.append(handler)
-
-
-# Dispatch a single event to the interpreter.
-# Resize events cause a resize of the editor.
-# Some events are treated specially.
-# Most other events are passed directly to the editor.
-#
-def pdispatch(event):
-       type, win, detail = event
-       if not win:
-               win = stdwin.getactive()
-               if not win: return
-       if type == WE_CLOSE:
-               do_close(win)
-               return
-       elif type == WE_SIZE:
-               win.editor.move((0, 0), win.getwinsize())
-       elif type == WE_COMMAND and detail == WC_RETURN:
-               if win.auto:
-                       do_exec(win)
-               else:
-                       void = win.editor.event(event)
-       elif type == WE_COMMAND and detail == WC_CANCEL:
-               if win.busy:
-                       raise KeyboardInterrupt
-               else:
-                       win.command = ''
-                       settitle(win)
-       elif type == WE_MENU:
-               mp, item = detail
-               mp.callback[item](win)
-       else:
-               void = win.editor.event(event)
-       if win in mainloop.windows:
-               # May have been deleted by close...
-               win.setdocsize(0, win.editor.getrect()[1][1])
-               if type in (WE_CHAR, WE_COMMAND):
-                       win.editor.setfocus(win.editor.getfocus())
-
-
-# Helper to set the title of the window
-#
-def settitle(win):
-       if win.filename == '':
-               win.settitle('Python interpreter ready')
-       else:
-               win.settitle(win.filename)
-
-
-# Helper to replace the text of the focus
-#
-def replace(win, text):
-       win.editor.replace(text)
-       # Resize the window to display the text
-       win.setdocsize(0, win.editor.getrect()[1][1]) # update the size before
-       win.editor.setfocus(win.editor.getfocus()) # move focus to the change
-
-
-# File menu handlers
-#
-def do_new(win):
-       win = makewindow()
-#
-def do_open(win):
-       try:
-               filename = stdwin.askfile('Open file', '', 0)
-               win = makewindow()
-               win.filename = filename
-               win.editor.replace(open(filename, 'r').read())
-               win.editor.setfocus(0, 0)
-               win.settitle(win.filename)
-               #
-       except KeyboardInterrupt:
-               pass                    # Don't give an error on cancel
-#
-def do_save(win):
-       try:
-               if win.filename == '':
-                       win.filename = stdwin.askfile('Open file', '', 1)
-               f = open(win.filename, 'w')
-               f.write(win.editor.gettext())
-               #
-       except KeyboardInterrupt:
-               pass                    # Don't give an error on cancel
-       
-def do_saveas(win):
-       currentFilename = win.filename
-       win.filename = ''
-       do_save(win)            # Use do_save with empty filename
-       if win.filename == '':  # Restore the name if do_save did not set it
-               win.filename = currentFilename
-#
-def do_close(win):
-       if win.busy:
-               stdwin.message('Can\'t close busy window')
-               return          # need to fail if quitting??
-       win.editor = None # Break circular reference
-       #del win.editmenu       # What about the filemenu??
-       mainloop.unregister(win)
-       win.close()
-#
-def do_quit(win):
-       # Call win.dispatch instead of do_close because there
-       # may be 'alien' windows in the list.
-       for win in mainloop.windows[:]:
-               mainloop.dispatch((WE_CLOSE, win, None))
-               # need to catch failed close
-
-
-# Edit menu handlers
-#
-def do_cut(win):
-       text = win.editor.getfocustext()
-       if not text:
-               stdwin.fleep()
-               return
-       stdwin.setcutbuffer(0, text)
-       replace(win, '')
-#
-def do_copy(win):
-       text = win.editor.getfocustext()
-       if not text:
-               stdwin.fleep()
-               return
-       stdwin.setcutbuffer(0, text)
-#
-def do_paste(win):
-       text = stdwin.getcutbuffer(0)
-       if not text:
-               stdwin.fleep()
-               return
-       replace(win, text)
-#
-def do_clear(win):
-       replace(win, '')
-
-
-# These would be better in a preferences dialog:
-#
-def do_auto(win):
-       win.auto = (not win.auto)
-       win.editmenu.check(win.iauto, win.auto)
-#
-def do_insertOutputOption(win):
-       win.insertOutput = (not win.insertOutput)
-       title = ['Append Output', 'Insert Output'][win.insertOutput]
-       win.editmenu.setitem(win.insertOutputNum, title)
-#
-def do_insertErrorOption(win):
-       win.insertError = (not win.insertError)
-       title = ['Error Dialog', 'Insert Error'][win.insertError]
-       win.editmenu.setitem(win.insertErrorNum, title)
-
-
-# Extract a command from the editor and execute it, or pass input to
-# an interpreter waiting for it.
-# Incomplete commands are merely placed in the window's command buffer.
-# All exceptions occurring during the execution are caught and reported.
-# (Tracebacks are currently not possible, as the interpreter does not
-# save the traceback pointer until it reaches its outermost level.)
-#
-def do_exec(win):
-       if win.busy:
-               if win not in inputwindows:
-                       stdwin.message('Can\'t run recursive commands')
-                       return
-               if win <> inputwindows[0]:
-                       stdwin.message('Please complete recursive input first')
-                       return
-       #
-       # Set text to the string to execute.
-       a, b = win.editor.getfocus()
-       alltext = win.editor.gettext()
-       n = len(alltext)
-       if a == b:
-               # There is no selected text, just an insert point;
-               # so execute the current line.
-               while 0 < a and alltext[a-1] <> '\n': # Find beginning of line
-                       a = a-1
-               while b < n and alltext[b] <> '\n': # Find end of line after b
-                       b = b+1
-               text = alltext[a:b] + '\n'
-       else:
-               # Execute exactly the selected text.
-               text = win.editor.getfocustext()
-               if text[-1:] <> '\n': # Make sure text ends with \n
-                       text = text + '\n'
-               while b < n and alltext[b] <> '\n': # Find end of line after b
-                       b = b+1
-       #
-       # Set the focus to expect the output, since there is always something.
-       # Output will be inserted at end of line after current focus,
-       # or appended to the end of the text.
-       b = [n, b][win.insertOutput]
-       win.editor.setfocus(b, b)
-       #
-       # Make sure there is a preceeding newline.
-       if alltext[b-1:b] <> '\n':
-               win.editor.replace('\n')
-       #
-       #
-       if win.busy:
-               # Send it to raw_input() below
-               raise InputAvailable, text
-       #
-       # Like the real Python interpreter, we want to execute
-       # single-line commands immediately, but save multi-line
-       # commands until they are terminated by a blank line.
-       # Unlike the real Python interpreter, we don't do any syntax
-       # checking while saving up parts of a multi-line command.
-       #
-       # The current heuristic to determine whether a command is
-       # the first line of a multi-line command simply checks whether
-       # the command ends in a colon (followed by a newline).
-       # This is not very robust (comments and continuations will
-       # confuse it), but it is usable, and simple to implement.
-       # (It even has the advantage that single-line loops etc.
-       # don't need te be terminated by a blank line.)
-       #
-       if win.command:
-               # Already continuing
-               win.command = win.command + text
-               if win.command[-2:] <> '\n\n':
-                       win.settitle('Unfinished command...')
-                       return # Need more...
-       else:
-               # New command
-               win.command = text
-               if text[-2:] == ':\n':
-                       win.settitle('Unfinished command...')
-                       return
-       command = win.command
-       win.command = ''
-       win.settitle('Executing command...')
-       #
-       # Some hacks:
-       # - The standard files are replaced by an IOWindow instance.
-       # - A 2nd argument to exec() is used to specify the directory
-       #   holding the user's global variables.  (If this wasn't done,
-       #   the exec would be executed in the current local environment,
-       #   and the user's assignments to globals would be lost...)
-       #
-       save_stdin = sys.stdin
-       save_stdout = sys.stdout
-       save_stderr = sys.stderr
-       try:
-               sys.stdin = sys.stdout = sys.stderr = IOWindow(win)
-               win.busy = 1
-               try:
-                       exec(command, win.globals)
-               except KeyboardInterrupt:
-                       print '[Interrupt]'
-               except:
-                       if type(sys.exc_type) == type(''):
-                               msg = sys.exc_type
-                       else: msg = sys.exc_type.__name__
-                       if sys.exc_value <> None:
-                               msg = msg + ': ' + `sys.exc_value`
-                       if win.insertError:
-                               stdwin.fleep()
-                               replace(win, msg + '\n')
-                       else:
-                               win.settitle('Unhandled exception')
-                               stdwin.message(msg)
-       finally:
-               # Restore redirected I/O in *all* cases
-               win.busy = 0
-               sys.stderr = save_stderr
-               sys.stdout = save_stdout
-               sys.stdin = save_stdin
-               settitle(win)
-
-
-# Class emulating file I/O from/to a window
-#
-class IOWindow:
-       #
-       def __init__(self, win):
-               self.win = win
-       #
-       def readline(self, *unused_args):
-               n = len(inputwindows)
-               save_title = self.win.gettitle()
-               title = n*'(' + 'Requesting input...' + ')'*n
-               self.win.settitle(title)
-               inputwindows.insert(0, self.win)
-               try:
-                       try:
-                               mainloop.mainloop()
-                       finally:
-                               del inputwindows[0]
-                               self.win.settitle(save_title)
-               except InputAvailable, val: # See do_exec above
-                       return val
-               except KeyboardInterrupt:
-                       raise EOFError # Until we have a "send EOF" key
-               # If we didn't catch InputAvailable, something's wrong...
-               raise EOFError
-       #
-       def write(self, text):
-               mainloop.check()
-               replace(self.win, text)
-               mainloop.check()
-
-
-# Currently unused function to test a command's syntax without executing it
-#
-def testsyntax(s):
-       import string
-       lines = string.splitfields(s, '\n')
-       for i in range(len(lines)): lines[i] = '\t' + lines[i]
-       lines.insert(0, 'if 0:')
-       lines.append('')
-       exec(string.joinfields(lines, '\n'))
-
-
-# Call the main program
-#
-main()
diff --git a/Demo/stdwin/wdiff.py b/Demo/stdwin/wdiff.py
deleted file mode 100755 (executable)
index 50ca032..0000000
+++ /dev/null
@@ -1,484 +0,0 @@
-#! /usr/bin/env python
-
-# A window-oriented recursive diff utility.
-# NB: This uses undocumented window classing modules.
-
-# TO DO:
-#      - faster update after moving/copying one file
-#      - diff flags (-b, etc.) should be global or maintained per window
-#      - use a few fixed windows instead of creating new ones all the time
-#      - ways to specify patterns to skip
-#        (best by pointing at a file and clicking a special menu entry!)
-#      - add rcsdiff menu commands
-#      - add a way to view status of selected files without opening them
-#      - add a way to diff two files with different names
-#      - add a way to rename files
-#      - keep backups of overwritten/deleted files
-#      - a way to mark specified files as uninteresting for dircmp
-
-import sys
-import os
-import rand
-import commands
-import dircache
-import statcache
-import cmp
-import cmpcache
-import stdwin
-import gwin
-import textwin
-import filewin
-import tablewin
-import anywin
-
-mkarg = commands.mkarg
-mk2arg = commands.mk2arg
-
-# List of names to ignore in dircmp()
-#
-skiplist = ['RCS', 'CVS', '.Amake', 'tags', 'TAGS', '.', '..']
-
-# Function to determine whether a name should be ignored in dircmp().
-#
-def skipthis(file):
-       return file[-1:] == '~' or file in skiplist
-
-
-def anydiff(a, b, flags): # Display differences between any two objects
-       print 'diff', flags, a, b
-       if os.path.isdir(a) and os.path.isdir(b):
-               w = dirdiff(a, b, flags)
-       else:
-               w = filediff(a, b, flags)
-       addstatmenu(w, [a, b])
-       w.original_close = w.close
-       w.close = close_dirwin
-       return w
-
-def close_dirwin(w):
-       close_subwindows(w, (), 0)
-       w.original_close(w)
-
-def filediff(a, b, flags): # Display differences between two text files
-       diffcmd = 'diff'
-       if flags: diffcmd = diffcmd + mkarg(flags)
-       diffcmd = diffcmd + mkarg(a) + mkarg(b)
-       difftext = commands.getoutput(diffcmd)
-       return textwin.open_readonly(mktitle(a, b), difftext)
-
-def dirdiff(a, b, flags): # Display differences between two directories
-       data = diffdata(a, b, flags)
-       w = tablewin.open(mktitle(a, b), data)
-       w.flags = flags
-       w.a = a
-       w.b = b
-       addviewmenu(w)
-       addactionmenu(w)
-       return w
-
-def diffdata(a, b, flags): # Compute directory differences.
-       #
-       a_only = [('A only:', header_action), ('', header_action)]
-       b_only = [('B only:', header_action), ('', header_action)]
-       ab_diff = [('A <> B:', header_action), ('', header_action)]
-       ab_same = [('A == B:', header_action), ('', header_action)]
-       data = [a_only, b_only, ab_diff, ab_same]
-       #
-       a_list = dircache.listdir(a)[:]
-       b_list = dircache.listdir(b)[:]
-       dircache.annotate(a, a_list)
-       dircache.annotate(b, b_list)
-       a_list.sort()
-       b_list.sort()
-       #
-       for x in a_list:
-               if x in ['./', '../']:
-                       pass
-               elif x not in b_list:
-                       a_only.append((x, a_only_action))
-               else:
-                       ax = os.path.join(a, x)
-                       bx = os.path.join(b, x)
-                       if os.path.isdir(ax) and os.path.isdir(bx):
-                               if flags == '-r':
-                                       same = dircmp(ax, bx)
-                               else:
-                                       same = 0
-                       else:
-                               try:
-                                       same = cmp.cmp(ax, bx)
-                               except (RuntimeError, os.error):
-                                       same = 0
-                       if same:
-                               ab_same.append((x, ab_same_action))
-                       else:
-                               ab_diff.append((x, ab_diff_action))
-       #
-       for x in b_list:
-               if x in ['./', '../']:
-                       pass
-               elif x not in a_list:
-                       b_only.append((x, b_only_action))
-       #
-       return data
-
-# Re-read the directory.
-# Attempt to find the selected item back.
-
-def update(w):
-       setbusy(w)
-       icol, irow = w.selection
-       if 0 <= icol < len(w.data) and 2 <= irow < len(w.data[icol]):
-               selname = w.data[icol][irow][0]
-       else:
-               selname = ''
-       statcache.forget_dir(w.a)
-       statcache.forget_dir(w.b)
-       tablewin.select(w, (-1, -1))
-       tablewin.update(w, diffdata(w.a, w.b, w.flags))
-       if selname:
-               for icol in range(len(w.data)):
-                       for irow in range(2, len(w.data[icol])):
-                               if w.data[icol][irow][0] == selname:
-                                       tablewin.select(w, (icol, irow))
-                                       break
-
-# Action functions for table items in directory diff windows
-
-def header_action(w, string, (icol, irow), (pos, clicks, button, mask)):
-       tablewin.select(w, (-1, -1))
-
-def a_only_action(w, string, (icol, irow), (pos, clicks, button, mask)):
-       tablewin.select(w, (icol, irow))
-       if clicks == 2:
-               w2 = anyopen(os.path.join(w.a, string))
-               if w2:
-                       w2.parent = w
-
-def b_only_action(w, string, (icol, irow), (pos, clicks, button, mask)):
-       tablewin.select(w, (icol, irow))
-       if clicks == 2:
-               w2 = anyopen(os.path.join(w.b, string))
-               if w2:
-                       w2.parent = w
-
-def ab_diff_action(w, string, (icol, irow), (pos, clicks, button, mask)):
-       tablewin.select(w, (icol, irow))
-       if clicks == 2:
-               w2 = anydiff(os.path.join(w.a, string), os.path.join(w.b, string),'')
-               w2.parent = w
-
-def ab_same_action(w, string, sel, detail):
-       ax = os.path.join(w.a, string)
-       if os.path.isdir(ax):
-               ab_diff_action(w, string, sel, detail)
-       else:
-               a_only_action(w, string, sel, detail)
-
-def anyopen(name): # Open any kind of document, ignore errors
-       try:
-               w = anywin.open(name)
-       except (RuntimeError, os.error):
-               stdwin.message('Can\'t open ' + name)
-               return 0
-       addstatmenu(w, [name])
-       return w
-
-def dircmp(a, b): # Compare whether two directories are the same
-       # To make this as fast as possible, it uses the statcache
-       print '  dircmp', a, b
-       a_list = dircache.listdir(a)
-       b_list = dircache.listdir(b)
-       for x in a_list:
-               if skipthis(x):
-                       pass
-               elif x not in b_list:
-                       return 0
-               else:
-                       ax = os.path.join(a, x)
-                       bx = os.path.join(b, x)
-                       if statcache.isdir(ax) and statcache.isdir(bx):
-                               if not dircmp(ax, bx): return 0
-                       else:
-                               try:
-                                       if not cmpcache.cmp(ax, bx): return 0
-                               except (RuntimeError, os.error):
-                                       return 0
-       for x in b_list:
-               if skipthis(x):
-                       pass
-               elif x not in a_list:
-                       return 0
-       return 1
-
-
-# View menu (for dir diff windows only)
-
-def addviewmenu(w):
-       w.viewmenu = m = w.menucreate('View')
-       m.action = []
-       add(m, 'diff -r A B', diffr_ab)
-       add(m, 'diff A B', diff_ab)
-       add(m, 'diff -b A B', diffb_ab)
-       add(m, 'diff -c A B', diffc_ab)
-       add(m, 'gdiff A B', gdiff_ab)
-       add(m, ('Open A   ', 'A'), open_a)
-       add(m, ('Open B   ', 'B'), open_b)
-       add(m, 'Rescan', rescan)
-       add(m, 'Rescan -r', rescan_r)
-
-# Action menu (for dir diff windows only)
-
-def addactionmenu(w):
-       w.actionmenu = m = w.menucreate('Action')
-       m.action = []
-       add(m, 'cp A B', cp_ab)
-       add(m, 'rm B', rm_b)
-       add(m, '', nop)
-       add(m, 'cp B A', cp_ba)
-       add(m, 'rm A', rm_a)
-
-# Main menu (global):
-
-def mainmenu():
-       m = stdwin.menucreate('Wdiff')
-       m.action = []
-       add(m, ('Quit wdiff', 'Q'), quit_wdiff)
-       add(m, 'Close subwindows', close_subwindows)
-       return m
-
-def add(m, text, action):
-       m.additem(text)
-       m.action.append(action)
-
-def quit_wdiff(w, m, item):
-       if askyesno('Really quit wdiff altogether?', 1):
-               sys.exit(0)
-
-def close_subwindows(w, m, item):
-       while 1:
-               for w2 in gwin.windows:
-                       if w2.parent == w:
-                               close_subwindows(w2, m, item)
-                               w2.close(w2)
-                               break # inner loop, continue outer loop
-               else:
-                       break # outer loop
-
-def diffr_ab(w, m, item):
-       dodiff(w, '-r')
-
-def diff_ab(w, m, item):
-       dodiff(w, '')
-
-def diffb_ab(w, m, item):
-       dodiff(w, '-b')
-
-def diffc_ab(w, m, item):
-       dodiff(w, '-c')
-
-def gdiff_ab(w, m, item): # Call SGI's gdiff utility
-       x = getselection(w)
-       if x:
-               a, b = os.path.join(w.a, x), os.path.join(w.b, x)
-               if os.path.isdir(a) or os.path.isdir(b):
-                       stdwin.fleep() # This is for files only
-               else:
-                       diffcmd = 'gdiff'
-                       diffcmd = diffcmd + mkarg(a) + mkarg(b) + ' &'
-                       print diffcmd
-                       sts = os.system(diffcmd)
-                       if sts: print 'Exit status', sts
-
-def dodiff(w, flags):
-       x = getselection(w)
-       if x:
-               w2 = anydiff(os.path.join(w.a, x), os.path.join(w.b, x), flags)
-               w2.parent = w
-
-def open_a(w, m, item):
-       x = getselection(w)
-       if x:
-               w2 = anyopen(os.path.join(w.a, x))
-               if w2:
-                       w2.parent = w
-
-def open_b(w, m, item):
-       x = getselection(w)
-       if x:
-               w2 = anyopen(os.path.join(w.b, x))
-               if w2:
-                       w2.parent = w
-
-def rescan(w, m, item):
-       w.flags = ''
-       update(w)
-
-def rescan_r(w, m, item):
-       w.flags = '-r'
-       update(w)
-
-def rm_a(w, m, item):
-       x = getselection(w)
-       if x:
-               if x[-1:] == '/': x = x[:-1]
-               x = os.path.join(w.a, x)
-               if os.path.isdir(x):
-                       if askyesno('Recursively remove A directory ' + x, 1):
-                               runcmd('rm -rf' + mkarg(x))
-               else:
-                       runcmd('rm -f' + mkarg(x))
-               update(w)
-
-def rm_b(w, m, item):
-       x = getselection(w)
-       if x:
-               if x[-1:] == '/': x = x[:-1]
-               x = os.path.join(w.b, x)
-               if os.path.isdir(x):
-                       if askyesno('Recursively remove B directory ' + x, 1):
-                               runcmd('rm -rf' + mkarg(x))
-               else:
-                       runcmd('rm -f' + mkarg(x))
-               update(w)
-
-def cp_ab(w, m, item):
-       x = getselection(w)
-       if x:
-               if x[-1:] == '/': x = x[:-1]
-               ax = os.path.join(w.a, x)
-               bx = os.path.join(w.b, x)
-               if os.path.isdir(ax):
-                       if os.path.exists(bx):
-                               m = 'Can\'t copy directory to existing target'
-                               stdwin.message(m)
-                               return
-                       runcmd('cp -r' + mkarg(ax) + mkarg(w.b))
-               else:
-                       runcmd('cp' + mkarg(ax) + mk2arg(w.b, x))
-               update(w)
-
-def cp_ba(w, m, item):
-       x = getselection(w)
-       if x:
-               if x[-1:] == '/': x = x[:-1]
-               ax = os.path.join(w.a, x)
-               bx = os.path.join(w.b, x)
-               if os.path.isdir(bx):
-                       if os.path.exists(ax):
-                               m = 'Can\'t copy directory to existing target'
-                               stdwin.message(m)
-                               return
-                       runcmd('cp -r' + mkarg(bx) + mkarg(w.a))
-               else:
-                       runcmd('cp' + mk2arg(w.b, x) + mkarg(ax))
-               update(w)
-
-def nop(args):
-       pass
-
-def getselection(w):
-       icol, irow = w.selection
-       if 0 <= icol < len(w.data):
-               if 0 <= irow < len(w.data[icol]):
-                       return w.data[icol][irow][0]
-       stdwin.message('no selection')
-       return ''
-
-def runcmd(cmd):
-       print cmd
-       sts, output = commands.getstatusoutput(cmd)
-       if sts or output:
-               if not output:
-                       output = 'Exit status ' + `sts`
-               stdwin.message(output)
-
-
-# Status menu (for all kinds of windows)
-
-def addstatmenu(w, files):
-       w.statmenu = m = w.menucreate('Stat')
-       m.files = files
-       m.action = []
-       for file in files:
-               m.additem(commands.getstatus(file))
-               m.action.append(stataction)
-
-def stataction(w, m, item): # Menu item action for stat menu
-       file = m.files[item]
-       try:
-               m.setitem(item, commands.getstatus(file))
-       except os.error:
-               stdwin.message('Can\'t get status for ' + file)
-
-
-# Compute a suitable window title from two paths
-
-def mktitle(a, b):
-       if a == b: return a
-       i = 1
-       while a[-i:] == b[-i:]: i = i+1
-       i = i-1
-       if not i:
-               return a + '  ' + b
-       else:
-               return '{' + a[:-i] + ',' + b[:-i] + '}' + a[-i:]
-
-
-# Ask a confirmation question
-
-def askyesno(prompt, default):
-       try:
-               return stdwin.askync(prompt, default)
-       except KeyboardInterrupt:
-               return 0
-
-
-# Display a message "busy" in a window, and mark it for updating
-
-def setbusy(w):
-       left, top = w.getorigin()
-       width, height = w.getwinsize()
-       right, bottom = left + width, top + height
-       d = w.begindrawing()
-       d.erase((0, 0), (10000, 10000))
-       text = 'Busy...'
-       textwidth = d.textwidth(text)
-       textheight = d.lineheight()
-       h, v = left + (width-textwidth)/2, top + (height-textheight)/2
-       d.text((h, v), text)
-       del d
-       w.change((0, 0), (10000, 10000))
-
-
-# Main function
-
-def main():
-       print 'wdiff: warning: this program does NOT make backups'
-       argv = sys.argv
-       flags = ''
-       if len(argv) >= 2 and argv[1][:1] == '-':
-               flags = argv[1]
-               del argv[1]
-       stdwin.setdefscrollbars(0, 1)
-       m = mainmenu() # Create menu earlier than windows
-       if len(argv) == 2: # 1 argument
-               w = anyopen(argv[1])
-               if not w: return
-       elif len(argv) == 3: # 2 arguments
-               w = anydiff(argv[1], argv[2], flags)
-               w.parent = ()
-       else:
-               sys.stdout = sys.stderr
-               print 'usage:', argv[0], '[diff-flags] dir-1 [dir-2]'
-               sys.exit(2)
-       del w # It's preserved in gwin.windows
-       while 1:
-               try:
-                       gwin.mainloop()
-                       break
-               except KeyboardInterrupt:
-                       pass    # Just continue...
-
-# Start the main function (this is a script)
-main()