summaryrefslogtreecommitdiffstats
path: root/Demo
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2000-05-11 14:43:52 (GMT)
committerGuido van Rossum <guido@python.org>2000-05-11 14:43:52 (GMT)
commitdab6cb8f6dacc107e9482976ca2f8e0313f05131 (patch)
tree88eef631a9c853ed763bb1be126ad3a11d6185db /Demo
parentede8c6eea1da425960b27ed735a41bc23a72a89a (diff)
downloadcpython-dab6cb8f6dacc107e9482976ca2f8e0313f05131.zip
cpython-dab6cb8f6dacc107e9482976ca2f8e0313f05131.tar.gz
cpython-dab6cb8f6dacc107e9482976ca2f8e0313f05131.tar.bz2
removing more stdwin users
Diffstat (limited to 'Demo')
-rw-r--r--Demo/sgi/audio_stdwin/README19
-rwxr-xr-xDemo/sgi/audio_stdwin/jukebox.py321
-rwxr-xr-xDemo/sgi/audio_stdwin/rec.py268
-rwxr-xr-xDemo/sgi/audio_stdwin/vumeter.py35
-rw-r--r--Demo/sgi/gl/glstdwin/fontchart.py34
-rw-r--r--Demo/sgi/gl/glstdwin/glstdwdraw.py135
-rw-r--r--Demo/sgi/gl/glstdwin/glstdwin.py400
-rw-r--r--Demo/sgi/gl/glstdwin/glstdwmenu.py62
-rw-r--r--Demo/sgi/gl/glstdwin/glstdwwin.py139
-rw-r--r--Demo/sgi/gl/glstdwin/stdwingl.py10
-rw-r--r--Demo/sgi/gl/glstdwin/tcolor.py43
-rw-r--r--Demo/sgi/gl/glstdwin/tglsw.py70
-rw-r--r--Demo/sgi/gl/glstdwin/tmenu.py44
-rwxr-xr-xDemo/stdwin/FormTest.py30
-rw-r--r--Demo/stdwin/README18
-rwxr-xr-xDemo/stdwin/RadioGroups.py98
-rwxr-xr-xDemo/stdwin/TestCSplit.py25
-rwxr-xr-xDemo/stdwin/TestDirList.py18
-rwxr-xr-xDemo/stdwin/TestFormSplit.py27
-rwxr-xr-xDemo/stdwin/TestSched.py38
-rwxr-xr-xDemo/stdwin/TestTextEdit.py13
-rwxr-xr-xDemo/stdwin/clock.py193
-rw-r--r--Demo/stdwin/ibrowse/README34
-rwxr-xr-xDemo/stdwin/ibrowse/dir62
-rwxr-xr-xDemo/stdwin/ibrowse/ib2
-rwxr-xr-xDemo/stdwin/ibrowse/ib.py21
-rwxr-xr-xDemo/stdwin/ibrowse/ibrowse719
-rwxr-xr-xDemo/stdwin/ibrowse/ibrowse.py617
-rwxr-xr-xDemo/stdwin/ibrowse/icache.py74
-rwxr-xr-xDemo/stdwin/ibrowse/ifile.py328
-rwxr-xr-xDemo/stdwin/ibrowse/itags.py127
-rwxr-xr-xDemo/stdwin/jukebox.py413
-rwxr-xr-xDemo/stdwin/lpwin.py198
-rwxr-xr-xDemo/stdwin/microedit.py183
-rwxr-xr-xDemo/stdwin/miniedit.py356
-rwxr-xr-xDemo/stdwin/python.py449
-rwxr-xr-xDemo/stdwin/wdiff.py484
37 files changed, 0 insertions, 6107 deletions
diff --git a/Demo/sgi/audio_stdwin/README b/Demo/sgi/audio_stdwin/README
deleted file mode 100644
index 6d96fe1..0000000
--- a/Demo/sgi/audio_stdwin/README
+++ /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
index 2aaaa83..0000000
--- a/Demo/sgi/audio_stdwin/jukebox.py
+++ /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
index 76e924e..0000000
--- a/Demo/sgi/audio_stdwin/rec.py
+++ /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
index e27c538..0000000
--- a/Demo/sgi/audio_stdwin/vumeter.py
+++ /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
index 6b58f12..0000000
--- a/Demo/sgi/gl/glstdwin/fontchart.py
+++ /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
index 4ddc7a6..0000000
--- a/Demo/sgi/gl/glstdwin/glstdwdraw.py
+++ /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
index b7d02c7..0000000
--- a/Demo/sgi/gl/glstdwin/glstdwin.py
+++ /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
index dd6d90b..0000000
--- a/Demo/sgi/gl/glstdwin/glstdwmenu.py
+++ /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
index b880b9a..0000000
--- a/Demo/sgi/gl/glstdwin/glstdwwin.py
+++ /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
index 4427593..0000000
--- a/Demo/sgi/gl/glstdwin/stdwingl.py
+++ /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
index d1c49e1..0000000
--- a/Demo/sgi/gl/glstdwin/tcolor.py
+++ /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
index 8854e98..0000000
--- a/Demo/sgi/gl/glstdwin/tglsw.py
+++ /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
index 233edae..0000000
--- a/Demo/sgi/gl/glstdwin/tmenu.py
+++ /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
index 15e3b36..0000000
--- a/Demo/stdwin/FormTest.py
+++ /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
index 5291225..0000000
--- a/Demo/stdwin/README
+++ /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
index 93b6a2d..0000000
--- a/Demo/stdwin/RadioGroups.py
+++ /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
index 720b8c3..0000000
--- a/Demo/stdwin/TestCSplit.py
+++ /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
index 321c2d9..0000000
--- a/Demo/stdwin/TestDirList.py
+++ /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
index e67c3f9..0000000
--- a/Demo/stdwin/TestFormSplit.py
+++ /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
index 29274e6..0000000
--- a/Demo/stdwin/TestSched.py
+++ /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
index b15b049..0000000
--- a/Demo/stdwin/TestTextEdit.py
+++ /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
index 90f1d22..0000000
--- a/Demo/stdwin/clock.py
+++ /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
index 22e4039..0000000
--- a/Demo/stdwin/ibrowse/README
+++ /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
index 21d1989..0000000
--- a/Demo/stdwin/ibrowse/dir
+++ /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.)
-
-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
index 04cb790..0000000
--- a/Demo/stdwin/ibrowse/ib
+++ /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
index ce6e16a..0000000
--- a/Demo/stdwin/ibrowse/ib.py
+++ /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
index 8b0dcde..0000000
--- a/Demo/stdwin/ibrowse/ibrowse
+++ /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.
-
-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.
-
-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.
-
-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.
-
-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.
-
-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.
-
-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.
-
-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.
-
-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.
-
-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.
-
-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.
-
-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.
-
-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.
-
-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.
-
-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.
-
-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!
-
-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-refs21419
-File: ibrowse, Node: Tags22145
-^_
-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.)
-
-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.
-
-Tag table:
-Node: Top117
-Node: Summary952
-Node: Help-Small-Screen997
-Node: Help2628
-Node: Help-P3588
-Node: Help-Page4348
-Node: Help-M7763
-Node: Help-FOO13183
-Node: Help-Adv13887
-Node: Help-Cross15923
-Node: Help-Q16443
-Node: Expert17326
-Node: Add20280
-Node: Menus23273
-Node: Cross-refs26394
-Node: Tags27050
-Node: Checking28966
-
-End tag table
diff --git a/Demo/stdwin/ibrowse/ibrowse.py b/Demo/stdwin/ibrowse/ibrowse.py
deleted file mode 100755
index eec5eb7..0000000
--- a/Demo/stdwin/ibrowse/ibrowse.py
+++ /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
index 0629bf9..0000000
--- a/Demo/stdwin/ibrowse/icache.py
+++ /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
index 9447164..0000000
--- a/Demo/stdwin/ibrowse/ifile.py
+++ /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
index 7cddcfa..0000000
--- a/Demo/stdwin/ibrowse/itags.py
+++ /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
index e3c9db8..0000000
--- a/Demo/stdwin/jukebox.py
+++ /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
index 519b428..0000000
--- a/Demo/stdwin/lpwin.py
+++ /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
index 1091676..0000000
--- a/Demo/stdwin/microedit.py
+++ /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
index 9a11c2d..0000000
--- a/Demo/stdwin/miniedit.py
+++ /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
index 8a3dfce..0000000
--- a/Demo/stdwin/python.py
+++ /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
index 50ca032..0000000
--- a/Demo/stdwin/wdiff.py
+++ /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()