]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Initial revision
authorGuido van Rossum <guido@python.org>
Mon, 30 Mar 1992 11:39:53 +0000 (11:39 +0000)
committerGuido van Rossum <guido@python.org>
Mon, 30 Mar 1992 11:39:53 +0000 (11:39 +0000)
Demo/sgi/audio/README [new file with mode: 0644]
Demo/sgi/audio/play.py [new file with mode: 0755]
Demo/sgi/audio_stdwin/README [new file with mode: 0644]
Demo/sgi/audio_stdwin/jukebox.py [new file with mode: 0755]
Demo/sgi/audio_stdwin/rec.py [new file with mode: 0755]
Demo/sgi/audio_stdwin/vumeter.py [new file with mode: 0755]
Demo/sgi/flp/test_cb.fd [new file with mode: 0755]
Demo/sgi/flp/test_cb.py [new file with mode: 0755]
Demo/sgi/flp/test_nocb.fd [new file with mode: 0755]
Demo/sgi/flp/test_nocb.py [new file with mode: 0755]

diff --git a/Demo/sgi/audio/README b/Demo/sgi/audio/README
new file mode 100644 (file)
index 0000000..02a3701
--- /dev/null
@@ -0,0 +1,8 @@
+Programs that demonstrate the use of the audio device on the SGI 4D/25.
+These require the built-in module 'audio'.
+
+XXX This hardware is already obsolete; see ../al for examples of audio
+XXX on the Indigo and 4D/35.
+
+play           Read a sound sample from a file and play it through the
+               speaker.  Options to set volume, sampling rate etc.
diff --git a/Demo/sgi/audio/play.py b/Demo/sgi/audio/play.py
new file mode 100755 (executable)
index 0000000..adc7625
--- /dev/null
@@ -0,0 +1,75 @@
+#! /usr/local/python
+
+import sys
+import audio
+
+import string
+import getopt
+import auds
+
+debug = []
+
+DEF_RATE = 3
+
+def main():
+       #
+       gain = 100
+       rate = 0
+       starter = audio.write
+       stopper = 0
+       #
+       optlist, args = getopt.getopt(sys.argv[1:], 'adg:r:')
+       #
+       for optname, optarg in optlist:
+               if 0:
+                       pass
+               elif optname == '-d':
+                       debug.append(1)
+               elif optname == '-g':
+                       gain = string.atoi(optarg)
+                       if not (0 < gain < 256):
+                               raise optarg.error, '-g gain out of range'
+               elif optname == '-r':
+                       rate = string.atoi(optarg)
+                       if not (1 <= rate <= 3):
+                               raise optarg.error, '-r rate out of range'
+               elif optname == '-a':
+                       starter = audio.start_playing
+                       stopper = audio.wait_playing
+       #
+       audio.setoutgain(gain)
+       audio.setrate(rate)
+       #
+       if not args:
+               play(starter, rate, auds.loadfp(sys.stdin))
+       else:
+               real_stopper = 0
+               for file in args:
+                       if real_stopper:
+                               real_stopper()
+                       play(starter, rate, auds.load(file))
+                       real_stopper = stopper
+
+def play(starter, rate, data):
+       magic = data[:4]
+       if magic == '0008':
+               mrate = 3
+       elif magic == '0016':
+               mrate = 2
+       elif magic == '0032':
+               mrate = 1
+       else:
+               mrate = 0
+       if mrate:
+               data = data[4:]
+       else:
+               mrate = DEF_RATE
+       if not rate: rate = mrate
+       audio.setrate(rate)
+       starter(data)
+
+try:
+       main()
+finally:
+       audio.setoutgain(0)
+       audio.done()
diff --git a/Demo/sgi/audio_stdwin/README b/Demo/sgi/audio_stdwin/README
new file mode 100644 (file)
index 0000000..6d96fe1
--- /dev/null
@@ -0,0 +1,19 @@
+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
new file mode 100755 (executable)
index 0000000..b223992
--- /dev/null
@@ -0,0 +1,321 @@
+#! /usr/local/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
new file mode 100755 (executable)
index 0000000..0caba89
--- /dev/null
@@ -0,0 +1,268 @@
+#! /ufs/guido/bin/sgi/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
new file mode 100755 (executable)
index 0000000..bfee66e
--- /dev/null
@@ -0,0 +1,35 @@
+#! /usr/local/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/flp/test_cb.fd b/Demo/sgi/flp/test_cb.fd
new file mode 100755 (executable)
index 0000000..e83fd1f
--- /dev/null
@@ -0,0 +1,75 @@
+Magic: 12321
+
+Internal Form Definition File
+    (do not change)
+
+Number of forms: 1
+
+=============== FORM ===============
+Name: main_form
+Width: 170.000000
+Height: 190.000000
+Number of Objects: 4
+
+--------------------
+class: 1
+type: 1
+box: 0.000000 0.000000 170.000000 190.000000
+boxtype: 1
+colors: 47 47
+alignment: 4
+style: 0
+size: 11.000000
+lcol: 0
+label: 
+name: 
+callback: 
+argument: 
+
+--------------------
+class: 11
+type: 0
+box: 10.000000 140.000000 150.000000 40.000000
+boxtype: 1
+colors: 47 47
+alignment: 4
+style: 0
+size: 11.000000
+lcol: 0
+label: Button 1
+name: button1
+callback: button1CB
+argument: 0
+
+--------------------
+class: 11
+type: 0
+box: 10.000000 100.000000 150.000000 40.000000
+boxtype: 1
+colors: 47 47
+alignment: 4
+style: 0
+size: 11.000000
+lcol: 0
+label: Button 2
+name: button2
+callback: button2CB
+argument: 0
+
+--------------------
+class: 11
+type: 6
+box: 10.000000 10.000000 150.000000 40.000000
+boxtype: 1
+colors: 47 47
+alignment: 4
+style: 0
+size: 11.000000
+lcol: 0
+label: EXIT
+name: exitbutton
+callback: exitbuttonCB
+argument: 0
+
+==============================
+create_the_forms
diff --git a/Demo/sgi/flp/test_cb.py b/Demo/sgi/flp/test_cb.py
new file mode 100755 (executable)
index 0000000..d622332
--- /dev/null
@@ -0,0 +1,62 @@
+#
+# Example 2 - Using fl in python with callbacks.
+#
+# The form is named 'main_form' and resides on file 'test_cb.fd'.
+# It has three objects named button1, button2 and exitbutton.
+# All buttons have callbacks with the same names as their corresponding
+# buttons but with CB appended.
+#
+import fl              # The forms library
+import FL              # Symbolic constants for the above
+import flp             # The module to parse .fd files
+import sys
+
+# The following struct is created to hold the instance variables
+# main_form, button1, button2 and exitbutton.
+
+class myform():
+       #
+       # The init function parses and creates the form, but doesn't
+       # display it (yet).
+       def init(self, number):
+               #
+               # First we parse the form
+               parsetree = flp.parse_form('test_cb', 'main_form')
+               #
+               # Next we create it
+               
+               flp.create_full_form(self, parsetree)
+
+               # And keep our number
+               self.number = number
+               return self
+
+       #
+       # The show function displays the form. It doesn't do any interaction,
+       # though.
+       def show(self):
+               self.main_form.show_form(FL.PLACE_SIZE, 1, '')
+
+       # The callback functions
+       def button1CB(self, obj, arg):
+               print 'Button 1 pressed on form', self.number
+
+       def button2CB(self, obj, arg):
+               print 'Button 2 pressed on form', self.number
+
+       def exitbuttonCB(self, obj, arg):
+               print 'Ok, bye bye'
+               sys.exit(0)
+
+#
+# The main program. Instantiate two variables of the forms class
+# and interact with them.
+
+form1 = myform().init(1)
+form2 = myform().init(2)
+
+form1.show()
+form2.show()
+
+obj = fl.do_forms()
+print 'do_forms() returned. This should not happen. obj=', obj
diff --git a/Demo/sgi/flp/test_nocb.fd b/Demo/sgi/flp/test_nocb.fd
new file mode 100755 (executable)
index 0000000..4d3f7ef
--- /dev/null
@@ -0,0 +1,75 @@
+Magic: 12321
+
+Internal Form Definition File
+    (do not change)
+
+Number of forms: 1
+
+=============== FORM ===============
+Name: main_form
+Width: 170.000000
+Height: 190.000000
+Number of Objects: 4
+
+--------------------
+class: 1
+type: 1
+box: 0.000000 0.000000 170.000000 190.000000
+boxtype: 1
+colors: 47 47
+alignment: 4
+style: 0
+size: 11.000000
+lcol: 0
+label: 
+name: 
+callback: 
+argument: 
+
+--------------------
+class: 11
+type: 0
+box: 10.000000 140.000000 150.000000 40.000000
+boxtype: 1
+colors: 47 47
+alignment: 4
+style: 0
+size: 11.000000
+lcol: 0
+label: Button 1
+name: button1
+callback: 
+argument: 
+
+--------------------
+class: 11
+type: 0
+box: 10.000000 100.000000 150.000000 40.000000
+boxtype: 1
+colors: 47 47
+alignment: 4
+style: 0
+size: 11.000000
+lcol: 0
+label: Button 2
+name: button2
+callback: 
+argument: 
+
+--------------------
+class: 11
+type: 6
+box: 10.000000 10.000000 150.000000 40.000000
+boxtype: 1
+colors: 47 47
+alignment: 4
+style: 0
+size: 11.000000
+lcol: 0
+label: EXIT
+name: exitbutton
+callback: 
+argument: 
+
+==============================
+create_the_forms
diff --git a/Demo/sgi/flp/test_nocb.py b/Demo/sgi/flp/test_nocb.py
new file mode 100755 (executable)
index 0000000..48cee9d
--- /dev/null
@@ -0,0 +1,45 @@
+#
+# Example 1 - Using fl in python without callbacks.
+#
+# The form is named 'main_form' and resides on file 'test_nocb.fd'.
+# It has three objects named button1, button2 and exitbutton.
+#
+import fl              # The forms library
+import FL              # Symbolic constants for the above
+import flp             # The module to parse .fd files
+import sys
+
+# The following struct is created to hold the instance variables
+# main_form, button1, button2 and exitbutton.
+
+class struct(): pass
+container = struct()
+
+#
+# We now first parse the forms file
+
+parsetree = flp.parse_form('test_nocb', 'main_form')
+
+#
+# Next we create it
+
+flp.create_full_form(container, parsetree)
+
+#
+# And display it
+
+container.main_form.show_form(FL.PLACE_MOUSE, 1, '')
+
+#
+# And interact until the exit button is pressed
+while 1:
+       selected_obj = fl.do_forms()
+       if selected_obj == container.button1:
+               print 'Button 1 selected'
+       elif selected_obj == container.button2:
+               print 'Button 2 selected'
+       elif selected_obj == container.exitbutton:
+               print 'Ok, bye bye'
+               sys.exit(0)
+       else:
+               print 'do_forms() returned unknown object ', selected_obj