aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README71
-rw-r--r--demo/README22
-rwxr-xr-xdemo/scripts/findlinksto.py29
-rwxr-xr-xdemo/scripts/mkreal.py65
-rwxr-xr-xdemo/scripts/ptags.py66
-rwxr-xr-xdemo/scripts/suff.py29
-rwxr-xr-xdemo/scripts/xxci.py77
-rw-r--r--demo/sgi/README15
-rw-r--r--demo/sgi/audio/README5
-rwxr-xr-xdemo/sgi/audio/play.py75
-rw-r--r--demo/sgi/audio_stdwin/README16
-rwxr-xr-xdemo/sgi/audio_stdwin/jukebox.py321
-rwxr-xr-xdemo/sgi/audio_stdwin/rec.py271
-rwxr-xr-xdemo/sgi/audio_stdwin/vumeter.py35
-rw-r--r--demo/sgi/gl/README22
-rwxr-xr-xdemo/sgi/gl/backface.py140
-rwxr-xr-xdemo/sgi/gl/kites.py194
-rw-r--r--demo/sgi/gl/mclock.doc60
-rwxr-xr-xdemo/sgi/gl/mclock.py729
-rwxr-xr-xdemo/sgi/gl/mixing.py116
-rwxr-xr-xdemo/sgi/gl/nurbs.py171
-rwxr-xr-xdemo/sgi/gl/zrgb.py169
-rw-r--r--demo/sgi/gl_panel/README23
-rwxr-xr-xdemo/sgi/gl_panel/apanel/apanel.py63
-rw-r--r--demo/sgi/gl_panel/apanel/apanel.s76
-rw-r--r--demo/sgi/gl_panel/flying/data.py42
-rwxr-xr-xdemo/sgi/gl_panel/flying/flying.py375
-rw-r--r--demo/sgi/gl_panel/flying/flying.s140
-rw-r--r--demo/sgi/gl_panel/flying/freeze.s31
-rw-r--r--demo/sgi/gl_panel/flying/light.py46
-rw-r--r--demo/sgi/gl_panel/flying/light.s94
-rw-r--r--demo/sgi/gl_panel/flying/material.py26
-rw-r--r--demo/sgi/gl_panel/flying/materials.s161
-rw-r--r--demo/sgi/gl_panel/flying/objdict.py41
-rw-r--r--demo/sgi/gl_panel/flying/objectdef.py147
-rw-r--r--demo/sgi/gl_panel/flying/panel.s76
-rwxr-xr-xdemo/sgi/gl_panel/nurbs/nurbs.py196
-rw-r--r--demo/sgi/gl_panel/nurbs/nurbs.s81
-rw-r--r--demo/sgi/gl_panel/nurbs/nurbsdata.py82
-rw-r--r--demo/sgi/gl_panel/twoview/block.py73
-rw-r--r--demo/sgi/gl_panel/twoview/camera.s55
-rw-r--r--demo/sgi/gl_panel/twoview/observer.s98
-rw-r--r--demo/sgi/gl_panel/twoview/topview.s47
-rwxr-xr-xdemo/sgi/gl_panel/twoview/twoview.py395
-rwxr-xr-xdemo/stdwin/wdiff.py480
-rw-r--r--doc/Makefile47
-rw-r--r--doc/README24
-rw-r--r--doc/SetClass.py17
-rw-r--r--doc/fibo.py15
-rw-r--r--doc/mod.tex62
-rw-r--r--doc/mod1.tex521
-rw-r--r--doc/mod2.tex1083
-rw-r--r--doc/mod3.tex484
-rw-r--r--doc/myformat.sty34
-rwxr-xr-xdoc/pytry20
-rw-r--r--doc/tut.tex1550
-rw-r--r--lib/Abstract.py61
-rw-r--r--lib/Buttons.py399
-rw-r--r--lib/CSplit.py70
-rw-r--r--lib/DEVICE.py423
-rw-r--r--lib/GL.py365
-rw-r--r--lib/HVSplit.py56
-rw-r--r--lib/Histogram.py36
-rw-r--r--lib/Sliders.py175
-rw-r--r--lib/Soundogram.py36
-rw-r--r--lib/Split.py116
-rw-r--r--lib/StripChart.py68
-rw-r--r--lib/Tcl.py421
-rw-r--r--lib/TclShell.py255
-rw-r--r--lib/TclUtil.py377
-rw-r--r--lib/TestCSplit.py26
-rw-r--r--lib/TransParent.py96
-rw-r--r--lib/VUMeter.py47
-rw-r--r--lib/WindowParent.py101
-rw-r--r--lib/adv.py366
-rw-r--r--lib/anywin.py14
-rw-r--r--lib/auds.py106
-rw-r--r--lib/calendar.py213
-rw-r--r--lib/clock.py202
-rw-r--r--lib/cmp.py61
-rw-r--r--lib/cmpcache.py68
-rw-r--r--lib/commands.py77
-rw-r--r--lib/dircache.py36
-rw-r--r--lib/dircmp.py205
-rw-r--r--lib/dirwin.py29
-rw-r--r--lib/dis.py176
-rw-r--r--lib/dump.py63
-rw-r--r--lib/fact.py37
-rw-r--r--lib/filewin.py18
-rw-r--r--lib/fnmatch.py35
-rw-r--r--lib/getopt.py47
-rw-r--r--lib/glob.py44
-rw-r--r--lib/grep.py32
-rw-r--r--lib/gwin.py122
-rw-r--r--lib/lambda.py151
-rw-r--r--lib/listwin.py47
-rw-r--r--lib/localtime.py53
-rw-r--r--lib/maccache.py61
-rw-r--r--lib/macglob.py46
-rw-r--r--lib/macpath.py108
-rw-r--r--lib/macshell.py399
-rw-r--r--lib/minmax.py6
-rw-r--r--lib/packmail.py48
-rw-r--r--lib/panel.py281
-rw-r--r--lib/panelparser.py128
-rw-r--r--lib/path.py125
-rw-r--r--lib/poly.py55
-rw-r--r--lib/rand.py12
-rw-r--r--lib/rect.py88
-rw-r--r--lib/selection.py72
-rw-r--r--lib/shutil.py70
-rw-r--r--lib/stat.py57
-rw-r--r--lib/statcache.py86
-rw-r--r--lib/stdwinevents.py46
-rw-r--r--lib/stdwinsupport.py34
-rw-r--r--lib/string.py129
-rw-r--r--lib/sunaudio.py54
-rw-r--r--lib/tablewin.py237
-rw-r--r--lib/tb.py220
-rw-r--r--lib/testall.py416
-rw-r--r--lib/textwin.py119
-rw-r--r--lib/util.py30
-rw-r--r--lib/whrandom.py74
-rw-r--r--lib/zmod.py94
-rw-r--r--python.man79
-rw-r--r--shar/python-0.9.1-01-21.shar1952
-rw-r--r--shar/python-0.9.1-01.patch163
-rw-r--r--shar/python-0.9.1-03-21.shar2944
-rw-r--r--shar/python-0.9.1-04-21.shar2755
-rw-r--r--shar/python-0.9.1-05-21.shar2528
-rw-r--r--shar/python-0.9.1-06-21.shar2510
-rw-r--r--shar/python-0.9.1-07-21.shar2518
-rw-r--r--shar/python-0.9.1-08-21.shar2349
-rw-r--r--shar/python-0.9.1-09-21.shar2688
-rw-r--r--shar/python-0.9.1-10-21.shar2508
-rw-r--r--shar/python-0.9.1-11-21.shar2618
-rw-r--r--shar/python-0.9.1-12-21.shar2833
-rw-r--r--shar/python-0.9.1-13-21.shar2811
-rw-r--r--shar/python-0.9.1-14-21.shar2720
-rw-r--r--shar/python-0.9.1-15-21.shar2539
-rw-r--r--shar/python-0.9.1-16-21.shar2495
-rw-r--r--shar/python-0.9.1-17-21.shar2464
-rw-r--r--shar/python-0.9.1-18-21.shar2268
-rw-r--r--shar/python-0.9.1-19-21.shar1997
-rw-r--r--shar/python-0.9.1-20-21.shar1941
-rw-r--r--shar/python-0.9.1-21-21.shar1675
-rw-r--r--src/Grammar72
-rw-r--r--src/Makefile508
-rw-r--r--src/PROTO.h79
-rw-r--r--src/README11
-rw-r--r--src/To.do11
-rw-r--r--src/acceler.c136
-rw-r--r--src/allobjects.h50
-rw-r--r--src/amoebamodule.c774
-rw-r--r--src/asa.c494
-rw-r--r--src/asa.h33
-rw-r--r--src/assert.h25
-rw-r--r--src/audiomodule.c615
-rw-r--r--src/bitset.c99
-rw-r--r--src/bitset.h46
-rw-r--r--src/bltinmodule.c559
-rw-r--r--src/bltinmodule.h27
-rw-r--r--src/ceval.c1436
-rw-r--r--src/ceval.h33
-rw-r--r--src/cgen458
-rw-r--r--src/cgensupport.c393
-rw-r--r--src/cgensupport.h39
-rw-r--r--src/classobject.c298
-rw-r--r--src/classobject.h44
-rw-r--r--src/compile.c1772
-rw-r--r--src/compile.h47
-rw-r--r--src/config.c180
-rw-r--r--src/configmac.c109
-rw-r--r--src/cstubs999
-rw-r--r--src/dictobject.c605
-rw-r--r--src/dictobject.h44
-rw-r--r--src/errcode.h36
-rw-r--r--src/errors.c196
-rw-r--r--src/errors.h58
-rw-r--r--src/fgetsintr.c94
-rw-r--r--src/fgetsintr.h25
-rw-r--r--src/fileobject.c293
-rw-r--r--src/fileobject.h33
-rw-r--r--src/firstsets.c133
-rw-r--r--src/floatobject.c271
-rw-r--r--src/floatobject.h44
-rw-r--r--src/fmod.c51
-rw-r--r--src/frameobject.c156
-rw-r--r--src/frameobject.h80
-rw-r--r--src/funcobject.c113
-rw-r--r--src/funcobject.h33
-rw-r--r--src/getcwd.c102
-rw-r--r--src/graminit.c1094
-rw-r--r--src/graminit.h66
-rw-r--r--src/grammar.c233
-rw-r--r--src/grammar.h105
-rw-r--r--src/grammar1.c75
-rw-r--r--src/import.c259
-rw-r--r--src/import.h31
-rw-r--r--src/intobject.c307
-rw-r--r--src/intobject.h72
-rw-r--r--src/intrcheck.c144
-rw-r--r--src/listnode.c93
-rw-r--r--src/listobject.c519
-rw-r--r--src/listobject.h59
-rw-r--r--src/macmodule.c246
-rw-r--r--src/malloc.h63
-rw-r--r--src/mathmodule.c180
-rw-r--r--src/metagrammar.c176
-rw-r--r--src/metagrammar.h30
-rw-r--r--src/methodobject.c147
-rw-r--r--src/methodobject.h42
-rw-r--r--src/modsupport.c381
-rw-r--r--src/modsupport.h27
-rw-r--r--src/moduleobject.c154
-rw-r--r--src/moduleobject.h33
-rw-r--r--src/node.c100
-rw-r--r--src/node.h58
-rw-r--r--src/object.c290
-rw-r--r--src/object.h324
-rw-r--r--src/objimpl.h50
-rw-r--r--src/opcode.h109
-rw-r--r--src/panelmodule.c1090
-rw-r--r--src/parser.c423
-rw-r--r--src/parser.h50
-rw-r--r--src/parsetok.c158
-rw-r--r--src/parsetok.h29
-rw-r--r--src/patchlevel.h1
-rw-r--r--src/pgen.c751
-rw-r--r--src/pgen.h30
-rw-r--r--src/pgenheaders.h50
-rw-r--r--src/pgenmain.c148
-rw-r--r--src/posixmodule.c427
-rw-r--r--src/printgrammar.c149
-rw-r--r--src/profmain.c133
-rw-r--r--src/pythonmain.c440
-rw-r--r--src/pythonrun.h47
-rw-r--r--src/regexp.c1394
-rw-r--r--src/regexp.h51
-rw-r--r--src/regexpmodule.c191
-rw-r--r--src/regmagic.h29
-rw-r--r--src/regsub.c115
-rw-r--r--src/rltokenizer.c26
-rw-r--r--src/sc_errors.c145
-rw-r--r--src/sc_errors.h41
-rw-r--r--src/sc_global.h137
-rw-r--r--src/sc_interpr.c1352
-rw-r--r--src/scdbg.c152
-rw-r--r--src/sigtype.h51
-rw-r--r--src/stdwinmodule.c1697
-rw-r--r--src/stdwinobject.h31
-rw-r--r--src/strdup.c39
-rw-r--r--src/strerror.c47
-rw-r--r--src/stringobject.c347
-rw-r--r--src/stringobject.h63
-rw-r--r--src/strtol.c122
-rw-r--r--src/structmember.c158
-rw-r--r--src/structmember.h64
-rw-r--r--src/stubcode.h28
-rw-r--r--src/sysmodule.c214
-rw-r--r--src/sysmodule.h30
-rw-r--r--src/timemodule.c229
-rw-r--r--src/token.h69
-rw-r--r--src/tokenizer.c523
-rw-r--r--src/tokenizer.h53
-rw-r--r--src/traceback.c217
-rw-r--r--src/traceback.h30
-rw-r--r--src/tupleobject.c287
-rw-r--r--src/tupleobject.h56
-rw-r--r--src/typeobject.c61
-rw-r--r--src/xxobject.c131
271 files changed, 96470 insertions, 0 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..5fe1ff7
--- /dev/null
+++ b/README
@@ -0,0 +1,71 @@
+This is Python, an extensible interpreted programming language that
+combines remarkable power with very clear syntax.
+
+This is version 0.9 (the first beta release), patchlevel 1.
+
+Python can be used instead of shell, Awk or Perl scripts, to write
+prototypes of real applications, or as an extension language of large
+systems, you name it. There are built-in modules that interface to
+the operating system and to various window systems: X11, the Mac
+window system (you need STDWIN for these two), and Silicon Graphics'
+GL library. It runs on most modern versions of UNIX, on the Mac, and
+I wouldn't be surprised if it ran on MS-DOS unchanged. I developed it
+mostly on an SGI IRIS workstation (using IRIX 3.1 and 3.2) and on the
+Mac, but have tested it also on SunOS (4.1) and BSD 4.3 (tahoe).
+
+Building and installing Python is easy (but do read the Makefile).
+A UNIX style manual page and extensive documentation (in LaTeX format)
+are provided. (In the beta release, the documentation is still under
+development.)
+
+Please try it out and send me your comments (on anything -- the
+language design, implementation, portability, installation,
+documentation) and the modules you wrote for it, to make the first
+real release better. If you needed to hack the source to get it to
+compile and run on a particular machine, send me the fixes -- I'll try
+to incorporate them into the next patch. If you can't get it to work
+at all, send me a *detailed* description of the problem and I may look
+into it.
+
+If you want to profit of the X11 or Mac window interface, you'll need
+STDWIN. This is a portable window system interface by the same
+author. The versions of STDWIN floating around on some archives are
+not sufficiently up-to-date for use with Python. I will distribute
+the latest and greatest STDWIN version at about the same time as Python.
+
+I am the author of Python:
+
+ Guido van Rossum
+ CWI, dept. CST
+ Kruislaan 413
+ 1098 SJ Amsterdam
+ The Netherlands
+
+
+The Python source is copyrighted, but you can freely use and copy it
+as long as you don't change or remove the copyright:
+
+/***********************************************************
+Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
+Netherlands.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
diff --git a/demo/README b/demo/README
new file mode 100644
index 0000000..a9ff224
--- /dev/null
+++ b/demo/README
@@ -0,0 +1,22 @@
+This directory contains various demonstrations of what you can do with
+Python. The demos are grouped sub(sub*)directories according to
+required optional built-in modules.
+
+scripts Some useful Python scripts that I put in my bin
+ directory. No optional built-in modules meeded.
+
+sgi Demos that only run on Silicon Graphics machines.
+ Require the built-in modules 'audio' and/or 'gl'.
+
+stdwin Demos that use the STDWIN library. Require the 'stdwin'
+ built-in module.
+
+WARNING: some scripts are executable and have a first line saying
+
+ #! /ufs/guido/bin/sgi/python
+
+This is unlikely to give good results anywhere else except in my
+office. Edit the first line before installing such scripts; to try
+them out, you can just say "python file.py". (The .py suffix is not
+necessary in this case, but makes it possible to debug the modules
+interactively by importing them.)
diff --git a/demo/scripts/findlinksto.py b/demo/scripts/findlinksto.py
new file mode 100755
index 0000000..210441e
--- /dev/null
+++ b/demo/scripts/findlinksto.py
@@ -0,0 +1,29 @@
+#! /ufs/guido/bin/sgi/python
+
+# findlinksto
+#
+# find symbolic links to a given path
+
+import posix, path, sys
+
+def visit(pattern, dirname, names):
+ if path.islink(dirname):
+ names[:] = []
+ return
+ if path.ismount(dirname):
+ print 'descend into', dirname
+ n = len(pattern)
+ for name in names:
+ name = path.cat(dirname, name)
+ try:
+ linkto = posix.readlink(name)
+ if linkto[:n] = pattern:
+ print name, '->', linkto
+ except posix.error:
+ pass
+
+def main(pattern, args):
+ for dirname in args:
+ path.walk(dirname, visit, pattern)
+
+main(sys.argv[1], sys.argv[2:])
diff --git a/demo/scripts/mkreal.py b/demo/scripts/mkreal.py
new file mode 100755
index 0000000..19fef28
--- /dev/null
+++ b/demo/scripts/mkreal.py
@@ -0,0 +1,65 @@
+#! /ufs/guido/bin/sgi/python
+
+# mkreal
+#
+# turn a symlink to a directory into a real directory
+
+import sys
+import posix
+import path
+from stat import *
+
+cat = path.cat
+
+error = 'mkreal error'
+
+BUFSIZE = 32*1024
+
+def mkrealfile(name):
+ st = posix.stat(name) # Get the mode
+ mode = S_IMODE(st[ST_MODE])
+ linkto = posix.readlink(name) # Make sure again it's a symlink
+ f_in = open(name, 'r') # This ensures it's a file
+ posix.unlink(name)
+ f_out = open(name, 'w')
+ while 1:
+ buf = f_in.read(BUFSIZE)
+ if not buf: break
+ f_out.write(buf)
+ del f_out # Flush data to disk before changing mode
+ posix.chmod(name, mode)
+
+def mkrealdir(name):
+ st = posix.stat(name) # Get the mode
+ mode = S_IMODE(st[ST_MODE])
+ linkto = posix.readlink(name)
+ files = posix.listdir(name)
+ posix.unlink(name)
+ posix.mkdir(name, mode)
+ posix.chmod(name, mode)
+ linkto = cat('..', linkto)
+ #
+ for file in files:
+ if file not in ('.', '..'):
+ posix.symlink(cat(linkto, file), cat(name, file))
+
+def main():
+ sys.stdout = sys.stderr
+ progname = path.basename(sys.argv[0])
+ args = sys.argv[1:]
+ if not args:
+ print 'usage:', progname, 'path ...'
+ sys.exit(2)
+ status = 0
+ for name in args:
+ if not path.islink(name):
+ print progname+':', name+':', 'not a symlink'
+ status = 1
+ else:
+ if path.isdir(name):
+ mkrealdir(name)
+ else:
+ mkrealfile(name)
+ sys.exit(status)
+
+main()
diff --git a/demo/scripts/ptags.py b/demo/scripts/ptags.py
new file mode 100755
index 0000000..0f99650
--- /dev/null
+++ b/demo/scripts/ptags.py
@@ -0,0 +1,66 @@
+#! /ufs/guido/bin/sgi/python
+
+# ptags
+#
+Create a tags file for Python programs
+# Tagged are:
+# - functions (even inside other defs or classes)
+# - classes
+# - filenames
+# Warns about files it cannot open.
+# No warnings about duplicate tags.
+
+import sys
+import posix
+import path
+import string
+
+keywords = ['def', 'class'] # If you add keywords, update starts!!!
+starts = 'dc' # Starting characters of keywords
+
+whitespace = string.whitespace
+identchars = string.letters + string.digits + '_'
+
+tags = [] # Modified!
+
+def main():
+ args = sys.argv[1:]
+ for file in args: treat_file(file)
+ if tags:
+ fp = open('tags', 'w')
+ tags.sort()
+ for s in tags: fp.write(s)
+
+def treat_file(file):
+ try:
+ fp = open(file, 'r')
+ except:
+ print 'Cannot open', file
+ return
+ base = path.basename(file)
+ if base[-3:] = '.py': base = base[:-3]
+ s = base + '\t' + file + '\t' + '1\n'
+ tags.append(s)
+ while 1:
+ line = fp.readline()
+ if not line: break
+ maketag(line, file)
+
+def maketag(line, file):
+ i = 0
+ while line[i:i+1] in whitespace: i = i+1
+ if line[i:i+1] not in starts: return
+ n = len(line)
+ j = i
+ while i < n and line[i] not in whitespace: i = i+1
+ if line[j:i] not in keywords: return
+ while i < n and line[i] in whitespace: i = i+1
+ j = i
+ while i < n and line[i] in identchars: i = i+1
+ name = line[j:i]
+ while i < n and line[i] in whitespace: i = i+1
+ if i < n and line[i] = '(': i = i+1
+ s = name + '\t' + file + '\t' + '/^' + line[:i] + '/\n'
+ tags.append(s)
+
+main()
diff --git a/demo/scripts/suff.py b/demo/scripts/suff.py
new file mode 100755
index 0000000..f6bd6bf
--- /dev/null
+++ b/demo/scripts/suff.py
@@ -0,0 +1,29 @@
+#! /ufs/guido/bin/sgi/python
+
+# suff
+#
+# show different suffixes amongst arguments
+
+import sys
+
+def main():
+ files = sys.argv[1:]
+ suffixes = {}
+ for file in files:
+ suff = getsuffix(file)
+ if not suffixes.has_key(suff):
+ suffixes[suff] = []
+ suffixes[suff].append(file)
+ keys = suffixes.keys()
+ keys.sort()
+ for suff in keys:
+ print `suff`, len(suffixes[suff])
+
+def getsuffix(file):
+ suff = ''
+ for i in range(len(file)):
+ if file[i] = '.':
+ suff = file[i:]
+ return suff
+
+main()
diff --git a/demo/scripts/xxci.py b/demo/scripts/xxci.py
new file mode 100755
index 0000000..43ea316
--- /dev/null
+++ b/demo/scripts/xxci.py
@@ -0,0 +1,77 @@
+#! /ufs/guido/bin/sgi/python
+
+# xxci
+#
+# check in files for which rcsdiff returns nonzero exit status
+
+import sys
+import posix
+import stat
+import path
+import commands
+
+MAXSIZE = 200*1024 # Files this big must be binaries and are skipped.
+
+def getargs():
+ args = sys.argv[1:]
+ if args:
+ return args
+ print 'No arguments, checking almost *'
+ for file in posix.listdir('.'):
+ if not skipfile(file):
+ args.append(file)
+ if not args:
+ print 'Nothing to do -- exit 1'
+ sys.exit(1)
+ args.sort()
+ return args
+
+badnames = ['tags', 'xyzzy']
+badprefixes = ['.', ',', '@', '#', 'o.']
+badsuffixes = \
+ ['~', '.a', '.o', '.old', '.bak', '.orig', '.new', '.prev', '.not']
+# XXX Should generalize even more to use fnmatch!
+
+def skipfile(file):
+ if file in badnames or \
+ badprefix(file) or badsuffix(file) or \
+ path.islink(file) or path.isdir(file):
+ return 1
+ # Skip huge files -- probably binaries.
+ try:
+ st = posix.stat(file)
+ except posix.error:
+ return 1 # Doesn't exist -- skip it
+ return st[stat.ST_SIZE] >= MAXSIZE
+
+def badprefix(file):
+ for bad in badprefixes:
+ if file[:len(bad)] = bad: return 1
+ return 0
+
+def badsuffix(file):
+ for bad in badsuffixes:
+ if file[-len(bad):] = bad: return 1
+ return 0
+
+def go(args):
+ for file in args:
+ print file + ':'
+ if run('rcsdiff -c', file):
+ if askyesno('Check in ' + file + ' ? '):
+ sts = run('rcs -l', file) # ignored
+ # can't use run() here because it's interactive
+ sts = posix.system('ci -l ' + file)
+
+def run(cmd, file):
+ sts, output = commands.getstatusoutput(cmd + commands.mkarg(file))
+ if sts:
+ print output
+ print 'Exit status', sts
+ return sts
+
+def askyesno(prompt):
+ s = raw_input(prompt)
+ return s in ['y', 'yes']
+
+go(getargs())
diff --git a/demo/sgi/README b/demo/sgi/README
new file mode 100644
index 0000000..5740c22
--- /dev/null
+++ b/demo/sgi/README
@@ -0,0 +1,15 @@
+Demonstrations of Python that use various features of the Silicon
+Graphics IRIS machines.
+
+audio Demonstrations of the audio capabilities of the 4D/25.
+ Require the built-in module 'audio'.
+
+audio_stdwin Window-based demonstrations the audio capabilities of
+ the 4D/25. Require the built-in modules 'stdwin' and
+ 'audio'.
+
+gl Demonstrations of the Graphics Library (GL).
+ Require the built-in module 'gl'.
+
+gl_panel Demonstrations of the Panel Library by NASA Ames.
+ Require the built-in modules 'gl' and 'pnl'.
diff --git a/demo/sgi/audio/README b/demo/sgi/audio/README
new file mode 100644
index 0000000..17dc9b2
--- /dev/null
+++ b/demo/sgi/audio/README
@@ -0,0 +1,5 @@
+Programs that demonstrate the use of the audio device on the SGI 4D/25.
+These require the built-in module 'audio'.
+
+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
index 0000000..8f6a802
--- /dev/null
+++ b/demo/sgi/audio/play.py
@@ -0,0 +1,75 @@
+#!/ufs/guido/bin/sgi/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
index 0000000..3074715
--- /dev/null
+++ b/demo/sgi/audio_stdwin/README
@@ -0,0 +1,16 @@
+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.
+
+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
index 0000000..5267d73
--- /dev/null
+++ b/demo/sgi/audio_stdwin/jukebox.py
@@ -0,0 +1,321 @@
+#! /ufs/guido/bin/sgi/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.cat(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.cat(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
index 0000000..3ab3aea
--- /dev/null
+++ b/demo/sgi/audio_stdwin/rec.py
@@ -0,0 +1,271 @@
+#! /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
+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():
+ #
+ # 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
+ #
+ while 1:
+ e = stdwin.getevent()
+ G.window.dispatch(e)
+
+# 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()
+
+Exit = 'exit' # exception
+
+def quit_hook(self):
+ raise Exit, 0
+
+try:
+ try:
+ main()
+ finally:
+ audio.setoutgain(0)
+except Exit, sts:
+ sys.exit(sts)
diff --git a/demo/sgi/audio_stdwin/vumeter.py b/demo/sgi/audio_stdwin/vumeter.py
new file mode 100755
index 0000000..1685ba2
--- /dev/null
+++ b/demo/sgi/audio_stdwin/vumeter.py
@@ -0,0 +1,35 @@
+#! /ufs/guido/bin/sgi/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/README b/demo/sgi/gl/README
new file mode 100644
index 0000000..f191cf5
--- /dev/null
+++ b/demo/sgi/gl/README
@@ -0,0 +1,22 @@
+These demos run only on SGI machines and require the 'gl' built-in module.
+The demonstrate the abilities of SGI's GL library as well as the ease of
+GL programming in Python. Most demos require the Z-buffer (aka
+24-bitplane) option.
+
+backface Demonstrates the 'backface' GL function.
+
+kites Show 3 flying kites. Demonstrates the rendering speed
+ obtainable by Python programs.
+
+mclock A colorful clock with more options than you can
+ remember. Works on 8-bit machines (but allows more
+ colors on 24-bit machines).
+
+mixing Demonstrates the effect of color mixing: through
+ frequent color switching it gives the effect of white
+ light.
+
+nurbs A simple demonstration of the 'nurbs' GL functions.
+
+zrgb Displays a 3-D Gouraud-shaded figure which can be moved
+ around with the mouse.
diff --git a/demo/sgi/gl/backface.py b/demo/sgi/gl/backface.py
new file mode 100755
index 0000000..5936f75
--- /dev/null
+++ b/demo/sgi/gl/backface.py
@@ -0,0 +1,140 @@
+#! /ufs/guido/bin/sgi/python
+
+# backface
+#
+# draw a cube that can run with backface() turned on or off.
+# cube is moved when LEFTMOUSE is pressed and mouse itself is moved.
+
+from gl import *
+from DEVICE import *
+from GL import *
+
+CUBE_SIZE = 200.0
+CUBE_OBJ = 1
+
+def main () :
+ #
+ x = 0
+ y = 0
+ moveit = 0
+ #
+ initialize()
+ #
+ while (1) :
+ #
+ while (qtest()) :
+ dev, val = qread()
+ #
+ if dev = ESCKEY :
+ backface(0)
+ return
+ #
+ elif dev = REDRAW :
+ reshapeviewport()
+ drawcube(x,y)
+ #
+ elif dev = LEFTMOUSE :
+ #
+ # LEFTMOUSE down
+ moveit = val
+ #
+ elif dev = BKEY :
+ backface(1)
+ drawcube(x,y)
+ #
+ elif dev = FKEY :
+ backface(0)
+ drawcube(x,y)
+ #
+ if moveit :
+ x = getvaluator(MOUSEX)
+ y = getvaluator(MOUSEY)
+ drawcube(x,y)
+
+
+def initialize () :
+ foreground ()
+ keepaspect (1, 1)
+ gid = winopen('backface')
+ winset(gid)
+ winconstraints()
+ #
+ doublebuffer()
+ gconfig()
+ shademodel(FLAT)
+ #
+ ortho(-1024.0, 1024.0, -1024.0, 1024.0, -1024.0, 1024.0)
+ #
+ qdevice(ESCKEY)
+ qdevice(REDRAW)
+ qdevice(LEFTMOUSE)
+ qdevice(BKEY)
+ qdevice(FKEY)
+ qenter(REDRAW,gid)
+ #
+ backface(1)
+
+#
+# define a cube
+def cube () :
+ #
+ # front face
+ pushmatrix()
+ translate(0.0,0.0,CUBE_SIZE)
+ color(RED)
+ rectf(-CUBE_SIZE,-CUBE_SIZE,CUBE_SIZE,CUBE_SIZE)
+ popmatrix()
+ #
+ # right face
+ pushmatrix()
+ translate(CUBE_SIZE, 0.0, 0.0)
+ rotate(900, 'y')
+ color(GREEN)
+ rectf(-CUBE_SIZE,-CUBE_SIZE,CUBE_SIZE,CUBE_SIZE)
+ popmatrix()
+ #
+ # back face
+ pushmatrix()
+ translate(0.0, 0.0, -CUBE_SIZE)
+ rotate(1800, 'y')
+ color(BLUE)
+ rectf(-CUBE_SIZE,-CUBE_SIZE,CUBE_SIZE,CUBE_SIZE)
+ popmatrix()
+ #
+ # left face
+ pushmatrix()
+ translate(-CUBE_SIZE, 0.0, 0.0)
+ rotate(-900, 'y')
+ color(CYAN)
+ rectf(-CUBE_SIZE,-CUBE_SIZE,CUBE_SIZE,CUBE_SIZE)
+ popmatrix()
+ #
+ # top face
+ pushmatrix()
+ translate(0.0, CUBE_SIZE, 0.0)
+ rotate(-900, 'x')
+ color(MAGENTA)
+ rectf(-CUBE_SIZE,-CUBE_SIZE,CUBE_SIZE,CUBE_SIZE)
+ popmatrix()
+ #
+ # bottom face
+ pushmatrix()
+ translate(0.0, -CUBE_SIZE, 0.0)
+ rotate(900, 'x')
+ color(YELLOW)
+ rectf(-CUBE_SIZE,-CUBE_SIZE,CUBE_SIZE,CUBE_SIZE)
+ popmatrix()
+
+def drawcube(x,y) :
+ #
+ pushmatrix()
+ rotate(2*x, 'x')
+ rotate(2*y, 'y')
+ color(BLACK)
+ clear()
+ cube()
+ popmatrix()
+ swapbuffers()
+
+
+main ()
diff --git a/demo/sgi/gl/kites.py b/demo/sgi/gl/kites.py
new file mode 100755
index 0000000..764ad2c
--- /dev/null
+++ b/demo/sgi/gl/kites.py
@@ -0,0 +1,194 @@
+#! /ufs/guido/bin/sgi/python
+
+# *** This only works correctly on a 24 bit-plane machine. ***
+#
+# A simple Python program that tests the some parts of the
+# GL library. It shows the speed that can be obtained when
+# doing simple graphics.
+#
+# The bottleneck in this program is NOT Python but the graphics
+# engine; i.e Python can feed the graphics pipeline fast enough
+# on the 4D/25G.
+#
+# This program show 3 kites flying around the screen. It uses
+#
+# * bgnpolygon, endpolygon
+# * v3, n3
+# * lmdef, lmbind
+#
+# Usage :
+#
+# ESC -> exit program
+# MOUSE3 -> freeze toggle
+# MOUSE2 -> one step (use this in freeze state)
+
+from GL import *
+from gl import *
+import DEVICE
+from math import *
+
+#
+# viewobj : sets the rotation, translation and scaling
+# set appropiate material, call drawobject()
+#
+def viewobj (r, s, t, mat) :
+ pushmatrix()
+ rot (r * 10.0, 'X')
+ rot (r * 10.0, 'Y')
+ rot (r * 10.0, 'Z')
+ scale (s[0], s[1], s[2])
+ translate (t[0], t[1], t[2])
+ lmbind(MATERIAL, mat)
+ drawobject()
+ popmatrix()
+
+#
+# makeobj : the contructor of the object
+#
+def mkobj () :
+ v0 = (-5.0 ,0.0, 0.0)
+ v1 = (0.0 ,5.0, 0.0)
+ v2 = (5.0 ,0.0, 0.0)
+ v3 = (0.0 ,2.0, 0.0)
+ n0 = (sqrt(2.0)/2.0, sqrt(2.0)/2.0, 0.0)
+ vn = ((v0, n0), (v1, n0), (v2, n0), (v3, n0))
+ #
+ return vn
+
+#
+# the object itself as an array of vertices and normals
+#
+kite = mkobj ()
+
+#
+# drawobject : draw a triangle. with bgnpolygon
+#
+def drawobject () :
+ #
+ bgnpolygon()
+ vnarray (kite)
+ endpolygon()
+
+#
+# identity matrix
+#
+idmat=[1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
+
+#
+# the rgb-value of light-blue
+#
+LightBlue = (43,169,255)
+
+#
+# the different materials.
+#
+m1=[SPECULAR,0.0,0.0,0.6,DIFFUSE,0.0,0.0,0.8,SHININESS,20.0,LMNULL]
+m2=[SPECULAR,0.8,0.0,0.1,DIFFUSE,0.8,0.0,0.3,SHININESS,120.0,LMNULL]
+m3=[SPECULAR,0.0,1.0,0.0,DIFFUSE,0.0,0.6,0.0,SHININESS,120.0,LMNULL]
+
+#
+# lightsources
+#
+light1 = [LCOLOR,1.0,1.0,1.0,POSITION,15.0,15.0,0.0,1.0,LMNULL]
+light2 = [LCOLOR,1.0,1.0,1.0,POSITION,-15.0,15.0,0.0,1.0,LMNULL]
+
+#
+# the lightmodel
+#
+model = [AMBIENT,0.2,0.2,0.2,LMNULL]
+
+#
+# initgl : opens the window, configures the pipeline to 2buf and zbuf,
+# sets the viewing, defines and binds the materials
+#
+def initgl () :
+ #
+ # open window
+ #
+ foreground ()
+ keepaspect (1, 1)
+ prefposition (100, 500, 100, 500)
+ w = winopen ('PYTHON lights')
+ keepaspect (1, 1)
+ winconstraints()
+ #
+ # configure pipeline (zbuf, 2buf, GOURAUD and RGBmode)
+ #
+ zbuffer (1)
+ doublebuffer ()
+ shademodel (GOURAUD)
+ RGBmode ()
+ gconfig ()
+ #
+ # define and bind materials (set perspective BEFORE loadmat !)
+ #
+ mmode(MVIEWING)
+ perspective (900, 1.0, 1.0, 20.0)
+ loadmatrix(idmat)
+ lmdef(DEFMATERIAL, 1, m1)
+ lmdef(DEFMATERIAL, 2, m2)
+ lmdef(DEFMATERIAL, 3, m3)
+ lmdef(DEFLIGHT, 1, light1)
+ lmdef(DEFLIGHT, 2, light2)
+ lmdef(DEFLMODEL, 1, model)
+ lmbind(LIGHT0,1)
+ lmbind(LIGHT1,2)
+ lmbind(LMODEL,1)
+ #
+ # set viewing
+ #
+ lookat (0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0)
+ #
+ # ask for the REDRAW and ESCKEY events
+ #
+ qdevice(DEVICE.MOUSE3)
+ qdevice(DEVICE.MOUSE2)
+ qdevice(DEVICE.REDRAW)
+ qdevice(DEVICE.ESCKEY)
+
+#
+# GoForIT : use 2buf to redraw the object 2n times. index i is used as
+# the (smoothly changing) rotation angle
+#
+def GoForIt(i) :
+ freeze = 1
+ while 1 :
+ if freeze <> 0 :
+ i = i + 1
+ #
+ # clear z-buffer and clear background to light-blue
+ #
+ zclear()
+ c3i (LightBlue)
+ clear()
+ #
+ # draw the 3 traiangles scaled above each other.
+ #
+ viewobj(float(i),[1.0,1.0,1.0],[1.0,1.0,1.0],1)
+ viewobj(float(i),[0.75,0.75,0.75],[0.0,2.0,2.0],2)
+ viewobj(float(i),[0.5,0.5,0.5],[0.0,4.0,4.0],3)
+ #
+ swapbuffers()
+ #
+ if qtest() <> 0 :
+ dev, val = qread()
+ if dev = DEVICE.ESCKEY :
+ break
+ elif dev = DEVICE.REDRAW :
+ reshapeviewport ()
+ elif dev = DEVICE.MOUSE3 and val <> 0 :
+ freeze = 1 - freeze
+ elif dev = DEVICE.MOUSE2 and val <> 0 :
+ i = i + 1
+
+
+# the main program
+#
+def main () :
+ initgl ()
+ GoForIt (0)
+
+#
+# exec main
+#
+main ()
diff --git a/demo/sgi/gl/mclock.doc b/demo/sgi/gl/mclock.doc
new file mode 100644
index 0000000..610e9ab
--- /dev/null
+++ b/demo/sgi/gl/mclock.doc
@@ -0,0 +1,60 @@
+Newsgroups: cwi.sgi
+Subject: Re: new clock
+Distribution: cwi.sgi
+References: <[email protected]>
+
+Last week I wrote:
+
+>For your enjoyment I have implemented a colorful clock.
+
+The clock has now been extended with some new facilities: a menu, an
+alarm and a gong. These may require some explanation beyond what's in
+the usage message.
+
+Menu
+----
+The right mouse button now pops up a menu that allows you to turn the
+seconds hand on or off and to switch the alarm off.
+
+Alarm
+-----
+
+The left and middle buttons set the alarm. When it is on, the alarm
+time is displayed as a time on a 24 hour clock in the bottom left
+corner. It is also indicated by two red triangles, corresponding to the
+little (hours) and big (minutes) hand. These hands can be moved around:
+the left mouse button moves the minutes hand, the middle button moves
+the hourds hand. Watch out for differences of twelve hours (always
+check the digital display); these can be corrected by dragging the hours
+hand once around the dial.
+
+When the alarm goes off, two things happen: a shell command specified on
+the command line with the -a option is executed (in the background), and
+the clock's colors change every two seconds, for five minutes. You can
+also turn the alarm off by using the menu accessible through the right
+mouse button.
+
+There is no default command for the -a option; if it is not specified,
+only the changing of the colors happens. If you have an 8 ohm speaker
+connected to the audio output of your Personal Iris, a suitable command
+would be:
+
+ mclock -a '/ufs/guido/bin/sgi/play /ufs/guido/lib/sounds/alarm'
+
+Gong
+----
+
+Some people like a clock that makes noises every hour, or even more
+often. This is supported by the -g and -G options. With -g you specify
+a shell command to be executed to sound the gong; with -G you can
+specify the interval between gong calls, in seconds (default is one hour).
+The shell command is executed in the background. It is given two
+arguments: the hours (on a 24 hour clock!) and the minutes. The
+executable Python script /ufs/guido/bin/sgi/chime is a suitable example.
+Again, this only works if you have installed a speaker (I bet 8 ohm
+speakers are going to be in demand!)
+
+--
+Guido van Rossum, Centre for Mathematics and Computer Science (CWI), Amsterdam
[email protected] or ..!hp4nl!cwi.nl!guido or guido%[email protected]
+"A thing of beauty is a joy till sunrise"
diff --git a/demo/sgi/gl/mclock.py b/demo/sgi/gl/mclock.py
new file mode 100755
index 0000000..806511c
--- /dev/null
+++ b/demo/sgi/gl/mclock.py
@@ -0,0 +1,729 @@
+#! /ufs/guido/bin/sgi/python
+
+#############################################################################
+# NOTA BENE: Before installing, fix TZDIFF to reflect your local time zone! #
+#############################################################################
+
+# "M Clock"
+#
+# An implementation in software of an original design by Rob Juda.
+# Clock implementation: Guido van Rossum.
+# Alarm and Gong features: Sape Mullender.
+#
+# XXX TO DO:
+# find out local time zone difference automatically
+# add a date indicator
+# allow multiple alarms
+# allow the menu to change more parameters
+
+import sys
+
+from gl import *
+from GL import *
+from DEVICE import *
+import time
+import getopt
+import string
+import path
+from math import pi
+import math
+import posix
+
+FULLC = 3600 # Full circle in 1/10-ths of a degree
+MIDN = 900 # Angle of the 12 o'clock position
+R, G, B = 0, 1, 2 # Indices of colors in RGB list
+
+HOUR = 3600 # Number of seconds per hour
+MINUTE = 60 # Number of seconds per minute
+
+class struct(): pass # Class to define featureless structures
+Gl = struct() # Object to hold writable global variables
+
+# Default constants (used in multiple places)
+
+SCREENBG = 127, 156, 191
+NPARTS = 9
+TITLE = 'M Clock'
+TZDIFF = -1*HOUR # <--- change this to reflect your local time zone
+
+# Default parameters
+
+Gl.foreground = 0 # If set, run in the foreground
+Gl.fullscreen = 0 # If set, run on full screen
+Gl.tzdiff = TZDIFF # Seconds west of Greenwich (winter time)
+Gl.nparts = NPARTS # Number of parts each circle is divided in (>= 2)
+Gl.debug = 0 # If set, print debug output
+Gl.doublebuffer = 1 # If set, use double buffering
+Gl.update = 0 # Update interval; seconds hand is suppressed if > 1
+Gl.colorsubset = 0 # If set, display only a subset of the colors
+Gl.cyan = 0 # If set, display cyan overlay (big hand)
+Gl.magenta = 0 # If set, display magenta overlay (little hand)
+Gl.yellow = 0 # If set, display yellow overlay (fixed background)
+Gl.black = 0 # If set, display black overlay (hands)
+Gl.colormap = 0 # If set, use colormap mode instead of RGB mode
+Gl.warnings = 0 # If set, print warnings
+Gl.title = '- - ' # Window title (default set later)
+Gl.border = 1 # If set, use a window border (and title)
+Gl.bg = 0, 0, 0 # Background color R, G, B value
+Gl.iconic = 0 # Set in iconic state
+Gl.fg = 255, 0, 0 # Alarm background RGB (either normal or alarm)
+Gl.ox,Gl.oy = 0,0 # Window origin
+Gl.cx,Gl.cy = 0,0 # Window size
+Gl.alarm_set = 0 # Alarm on or off
+Gl.alarm_on = 0 # Alarm is ringing
+Gl.alarm_time = 0 # Alarm time in seconds after midnight
+Gl.alarm_hours = 0 # Alarm hour setting, 24 hour clock
+Gl.alarm_minutes = 0 # Alarm minutes setting
+Gl.alarm_rgb = 0,0,0 # Alarm display RGB colors
+Gl.alarm_cmd = '' # Command to execute when alarm goes off
+Gl.mouse2down = 0 # Mouse button state
+Gl.mouse3down = 0 # Mouse button state
+Gl.gong_cmd = '' # Command to execute when chimes go off
+Gl.gong_int = 3600 # Gong interval
+Gl.indices = R, G, B # Colors (permuted when alarm is on)
+
+def main():
+ #
+ sys.stdout = sys.stderr # All output is errors/warnings etc.
+ #
+ try:
+ args = getoptions()
+ except string.atoi_error, value:
+ usage(string.atoi_error, value)
+ except getopt.error, msg:
+ usage(getopt.error, msg)
+ #
+ if args:
+ realtime = 0
+ hours = string.atoi(args[0])
+ minutes = seconds = 0
+ if args[1:]: minutes = string.atoi(args[1])
+ if args[2:]: seconds = string.atoi(args[2])
+ localtime = ((hours*60)+minutes)*60+seconds
+ else:
+ realtime = 1
+ #
+ if Gl.title = '- - ':
+ if realtime:
+ Gl.title = TITLE
+ else:
+ title = ''
+ for arg in args: title = title + ' ' + arg
+ Gl.title = title[1:]
+ del title
+ #
+ wid = makewindow()
+ Gl.ox,Gl.oy = getorigin()
+ Gl.cx,Gl.cy = getsize()
+ initmenu()
+ clearall()
+ #
+ if not Gl.update:
+ Gl.update = 60
+ #
+ if Gl.update <= 1:
+ Gl.timernoise = 6
+ else:
+ Gl.timernoise = 60
+ noise(TIMER0, Gl.timernoise)
+ #
+ qdevice(WINSHUT)
+ qdevice(WINQUIT)
+ qdevice(ESCKEY)
+ if realtime:
+ qdevice(TIMER0)
+ qdevice(REDRAW)
+ qdevice(WINFREEZE)
+ qdevice(WINTHAW)
+ qdevice(MENUBUTTON) # MOUSE1
+ qdevice(MOUSE3) # Left button
+ qdevice(MOUSE2) # Middle button
+ unqdevice(INPUTCHANGE)
+ #
+ lasttime = 0
+ Gl.change = 1
+ while 1:
+ if realtime:
+ localtime = time.time() - Gl.tzdiff
+ if Gl.alarm_set:
+ if localtime%(24*HOUR) = Gl.alarm_time:
+ # Ring the alarm!
+ if Gl.debug:
+ print 'Rrrringg!'
+ Gl.alarm_on = 1
+ if Gl.alarm_cmd <> '':
+ d = posix.system(Gl.alarm_cmd+' '+`Gl.alarm_time/3600`+' '+`(Gl.alarm_time/60)%60` + ' &')
+ Gl.change = 1
+ clearall()
+ if Gl.alarm_on:
+ if (localtime - Gl.alarm_time) % (24*HOUR) > 300:
+ # More than 5 minutes away from alarm
+ Gl.alarm_on = 0
+ if Gl.debug:
+ print 'Alarm turned off'
+ Gl.change = 1
+ clearall()
+ Gl.indices = R, G, B
+ else:
+ if localtime % 2 = 0:
+ # Permute color indices
+ Gl.indices = Gl.indices[2:] + Gl.indices[:2]
+ Gl.change = 1
+ if Gl.gong_cmd <> '' and localtime%Gl.gong_int = 0:
+ d = posix.system(Gl.gong_cmd+' '+`(localtime/3600)%24`+' '+`(localtime/60)%60` + ' &')
+ if localtime/Gl.update <> lasttime/Gl.update:
+ if Gl.debug: print 'new time'
+ Gl.change = 1
+ if Gl.change:
+ if Gl.debug: print 'drawing'
+ doit(localtime)
+ lasttime = localtime
+ Gl.change = 0
+ dev, data = qread()
+ if Gl.debug and dev <> TIMER0:
+ print dev, data
+ if dev = TIMER0:
+ if Gl.debug > 1:
+ print dev, data
+ elif dev = MOUSE3:
+ mousex = getvaluator(MOUSEX)
+ mousey = getvaluator(MOUSEY)
+ if mouseclick(3, data, mousex, mousey):
+ Gl.change = 1
+ elif dev = MOUSE2:
+ mousex = getvaluator(MOUSEX)
+ mousey = getvaluator(MOUSEY)
+ if mouseclick(2, data, mousex, mousey):
+ Gl.change = 1
+ elif dev = MOUSEX:
+ mousex = data
+ if Gl.mouse2down:
+ mouse2track(mousex, mousey)
+ if Gl.mouse3down:
+ mouse3track(mousex, mousey)
+ elif dev = MOUSEY:
+ mousey = data
+ if Gl.mouse2down:
+ mouse2track(mousex, mousey)
+ if Gl.mouse3down:
+ mouse3track(mousex, mousey)
+ elif dev = REDRAW or dev = REDRAWICONIC:
+ if Gl.debug:
+ if dev = REDRAW: print 'REDRAW'
+ else: print 'REDRAWICONIC'
+ reshapeviewport()
+ Gl.ox,Gl.oy = getorigin()
+ Gl.cx,Gl.cy = getsize()
+ Gl.change = 1
+ clearall()
+ elif dev = MENUBUTTON:
+ if Gl.debug: print 'MENUBUTTON'
+ handlemenu()
+ elif dev = WINFREEZE:
+ if Gl.debug: print 'WINFREEZE'
+ Gl.iconic = 1
+ noise(TIMER0, 60*60) # Redraw every 60 seconds only
+ elif dev = WINTHAW:
+ if Gl.debug: print 'WINTHAW'
+ Gl.iconic = 0
+ noise(TIMER0, Gl.timernoise)
+ Gl.change = 1
+ elif dev = ESCKEY or dev = WINSHUT or dev = WINQUIT:
+ if Gl.debug: print 'Exit'
+ sys.exit(0)
+
+def getoptions():
+ optlist, args = getopt.getopt(sys.argv[1:], 'A:a:B:bc:dFfG:g:n:sT:t:u:wCMYK')
+ for optname, optarg in optlist:
+ if optname = '-A':
+ Gl.fg = eval(optarg) # Should be (r,g,b)
+ elif optname = '-a':
+ Gl.alarm_cmd = optarg
+ elif optname = '-B':
+ Gl.bg = eval(optarg) # Should be (r,g,b)
+ elif optname = '-b':
+ Gl.border = 0
+ elif optname = '-c':
+ Gl.colormap = string.atoi(optarg)
+ elif optname = '-d':
+ Gl.debug = Gl.debug + 1
+ Gl.warnings = 1
+ elif optname = '-F':
+ Gl.foreground = 1
+ elif optname = '-f':
+ Gl.fullscreen = 1
+ elif optname = '-G':
+ Gl.gong_int = 60*string.atoi(optarg)
+ elif optname = '-g':
+ Gl.gong_cmd = optarg
+ elif optname = '-n':
+ Gl.nparts = string.atoi(optarg)
+ elif optname = '-s':
+ Gl.doublebuffer = 0
+ elif optname = '-T':
+ Gl.title = optarg
+ elif optname = '-t':
+ Gl.tzdiff = string.atoi(optarg)
+ elif optname = '-u':
+ Gl.update = string.atoi(optarg)
+ elif optname = '-w':
+ Gl.warnings = 1
+ elif optname = '-C':
+ Gl.cyan = Gl.colorsubset = 1
+ elif optname = '-M':
+ Gl.magenta = Gl.colorsubset = 1
+ elif optname = '-Y':
+ Gl.yellow = Gl.colorsubset = 1
+ elif optname = '-K':
+ Gl.black = Gl.colorsubset = 1
+ else:
+ print 'Unsupported option', optname
+ return args
+
+def usage(exc, msg):
+ if sys.argv:
+ progname = path.basename(sys.argv[0])
+ else:
+ progname = 'mclock'
+ #
+ print progname + ':',
+ if exc = string.atoi_error:
+ print 'non-numeric argument:',
+ print msg
+ #
+ print 'usage:', progname, '[options] [hh [mm [ss]]]'
+ #
+ print '-A r,g,b : alarm background red,green,blue [255,0,0]'
+ print '-a cmd : shell command executed when alarm goes off'
+ print '-B r,g,b : background red,green,blue [0,0,0]'
+ print ' (-B SCREENBG uses the default screen background)'
+ print '-b : suppress window border and title'
+ print '-c cmapid : select explicit colormap'
+ print '-d : more debug output (implies -F, -w)'
+ print '-F : run in foreground'
+ print '-f : use full screen'
+ print '-G intrvl : interval between chimes in minutes [60]'
+ print '-g cmd : shell command executed when chimes go off'
+ print '-s : single buffer mode'
+ print '-w : print various warnings'
+ print '-n nparts : number of parts [' + `NPARTS` + ']'
+ print '-T title : alternate window title [\'' + TITLE + '\']'
+ print '-t tzdiff : time zone difference [' + `TZDIFF` + ']'
+ print '-u update : update interval [60]'
+ print '-CMYK : Cyan, Magenta, Yellow or blacK overlay only'
+ print 'if hh [mm [ss]] is specified, display that time statically'
+ print 'on machines with < 12 bitplanes, -c and -s are forced on'
+ #
+ sys.exit(2)
+
+def doit(localtime):
+ hands = makehands(localtime)
+ list = makelist(hands)
+ render(list, hands)
+
+def makehands(localtime):
+ localtime = localtime % (12*HOUR)
+ seconds_hand = MIDN + FULLC - (localtime*60) % FULLC
+ big_hand = (MIDN + FULLC - (localtime%HOUR)) % FULLC
+ little_hand = (MIDN + FULLC - ((localtime/12) % HOUR)) % FULLC
+ return little_hand, big_hand, seconds_hand
+
+def makelist(little_hand, big_hand, seconds_hand):
+ total = []
+ if Gl.cyan or not Gl.colorsubset:
+ total = total + makesublist(big_hand, Gl.indices[0])
+ if Gl.magenta or not Gl.colorsubset:
+ total = total + makesublist(little_hand, Gl.indices[1])
+ if Gl.yellow or not Gl.colorsubset:
+ total = total + makesublist(MIDN, Gl.indices[2])
+ total.sort()
+ return total
+
+def makesublist(first, icolor):
+ list = []
+ alpha = FULLC/Gl.nparts
+ a = first - alpha/2
+ for i in range(Gl.nparts):
+ angle = (a + i*alpha + FULLC) % FULLC
+ value = 255*(Gl.nparts-1-i)/(Gl.nparts-1)
+ list.append(angle, icolor, value)
+ list.sort()
+ a, icolor, value = list[0]
+ if a <> 0:
+ a, icolor, value = list[len(list)-1]
+ t = 0, icolor, value
+ list.insert(0, t)
+ return list
+
+def rgb_fg():
+ return Gl.fg
+ # Obsolete code:
+ if Gl.alarm_on:
+ return Gl.bg
+ else:
+ return Gl.fg
+
+def rgb_bg():
+ return Gl.bg
+ # Obsolete code:
+ if Gl.alarm_on:
+ return Gl.fg
+ else:
+ return Gl.bg
+
+def clearall():
+ Gl.c3i(rgb_bg())
+ clear()
+ if Gl.doublebuffer:
+ swapbuffers()
+ clear()
+
+def draw_alarm(color):
+ frontbuffer(TRUE)
+ Gl.c3i(color)
+ pushmatrix()
+ rotate(-((Gl.alarm_time/12)%3600), 'z')
+ bgnpolygon()
+ v2f( 0.00,1.00)
+ v2f( 0.04,1.05)
+ v2f(-0.04,1.05)
+ endpolygon()
+ popmatrix()
+ #
+ pushmatrix()
+ rotate(-((Gl.alarm_time)%3600), 'z')
+ bgnpolygon()
+ v2f( 0.00,1.05)
+ v2f( 0.07,1.10)
+ v2f(-0.07,1.10)
+ endpolygon()
+ popmatrix()
+ #
+ cmov2(-1.06, -1.06)
+ charstr(string.rjust(`Gl.alarm_time/3600`,2))
+ charstr(':')
+ charstr(string.zfill((Gl.alarm_time/60)%60,2))
+ frontbuffer(FALSE)
+
+def render(list, (little_hand, big_hand, seconds_hand)):
+ #
+ if Gl.colormap:
+ resetindex()
+ #
+ if not list:
+ Gl.c3i(255, 255, 255) # White
+ circf(0.0, 0.0, 1.0)
+ else:
+ list.append(3600, 0, 255) # Sentinel
+ #
+ rgb = [255, 255, 255]
+ a_prev = 0
+ for a, icolor, value in list:
+ if a <> a_prev:
+ [r, g, b] = rgb
+ if Gl.debug > 1:
+ print rgb, a_prev, a
+ Gl.c3i(r, g, b)
+ arcf(0.0, 0.0, 1.0, a_prev, a)
+ rgb[icolor] = value
+ a_prev = a
+ #
+ if Gl.black or not Gl.colorsubset:
+ #
+ # Draw the hands -- in black
+ #
+ Gl.c3i(0, 0, 0)
+ #
+ if Gl.update = 1 and not Gl.iconic:
+ # Seconds hand is only drawn if we update every second
+ pushmatrix()
+ rotate(seconds_hand, 'z')
+ bgnline()
+ v2f(0.0, 0.0)
+ v2f(1.0, 0.0)
+ endline()
+ popmatrix()
+ #
+ pushmatrix()
+ rotate(big_hand, 'z')
+ rectf(0.0, -0.01, 0.97, 0.01)
+ circf(0.0, 0.0, 0.01)
+ circf(0.97, 0.0, 0.01)
+ popmatrix()
+ #
+ pushmatrix()
+ rotate(little_hand, 'z')
+ rectf(0.04, -0.02, 0.63, 0.02)
+ circf(0.04, 0.0, 0.02)
+ circf(0.63, 0.0, 0.02)
+ popmatrix()
+ #
+ # Draw the alarm time, if set or being set
+ #
+ if Gl.alarm_set:
+ draw_alarm(rgb_fg())
+ #
+ if Gl.doublebuffer: swapbuffers()
+
+def makewindow():
+ #
+ if Gl.debug or Gl.foreground:
+ foreground()
+ #
+ if Gl.fullscreen:
+ # XXX Should find out true screen size using getgdesc()
+ prefposition(0, 1279, 0, 1023)
+ else:
+ keepaspect(1, 1)
+ minsize(64, 64)
+ #
+ if not Gl.border:
+ noborder()
+ wid = winopen(Gl.title)
+ #
+ if not Gl.fullscreen:
+ keepaspect(1, 1)
+ minsize(10, 10)
+ maxsize(2000, 2000)
+ iconsize(66, 66)
+ winconstraints()
+ #
+ nplanes = getplanes()
+ nmaps = getgdesc(GD_NMMAPS)
+ if Gl.warnings:
+ print nplanes, 'color planes,', nmaps, 'color maps'
+ #
+ if nplanes < 12 or Gl.colormap:
+ if not Gl.colormap:
+ Gl.colormap = nmaps - 1
+ if Gl.warnings:
+ print 'not enough color planes available',
+ print 'for RGB mode; forcing colormap mode'
+ print 'using color map number', Gl.colormap
+ if not Gl.colorsubset:
+ needed = 3
+ else:
+ needed = Gl.cyan + Gl.magenta + Gl.yellow
+ needed = needed*Gl.nparts
+ if Gl.bg <> (0, 0, 0):
+ needed = needed+1
+ if Gl.fg <> (0, 0, 0):
+ needed = needed+1
+ if Gl.doublebuffer:
+ if needed > available(nplanes/2):
+ Gl.doublebuffer = 0
+ if Gl.warnings:
+ print 'not enough colors available',
+ print 'for double buffer mode;',
+ print 'forcing single buffer mode'
+ else:
+ nplanes = nplanes/2
+ if needed > available(nplanes):
+ # Do this warning always
+ print 'still not enough colors available;',
+ print 'parts will be left white'
+ print '(needed', needed, 'but have only',
+ print available(nplanes), 'colors available)'
+ #
+ if Gl.doublebuffer:
+ doublebuffer()
+ gconfig()
+ #
+ if Gl.colormap:
+ Gl.c3i = pseudo_c3i
+ fixcolormap()
+ else:
+ Gl.c3i = c3i
+ RGBmode()
+ gconfig()
+ #
+ if Gl.fullscreen:
+ # XXX Should find out true screen size using getgdesc()
+ ortho2(-1.1*1.280, 1.1*1.280, -1.1*1.024, 1.1*1.024)
+ else:
+ ortho2(-1.1, 1.1, -1.1, 1.1)
+ #
+ return wid
+
+def available(nplanes):
+ return pow(2, nplanes) - 1 # Reserve one pixel for black
+
+def fixcolormap():
+ multimap()
+ gconfig()
+ nplanes = getplanes()
+ if Gl.warnings:
+ print 'multimap mode has', nplanes, 'color planes'
+ imap = Gl.colormap
+ Gl.startindex = pow(2, nplanes) - 1
+ Gl.stopindex = 1
+ setmap(imap)
+ mapcolor(0, 0, 0, 0) # Fixed entry for black
+ if Gl.bg <> (0, 0, 0):
+ r, g, b = Gl.bg
+ mapcolor(1, r, g, b) # Fixed entry for Gl.bg
+ Gl.stopindex = 2
+ if Gl.fg <> (0, 0, 0):
+ r, g, b = Gl.fg
+ mapcolor(2, r, g, b) # Fixed entry for Gl.fg
+ Gl.stopindex = 3
+ Gl.overflow_seen = 0
+ resetindex()
+
+def resetindex():
+ Gl.index = Gl.startindex
+
+r0g0b0 = (0, 0, 0)
+
+def pseudo_c3i(rgb):
+ if rgb = r0g0b0:
+ index = 0
+ elif rgb = Gl.bg:
+ index = 1
+ elif rgb = Gl.fg:
+ index = 2
+ else:
+ index = definecolor(rgb)
+ color(index)
+
+def definecolor(rgb):
+ index = Gl.index
+ if index < Gl.stopindex:
+ if Gl.debug: print 'definecolor hard case', rgb
+ # First see if we already have this one...
+ for index in range(Gl.stopindex, Gl.startindex+1):
+ if rgb = getmcolor(index):
+ if Gl.debug: print 'return', index
+ return index
+ # Don't clobber reserverd colormap entries
+ if not Gl.overflow_seen:
+ # Shouldn't happen any more, hence no Gl.warnings test
+ print 'mclock: out of colormap entries'
+ Gl.overflow_seen = 1
+ return Gl.stopindex
+ r, g, b = rgb
+ if Gl.debug > 1: print 'mapcolor', (index, r, g, b)
+ mapcolor(index, r, g, b)
+ Gl.index = index - 1
+ return index
+
+# Compute n**i
+def pow(n, i):
+ x = 1
+ for j in range(i): x = x*n
+ return x
+
+def mouseclick(mouse, updown, x, y):
+ if updown = 1:
+ # mouse button came down, start tracking
+ if Gl.debug:
+ print 'mouse', mouse, 'down at', x, y
+ if mouse = 2:
+ Gl.mouse2down = 1
+ mouse2track(x, y)
+ elif mouse = 3:
+ Gl.mouse3down = 1
+ mouse3track(x, y)
+ else:
+ print 'fatal error'
+ qdevice(MOUSEX)
+ qdevice(MOUSEY)
+ return 0
+ else:
+ # mouse button came up, stop tracking
+ if Gl.debug:
+ print 'mouse', mouse, 'up at', x, y
+ unqdevice(MOUSEX)
+ unqdevice(MOUSEY)
+ if mouse = 2:
+ mouse2track(x, y)
+ Gl.mouse2down = 0
+ elif mouse = 3:
+ mouse3track(x, y)
+ Gl.mouse3down = 0
+ else:
+ print 'fatal error'
+ Gl.alarm_set = 1
+ return 1
+
+def mouse3track(x, y):
+ # first compute polar coordinates from x and y
+ cx, cy = Gl.ox + Gl.cx/2, Gl.oy + Gl.cy/2
+ x, y = x - cx, y - cy
+ if (x, y) = (0, 0): return # would cause an exception
+ minutes = int(30.5 + 30.0*math.atan2(float(-x), float(-y))/pi)
+ if minutes = 60: minutes = 0
+ a,b = Gl.alarm_minutes/15, minutes/15
+ if (a,b) = (0,3):
+ # Moved backward through 12 o'clock:
+ Gl.alarm_hours = Gl.alarm_hours - 1
+ if Gl.alarm_hours < 0: Gl.alarm_hours = Gl.alarm_hours + 24
+ if (a,b) = (3,0):
+ # Moved forward through 12 o'clock:
+ Gl.alarm_hours = Gl.alarm_hours + 1
+ if Gl.alarm_hours >= 24: Gl.alarm_hours = Gl.alarm_hours - 24
+ Gl.alarm_minutes = minutes
+ seconds = Gl.alarm_hours * HOUR + Gl.alarm_minutes * MINUTE
+ if seconds <> Gl.alarm_time:
+ draw_alarm(rgb_bg())
+ Gl.alarm_time = seconds
+ draw_alarm(rgb_fg())
+
+def mouse2track(x, y):
+ # first compute polar coordinates from x and y
+ cx, cy = Gl.ox + Gl.cx/2, Gl.oy + Gl.cy/2
+ x, y = x - cx, y - cy
+ if (x, y) = (0, 0): return # would cause an exception
+ hours = int(6.5 - float(Gl.alarm_minutes)/60.0 + 6.0*math.atan2(float(-x), float(-y))/pi)
+ if hours = 12: hours = 0
+ if (Gl.alarm_hours,hours) = (0,11):
+ # Moved backward through midnight:
+ Gl.alarm_hours = 23
+ elif (Gl.alarm_hours,hours) = (12,11):
+ # Moved backward through noon:
+ Gl.alarm_hours = 11
+ elif (Gl.alarm_hours,hours) = (11,0):
+ # Moved forward through noon:
+ Gl.alarm_hours = 12
+ elif (Gl.alarm_hours,hours) = (23,0):
+ # Moved forward through midnight:
+ Gl.alarm_hours = 0
+ elif Gl.alarm_hours < 12:
+ Gl.alarm_hours = hours
+ else:
+ Gl.alarm_hours = hours + 12
+ seconds = Gl.alarm_hours * HOUR + Gl.alarm_minutes * MINUTE
+ if seconds <> Gl.alarm_time:
+ draw_alarm(rgb_bg())
+ Gl.alarm_time = seconds
+ draw_alarm(rgb_fg())
+
+def initmenu():
+ Gl.pup = pup = newpup()
+ addtopup(pup, 'M Clock%t|Alarm On/Off|Seconds Hand On/Off|Quit', 0)
+
+def handlemenu():
+ item = dopup(Gl.pup)
+ if item = 1:
+ # Toggle alarm
+ if Gl.alarm_set:
+ Gl.alarm_set = 0
+ Gl.alarm_on = 0
+ else:
+ Gl.alarm_set = 1
+ Gl.change = 1
+ clearall()
+ elif item = 2:
+ # Toggle Seconds Hand
+ if Gl.update = 1:
+ Gl.update = 60
+ Gl.timernoise = 60
+ else:
+ Gl.update = 1
+ Gl.timernoise = 6
+ Gl.change = 1
+ elif item = 3:
+ if Gl.debug: print 'Exit'
+ sys.exit(0)
+
+main()
diff --git a/demo/sgi/gl/mixing.py b/demo/sgi/gl/mixing.py
new file mode 100755
index 0000000..294e65f
--- /dev/null
+++ b/demo/sgi/gl/mixing.py
@@ -0,0 +1,116 @@
+#! /ufs/guido/bin/sgi/python
+
+# Use Gouraud shading to mix colors. Requires Z-buffer.
+# It changes the color assignments so fast that you see white.
+# Left button pauses, middle rotates the square. ESC to quit.
+# Experiment with a larger window (too slow) or smaller window (really white).
+
+from GL import *
+from gl import *
+import DEVICE
+from math import *
+
+#
+# tekenvlak : draw a square. with bgnpolygon
+#
+def tekenvlak (vc) :
+ bgnpolygon()
+ #vcarray (vc)
+ for i in vc :
+ c3f (i[1])
+ v3f (i[0])
+ endpolygon()
+
+#
+# tekendoos : draw a box
+#
+def tekendoos (col) :
+ v = [(-5.0,0.0,0.0),(0.0,5.0,0.0),(5.0,0.0,0.0),(0.0,-5.0,0.0)]
+ vc = [(v[0],col[0]),(v[1],col[1]),(v[2],col[2]),(v[3],col[1])]
+ tekenvlak (vc)
+
+#
+# initialize gl
+#
+def initgl () :
+ #
+ # open window
+ #
+ foreground ()
+ keepaspect (1, 1)
+ prefposition (100, 500, 100, 500)
+ w = winopen ('PYTHON RGB')
+ keepaspect (1, 1)
+ winconstraints()
+ #
+ # configure pipeline (2buf, GOURAUD and RGBmode)
+ #
+ doublebuffer ()
+ zbuffer (1)
+ shademodel (GOURAUD)
+ RGBmode ()
+ gconfig ()
+ #
+ # set viewing
+ #
+ perspective (900, 1, 1.0, 10.0)
+ polarview (10.0, 0, 0, 0)
+ #
+ # ask for the REDRAW and ESCKEY events
+ #
+ qdevice(DEVICE.MOUSE2)
+ qdevice(DEVICE.MOUSE3)
+ qdevice(DEVICE.REDRAW)
+ qdevice(DEVICE.ESCKEY)
+
+
+#
+# the color black
+#
+black = 0
+#
+# GoForIT : use 2buf to redraw the object 2n times. index i is used as
+# the (smoothly changing) rotation angle
+#
+def GoForIt(i) :
+ col = [(255.0,0.0,0.0), (0.0,255.0,0.0), (0.0,0.0,255.0)]
+ twist = 0
+ freeze = 1
+ while 1 :
+ if freeze <> 0 :
+ col[0],col[1],col[2] = col[1],col[2],col[0]
+ #
+ # clear z-buffer and clear background to light-blue
+ #
+ zclear()
+ cpack (black)
+ clear()
+ #
+ tekendoos (col)
+ #
+ swapbuffers()
+ #
+ if qtest() <> 0 :
+ dev, val = qread()
+ if dev = DEVICE.ESCKEY :
+ break
+ elif dev = DEVICE.REDRAW :
+ reshapeviewport ()
+ elif dev = DEVICE.MOUSE2 and val <> 0 :
+ twist = twist + 30
+ perspective (900, 1, 1.0, 10.0)
+ polarview (10.0, 0, 0, twist)
+ elif dev = DEVICE.MOUSE3 and val <> 0 :
+ freeze = 1 - freeze
+
+
+# the main program
+#
+def main () :
+ initgl ()
+ GoForIt (0)
+
+#
+# exec main
+#
+main ()
diff --git a/demo/sgi/gl/nurbs.py b/demo/sgi/gl/nurbs.py
new file mode 100755
index 0000000..ee48e23
--- /dev/null
+++ b/demo/sgi/gl/nurbs.py
@@ -0,0 +1,171 @@
+#! /ufs/guido/bin/sgi/python
+
+# Rotate a 3D surface created using NURBS.
+#
+# Press left mouse button to toggle surface trimming.
+# Press ESC to quit.
+#
+# See the GL manual for an explanation of NURBS.
+
+from gl import *
+from GL import *
+from DEVICE import *
+
+TRUE = 1
+FALSE = 0
+ORDER = 4
+
+idmat = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]
+
+surfknots = [-1, -1, -1, -1, 1, 1, 1, 1]
+
+def make_ctlpoints():
+ c = []
+ #
+ ci = []
+ ci.append(-2.5, -3.7, 1.0)
+ ci.append(-1.5, -3.7, 3.0)
+ ci.append(1.5, -3.7, -2.5)
+ ci.append(2.5, -3.7, -0.75)
+ c.append(ci)
+ #
+ ci = []
+ ci.append(-2.5, -2.0, 3.0)
+ ci.append(-1.5, -2.0, 4.0)
+ ci.append(1.5, -2.0, -3.0)
+ ci.append(2.5, -2.0, 0.0)
+ c.append(ci)
+ #
+ ci = []
+ ci.append(-2.5, 2.0, 1.0)
+ ci.append(-1.5, 2.0, 0.0)
+ ci.append(1.5, 2.0, -1.0)
+ ci.append(2.5, 2.0, 2.0)
+ c.append(ci)
+ #
+ ci = []
+ ci.append(-2.5, 2.7, 1.25)
+ ci.append(-1.5, 2.7, 0.1)
+ ci.append(1.5, 2.7, -0.6)
+ ci.append(2.5, 2.7, 0.2)
+ c.append(ci)
+ #
+ return c
+
+ctlpoints = make_ctlpoints()
+
+trimknots = [0., 0., 0., 1., 1., 2., 2., 3., 3., 4., 4., 4.]
+
+def make_trimpoints():
+ c = []
+ c.append(1.0, 0.0, 1.0)
+ c.append(1.0, 1.0, 1.0)
+ c.append(0.0, 2.0, 2.0)
+ c.append(-1.0, 1.0, 1.0)
+ c.append(-1.0, 0.0, 1.0)
+ c.append(-1.0, -1.0, 1.0)
+ c.append(0.0, -2.0, 2.0)
+ c.append(1.0, -1.0, 1.0)
+ c.append(1.0, 0.0, 1.0)
+ return c
+
+trimpoints = make_trimpoints()
+
+def main():
+ init_windows()
+ setup_queue()
+ make_lights()
+ init_view()
+ #
+ set_scene()
+ setnurbsproperty( N_ERRORCHECKING, 1.0 )
+ setnurbsproperty( N_PIXEL_TOLERANCE, 50.0 )
+ trim_flag = 0
+ draw_trim_surface(trim_flag)
+ #
+ while 1:
+ while qtest():
+ dev, val = qread()
+ if dev = ESCKEY:
+ return
+ elif dev = WINQUIT:
+ dglclose(-1) # this for DGL only
+ return
+ elif dev = REDRAW:
+ reshapeviewport()
+ set_scene()
+ draw_trim_surface(trim_flag)
+ elif dev = LEFTMOUSE:
+ if val:
+ trim_flag = (not trim_flag)
+ set_scene()
+ draw_trim_surface(trim_flag)
+
+def init_windows():
+ foreground()
+ #prefposition(0, 500, 0, 500)
+ wid = winopen('nurbs')
+ wintitle('NURBS Surface')
+ doublebuffer()
+ RGBmode()
+ gconfig()
+ lsetdepth(0x000, 0x7fffff)
+ zbuffer( TRUE )
+
+def setup_queue():
+ qdevice(ESCKEY)
+ qdevice(REDRAW)
+ qdevice(RIGHTMOUSE)
+ qdevice(WINQUIT)
+ qdevice(LEFTMOUSE) #trimming
+
+def init_view():
+ mmode(MPROJECTION)
+ ortho( -4., 4., -4., 4., -4., 4. )
+ #
+ mmode(MVIEWING)
+ loadmatrix(idmat)
+ #
+ lmbind(MATERIAL, 1)
+
+def set_scene():
+ lmbind(MATERIAL, 0)
+ RGBcolor(150,150,150)
+ lmbind(MATERIAL, 1)
+ clear()
+ zclear()
+ #
+ rotate( 100, 'y' )
+ rotate( 100, 'z' )
+
+def draw_trim_surface(trim_flag):
+ bgnsurface()
+ nurbssurface(surfknots, surfknots, ctlpoints, ORDER, ORDER, N_XYZ)
+ if trim_flag:
+ bgntrim()
+ nurbscurve(trimknots, trimpoints, ORDER-1, N_STW)
+ endtrim()
+ endsurface()
+ swapbuffers()
+
+def make_lights():
+ lmdef(DEFLMODEL,1,[])
+ lmdef(DEFLIGHT,1,[])
+ #
+ # define material #1
+ #
+ a = []
+ a = a + [EMISSION, 0.0, 0.0, 0.0]
+ a = a + [AMBIENT, 0.1, 0.1, 0.1]
+ a = a + [DIFFUSE, 0.6, 0.3, 0.3]
+ a = a + [SPECULAR, 0.0, 0.6, 0.0]
+ a = a + [SHININESS, 2.0]
+ a = a + [LMNULL]
+ lmdef(DEFMATERIAL, 1, a)
+ #
+ # turn on lighting
+ #
+ lmbind(LIGHT0, 1)
+ lmbind(LMODEL, 1)
+
+main()
diff --git a/demo/sgi/gl/zrgb.py b/demo/sgi/gl/zrgb.py
new file mode 100755
index 0000000..c3f934a
--- /dev/null
+++ b/demo/sgi/gl/zrgb.py
@@ -0,0 +1,169 @@
+#! /ufs/guido/bin/sgi/python
+
+# zrgb (Requires Z buffer.)
+#
+# This program demostrates zbuffering 3 intersecting RGB polygons while
+# in doublebuffer mode where, movement of the mouse with the LEFTMOUSE
+# button depressed will, rotate the 3 polygons. This is done by compound
+# rotations allowing continuous screen-oriented rotations.
+#
+# Press the "Esc" key to exit.
+
+from gl import *
+from GL import *
+from DEVICE import *
+
+
+objmat=[1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
+
+idmat=[1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
+
+def main() :
+ #
+ # old and new mouse position
+ #
+ #
+ mode = 0
+ omx = 0
+ mx = 0
+ omy = 0
+ my = 0
+ #
+ initialize ()
+ #
+ draw_scene (objmat)
+ #
+ while (1) :
+ #
+ dev, val = qread()
+ #
+ if dev = ESCKEY :
+ if val :
+ break
+ # exit when key is going up, not down
+ # this avoids the scenario where a window
+ # underneath this program's window
+ # would otherwise "eat up" the up-
+ # event of the Esc key being released
+ return
+ #
+ elif dev = REDRAW :
+ reshapeviewport()
+ draw_scene(objmat)
+ #
+ elif dev = LEFTMOUSE:
+ omx = mx
+ omy = my
+ if val :
+ mode = 1
+ else :
+ mode = 0
+ elif dev = MOUSEX :
+ omx = mx
+ mx = val
+ #print omx, mx
+ objmat = update_scene(objmat,mx,my,omx,omy,mode)
+ #
+ elif dev = MOUSEY :
+ omy = my
+ my = val
+ #print omy, my
+ objmat = update_scene(objmat,mx,my,omx,omy,mode)
+ #
+
+
+def initialize () :
+ #
+ foreground ()
+ keepaspect(5, 4)
+ w = winopen('Zbuffered RGB')
+ #
+ doublebuffer()
+ RGBmode()
+ gconfig()
+ zbuffer(1)
+ lsetdepth(0x0, 0x7FFFFF)
+ #
+ qdevice(ESCKEY)
+ qdevice(LEFTMOUSE)
+ qdevice(MOUSEX)
+ qdevice(MOUSEY)
+
+def update_scene (mat, mx, my, omx, omy, mode) :
+ #
+ if mode = 1 :
+ mat = orient(mat, mx, my, omx, omy)
+ draw_scene(mat)
+ return mat
+
+def orient (mat, mx, my, omx, omy) :
+ #
+ #
+ pushmatrix()
+ loadmatrix(idmat)
+ #
+ if mx - omx : rot (float (mx - omx), 'y')
+ if omy - my : rot (float (omy - my), 'x')
+ #
+ multmatrix(mat)
+ mat = getmatrix()
+ #
+ #
+ popmatrix()
+ #
+ return mat
+
+def draw_scene (mat) :
+ RGBcolor(40, 100, 200)
+ clear()
+ zclear()
+ #
+ perspective(400, 1.25, 30.0, 60.0)
+ translate(0.0, 0.0, -40.0)
+ multmatrix(mat)
+ #
+ # skews original view to show all polygons
+ #
+ rotate(-580, 'y')
+ draw_polys()
+ #
+ swapbuffers()
+
+polygon1 = [(-10.0,-10.0,0.0),(10.0,-10.0,0.0),(-10.0,10.0,0.0)]
+
+polygon2 = [(0.0,-10.0,-10.0),(0.0,-10.0,10.0),(0.0,5.0,-10.0)]
+
+polygon3 = [(-10.0,6.0,4.0),(-10.0,3.0,4.0),(4.0,-9.0,-10.0),(4.0,-6.0,-10.0)]
+
+def draw_polys():
+ bgnpolygon()
+ cpack(0x0)
+ v3f(polygon1[0])
+ cpack(0x007F7F7F)
+ v3f(polygon1[1])
+ cpack(0x00FFFFFF)
+ v3f(polygon1[2])
+ endpolygon()
+ #
+ bgnpolygon()
+ cpack(0x0000FFFF)
+ v3f(polygon2[0])
+ cpack(0x007FFF00)
+ v3f(polygon2[1])
+ cpack(0x00FF0000)
+ v3f(polygon2[2])
+ endpolygon()
+ #
+ bgnpolygon()
+ cpack(0x0000FFFF)
+ v3f(polygon3[0])
+ cpack(0x00FF00FF)
+ v3f(polygon3[1])
+ cpack(0x00FF0000)
+ v3f(polygon3[2])
+ cpack(0x00FF00FF)
+ v3f(polygon3[3])
+ endpolygon()
+
+
+main ()
diff --git a/demo/sgi/gl_panel/README b/demo/sgi/gl_panel/README
new file mode 100644
index 0000000..889a2cf
--- /dev/null
+++ b/demo/sgi/gl_panel/README
@@ -0,0 +1,23 @@
+This directory contains demos that use the Panel Library by NASA Ames.
+They only run on SGI machines and require the 'pnl' and 'gl' built-in
+modules. Each subdirectory contains one demo.
+
+apanel A trivial user interface to the audio capabilities of
+ the 4D/25 (Personal IRIS). Lets you record a sample and
+ play it back at different volumes. Requires the 'audio'
+ built-in module.
+
+flying A large demonstration that can display several
+ differently shaped objects through space. Control
+ panels let you manipulate light sources, material
+ properties and drawing modes.
+
+nurbs A demo of the capabilities of the GL 'nurbs' functions
+ that can display the control points. (It was intended
+ to let you move these as well, but there was a problem
+ with the mapping of mouse movements in a 3-D world.)
+
+twoview A demo of GL's transformation primitives. Two views on
+ a scene are given, and the position and orientation of a
+ viewer in one of the views can be changed through
+ various buttons and dials in a control panel.
diff --git a/demo/sgi/gl_panel/apanel/apanel.py b/demo/sgi/gl_panel/apanel/apanel.py
new file mode 100755
index 0000000..de9a710
--- /dev/null
+++ b/demo/sgi/gl_panel/apanel/apanel.py
@@ -0,0 +1,63 @@
+#! /ufs/guido/bin/sgi/python
+
+# A (too) trivial control panel to record a sound sample and play it back.
+# Requires the audio built-in module.
+# Requires the NASA AMES Panel Library.
+
+import sys
+
+import gl
+import panel
+
+panel.block(1)
+
+import audio
+
+def main():
+ gl.foreground()
+ gl.noport()
+ #gl.prefposition(700, 850, 950, 970)
+ wid = gl.winopen('audio demo')
+ #
+ panels = panel.defpanellist('apanel.s') # XXX
+ p = panels[0]
+ p.playbackbutton.back = p
+ p.recordbutton.back = p
+ p.sample = ''
+ #
+ def quit(a):
+ sys.exit(0)
+ #
+ p.quitbutton.downfunc = quit
+ #
+ def playback(a):
+ p = a.back
+ gain = int(255.0*p.outputgain.val)
+ a.val = 1.0
+ a.fixact()
+ panel.drawpanel()
+ audio.setoutgain(gain)
+ audio.write(p.sample)
+ audio.setoutgain(0)
+ a.val = 0.0
+ a.fixact()
+ #
+ p.playbackbutton.downfunc = playback
+ #
+ def record(a):
+ p = a.back
+ size = int(10.0 * 8192.0 * p.recordsize.val)
+ a.val = 1.0
+ a.fixact()
+ panel.drawpanel()
+ audio.setoutgain(0)
+ p.sample = audio.read(size)
+ a.val = 0.0
+ a.fixact()
+ #
+ p.recordbutton.downfunc = record
+ #
+ while 1:
+ act = panel.dopanel()
+
+main()
diff --git a/demo/sgi/gl_panel/apanel/apanel.s b/demo/sgi/gl_panel/apanel/apanel.s
new file mode 100644
index 0000000..7c94da2
--- /dev/null
+++ b/demo/sgi/gl_panel/apanel/apanel.s
@@ -0,0 +1,76 @@
+;;; This file was automatically generated by the panel editor.
+;;; If you read it into gnu emacs, it will automagically format itself.
+
+(panel (prop help creator:user-panel-help)
+(prop user-panel #t)
+(label "Audio Control Panel")
+(x 395)
+(y 69)
+(al (pnl_filled_vslider (name "outputgain")
+(prop help creator:user-act-help)
+(label "output gain")
+(x 6.5)
+(y 0.75)
+(w 0.4)
+(h 4.35)
+(val 0.329)
+(labeltype 13)
+(downfunc move-then-resize)
+)
+(pnl_frame (prop help creator:user-frame-help)
+(x 0.25)
+(y 2.75)
+(w 5.1)
+(h 2.3)
+(downfunc move-then-resize)
+(al (pnl_filled_hslider (name "recordsize")
+(prop help creator:user-act-help)
+(label "recording length")
+(x -0.75)
+(w 3.3)
+(h 0.4)
+(val 0.1)
+(labeltype 11)
+(downfunc move-then-resize)
+)
+(pnl_label (prop help creator:user-act-help)
+(label "(max 10 seconds)")
+(x -0.75)
+(y -0.75)
+(downfunc move-then-resize)
+)
+(pnl_wide_button (name "recordbutton")
+(prop help creator:user-act-help)
+(label "record from microphone...")
+(x -0.75)
+(y 0.75)
+(w 4.7)
+(downfunc move-then-resize)
+)
+)
+)
+(pnl_wide_button (name "playbackbutton")
+(prop help creator:user-act-help)
+(label "playback to speaker")
+(x 0.25)
+(y 2)
+(w 5.15)
+(downfunc move-then-resize)
+)
+(pnl_wide_button (name "quitbutton")
+(prop help creator:user-act-help)
+(label "quit")
+(x 0.25)
+(y 0.25)
+(w 1.75)
+(downfunc move-then-resize)
+)
+)
+)
+;;; Local Variables:
+;;; mode: scheme
+;;; eval: (save-excursion (goto-char (point-min)) (kill-line 3))
+;;; eval: (save-excursion (goto-char (point-min)) (replace-regexp "[ \n]*)" ")"))
+;;; eval: (indent-region (point-min) (point-max) nil)
+;;; eval: (progn (kill-line -3) (delete-backward-char 1) (save-buffer))
+;;; End:
diff --git a/demo/sgi/gl_panel/flying/data.py b/demo/sgi/gl_panel/flying/data.py
new file mode 100644
index 0000000..bfc934a
--- /dev/null
+++ b/demo/sgi/gl_panel/flying/data.py
@@ -0,0 +1,42 @@
+
+# two string constants
+ARROW = '-> '
+NULL = ''
+ZERO = 0
+ONE = 1
+
+#
+# the color light-blue
+#
+lightblue = (43,169,255)
+
+
+#
+# a couple of rotation, translation, scaling vectors
+#
+rts1 = [[3.0,3.1,2.0],[2.2, 1.2, 2.0], [0.8,0.8,0.8]]
+rts2 = [[3.2,2.6,1.8],[-1.9, 1.2, 1.6], [0.3,0.3,1.0]]
+rts3 = [[2.2,3.3,1.4], [-1.0, 1.2,-1.5], [0.6,0.6, 0.6]]
+rts4 = [[4.2,2.1,3.2],[1.2, 1.3, 1.0],[0.5,0.5,0.8]]
+rts5 = [[1.2,3.3,2.4], [-2.0, 1.4,-2.1], [0.8, 0.8, 0.2]]
+rts6 = [[3.2,3.6,2.4], [1.1, 1.6, 2.5], [0.8,0.3,0.1]]
+rts7 = [[2.3,2.7,3.3], [1.1, 2.3, 1.7], [0.6,0.6,0.5]]
+rts8 = [[4.2,2.1,3.2], [1.2, 1.3, 0.0], [0.5,0.5,0.5]]
+#
+rts90 = [[4.2,2.1,3.2], [2.0, 0.0, 0.9], [0.3,0.3,1.0]]
+rts91 = [[4.2,2.1,3.2], [-2.0, 0.0, 0.9], [0.3,0.3,1.0]]
+rts92 = [[4.2,2.1,3.2], [0.0, 2.0, 0.9], [0.3,0.3,1.0]]
+rts93 = [[4.2,2.1,3.2], [0.0, -2.0, 0.9], [0.3,0.3,1.0]]
+rts10 = [[4.2,2.1,3.2], [0.0, 0.0, 0.0], [2.2,2.2,0.2]]
+
+#
+# (composite) object definitions
+#
+o1 = [['sphere',rts1, 1]]
+o2 = [['cylinder', rts2, 4]]
+o3 = [['cube', rts3, 3]]
+o4 = [['cone', rts4, 2], ['sphere', rts8, 9]]
+o5 = [['sphere', rts5, 5]]
+o6 = [['cube', rts6, 6]]
+o7 = [['pyramid', rts7, 8]]
+o8 = [['cube', rts10, 9], ['cylinder', rts90, 2], ['cylinder', rts91, 2], ['cylinder', rts92, 2], ['cylinder', rts93, 2]]
diff --git a/demo/sgi/gl_panel/flying/flying.py b/demo/sgi/gl_panel/flying/flying.py
new file mode 100755
index 0000000..e6fd823
--- /dev/null
+++ b/demo/sgi/gl_panel/flying/flying.py
@@ -0,0 +1,375 @@
+#! /ufs/guido/bin/sgi/python
+
+from gl import *
+from objdict import *
+from GL import *
+import DEVICE, time
+import objectdef, light, panel, material
+
+def fixmatact (p) :
+ p.diffR.fixact ()
+ p.diffG.fixact ()
+ p.diffB.fixact ()
+ p.specR.fixact ()
+ p.specG.fixact ()
+ p.specB.fixact ()
+ p.shine.fixact ()
+
+def fixlichtact (p) :
+ p.R.fixact ()
+ p.G.fixact ()
+ p.B.fixact ()
+ p.X.fixact ()
+ p.Y.fixact ()
+ p.Z.fixact ()
+ p.local.fixact ()
+
+def cbsetlight (a) :
+ p = a.back
+ setlight (p, a.label)
+
+def cbsetmaterial (a) :
+ p = a.back
+ setmaterial (p, a.label)
+
+mater = [0]
+licht = [0]
+
+def setmaterial (p, mname) :
+ #
+ mater [0:1] = [material.materdict [mname]]
+ #
+ p.diffR.val = mater [0][1]
+ p.diffG.val = mater [0][2]
+ p.diffB.val = mater [0][3]
+ #