diff options
author | Guido van Rossum <guido@python.org> | 1995-01-30 11:53:55 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1995-01-30 11:53:55 (GMT) |
commit | 17448e24081eb713ac00d7bcb681f4f0d8abfcbf (patch) | |
tree | 4f9d6768ef326173e1141b1a92af63247a42b13a /Mac/Lib | |
parent | 80ffd6683ca7b06ed743c629459b06b07defbfb3 (diff) | |
download | cpython-17448e24081eb713ac00d7bcb681f4f0d8abfcbf.zip cpython-17448e24081eb713ac00d7bcb681f4f0d8abfcbf.tar.gz cpython-17448e24081eb713ac00d7bcb681f4f0d8abfcbf.tar.bz2 |
Committed a more or less working version.
Diffstat (limited to 'Mac/Lib')
-rw-r--r-- | Mac/Lib/Audio_mac.py | 108 | ||||
-rw-r--r-- | Mac/Lib/audiodev.py | 241 | ||||
-rw-r--r-- | Mac/Lib/test/aete.py | 402 | ||||
-rw-r--r-- | Mac/Lib/test/tctl.py | 17 | ||||
-rw-r--r-- | Mac/Lib/test/tdlg.py | 15 | ||||
-rw-r--r-- | Mac/Lib/test/tmenu.py | 60 | ||||
-rw-r--r-- | Mac/Lib/test/tsnd.py | 18 | ||||
-rw-r--r-- | Mac/Lib/test/twin.py | 9 | ||||
-rw-r--r-- | Mac/Lib/toolbox/AppleEvents.py | 103 | ||||
-rw-r--r-- | Mac/Lib/toolbox/Controls.py | 41 | ||||
-rw-r--r-- | Mac/Lib/toolbox/Dialogs.py | 20 | ||||
-rw-r--r-- | Mac/Lib/toolbox/Events.py | 49 | ||||
-rw-r--r-- | Mac/Lib/toolbox/Menus.py | 12 | ||||
-rw-r--r-- | Mac/Lib/toolbox/Resources.py | 12 | ||||
-rw-r--r-- | Mac/Lib/toolbox/Sound.py | 101 | ||||
-rw-r--r-- | Mac/Lib/toolbox/Windows.py | 41 | ||||
-rw-r--r-- | Mac/Lib/toolbox/aetools.py | 296 |
17 files changed, 1545 insertions, 0 deletions
diff --git a/Mac/Lib/Audio_mac.py b/Mac/Lib/Audio_mac.py new file mode 100644 index 0000000..373f16a --- /dev/null +++ b/Mac/Lib/Audio_mac.py @@ -0,0 +1,108 @@ +QSIZE = 100000 + +class Play_Audio_mac: + + def __init__(self): + self._chan = None + self._qsize = QSIZE + self._outrate = 22254 + self._sampwidth = 1 + self._nchannels = 1 + self._gc = [] + + def __del__(self): + self.stop() + + def wait(self): + import time + while self.getfilled(): + time.sleep(0.1) + self._chan = None + self._gc = [] + + def stop(self, quietNow = 1): + ##chan = self._chan + self._chan = None + ##chan.SndDisposeChannel(1) + self._gc = [] + + def setoutrate(self, outrate): + self._outrate = outrate + + def setsampwidth(self, sampwidth): + self._sampwidth = sampwidth + + def setnchannels(self, nchannels): + self._nchannels = nchannels + + def writeframes(self, data): + import time + from Sound import * + import struct + if not self._chan: + import Snd + self._chan = Snd.SndNewChannel(5, 0, self._callback) + nframes = len(data) / self._nchannels / self._sampwidth + if len(data) != nframes * self._nchannels * self._sampwidth: + raise ValueError, 'data is not a whole number of frames' + while self._gc and \ + self.getfilled() + nframes > \ + self._qsize / self._nchannels / self._sampwidth: + time.sleep(0.1) + if self._sampwidth == 1: + import audioop + data = audioop.add(data, '\x80'*len(data), 1) + h1 = struct.pack('llhhllbbl', + id(data)+12, + self._nchannels, + self._outrate, 0, + 0, + 0, + extSH, + 60, + nframes) + h2 = 22*'\0' + h3 = struct.pack('hhlll', + self._sampwidth*8, + 0, + 0, + 0, + 0) + header = h1+h2+h3 + self._gc.append((header, data)) + self._chan.SndDoCommand((bufferCmd, 0, header), 0) + self._chan.SndDoCommand((callBackCmd, 0, 0), 0) + + def _callback(self, *args): + del self._gc[0] + + def getfilled(self): + filled = 0 + for header, data in self._gc: + filled = filled + len(data) + return filled / self._nchannels / self._sampwidth + + def getfillable(self): + return self._qsize - self.getfilled() + + def ulaw2lin(self, data): + import audioop + return audioop.ulaw2lin(data, 2) + +def test(fn = 'f:just samples:just.aif'): + import aifc + af = aifc.open(fn, 'r') + print af.getparams() + p = Play_Audio_mac() + p.setoutrate(af.getframerate()) + p.setsampwidth(af.getsampwidth()) + p.setnchannels(af.getnchannels()) + BUFSIZ = 10000 + while 1: + data = af.readframes(BUFSIZ) + if not data: break + p.writeframes(data) + p.wait() + +if __name__ == '__main__': + test() diff --git a/Mac/Lib/audiodev.py b/Mac/Lib/audiodev.py new file mode 100644 index 0000000..adfeb96 --- /dev/null +++ b/Mac/Lib/audiodev.py @@ -0,0 +1,241 @@ +error = 'audiodev.error' + +class Play_Audio_sgi: + # Private instance variables + access frameratelist, nchannelslist, sampwidthlist, oldparams, \ + params, config, inited_outrate, inited_width, \ + inited_nchannels, port, converter, classinited: private + + classinited = 0 + frameratelist = nchannelslist = sampwidthlist = None + + def initclass(self): + import AL + Play_Audio_sgi.frameratelist = [ + (48000, AL.RATE_48000), + (44100, AL.RATE_44100), + (32000, AL.RATE_32000), + (22050, AL.RATE_22050), + (16000, AL.RATE_16000), + (11025, AL.RATE_11025), + ( 8000, AL.RATE_8000), + ] + Play_Audio_sgi.nchannelslist = [ + (1, AL.MONO), + (2, AL.STEREO), + ] + Play_Audio_sgi.sampwidthlist = [ + (1, AL.SAMPLE_8), + (2, AL.SAMPLE_16), + (3, AL.SAMPLE_24), + ] + Play_Audio_sgi.classinited = 1 + + def __init__(self): + import al, AL + if not self.classinited: + self.initclass() + self.oldparams = [] + self.params = [AL.OUTPUT_RATE, 0] + self.config = al.newconfig() + self.inited_outrate = 0 + self.inited_width = 0 + self.inited_nchannels = 0 + self.converter = None + self.port = None + return + + def __del__(self): + if self.port: + self.stop() + if self.oldparams: + import al, AL + al.setparams(AL.DEFAULT_DEVICE, self.oldparams) + self.oldparams = [] + + def wait(self): + if not self.port: + return + import time + while self.port.getfilled() > 0: + time.sleep(0.1) + self.stop() + + def stop(self): + if self.port: + self.port.closeport() + self.port = None + if self.oldparams: + import al, AL + al.setparams(AL.DEFAULT_DEVICE, self.oldparams) + self.oldparams = [] + + def setoutrate(self, rate): + for (raw, cooked) in self.frameratelist: + if rate == raw: + self.params[1] = cooked + self.inited_outrate = 1 + break + else: + raise error, 'bad output rate' + + def setsampwidth(self, width): + for (raw, cooked) in self.sampwidthlist: + if width == raw: + self.config.setwidth(cooked) + self.inited_width = 1 + break + else: + if width == 0: + import AL + self.inited_width = 0 + self.config.setwidth(AL.SAMPLE_16) + self.converter = self.ulaw2lin + else: + raise error, 'bad sample width' + + def setnchannels(self, nchannels): + for (raw, cooked) in self.nchannelslist: + if nchannels == raw: + self.config.setchannels(cooked) + self.inited_nchannels = 1 + break + else: + raise error, 'bad # of channels' + + def writeframes(self, data): + if not (self.inited_outrate and self.inited_nchannels): + raise error, 'params not specified' + if not self.port: + import al, AL + self.port = al.openport('Python', 'w', self.config) + self.oldparams = self.params[:] + al.getparams(AL.DEFAULT_DEVICE, self.oldparams) + al.setparams(AL.DEFAULT_DEVICE, self.params) + if self.converter: + data = self.converter(data) + self.port.writesamps(data) + + def getfilled(self): + if self.port: + return self.port.getfilled() + else: + return 0 + + def getfillable(self): + if self.port: + return self.port.getfillable() + else: + return self.config.getqueuesize() + + # private methods + access *: private + + def ulaw2lin(self, data): + import audioop + return audioop.ulaw2lin(data, 2) + +class Play_Audio_sun: + access outrate, sampwidth, nchannels, inited_outrate, inited_width, \ + inited_nchannels, converter: private + + def __init__(self): + self.outrate = 0 + self.sampwidth = 0 + self.nchannels = 0 + self.inited_outrate = 0 + self.inited_width = 0 + self.inited_nchannels = 0 + self.converter = None + self.port = None + return + + def __del__(self): + self.stop() + + def setoutrate(self, rate): + self.outrate = rate + self.inited_outrate = 1 + + def setsampwidth(self, width): + self.sampwidth = width + self.inited_width = 1 + + def setnchannels(self, nchannels): + self.nchannels = nchannels + self.inited_nchannels = 1 + + def writeframes(self, data): + if not (self.inited_outrate and self.inited_width and self.inited_nchannels): + raise error, 'params not specified' + if not self.port: + import sunaudiodev, SUNAUDIODEV + self.port = sunaudiodev.open('w') + info = self.port.getinfo() + info.o_sample_rate = self.outrate + info.o_channels = self.nchannels + if self.sampwidth == 0: + info.o_precision = 8 + self.o_encoding = ENCODING_ULAW + else: + info.o_precision = 8 * self.sampwidth + info.o_encoding = SUNAUDIODEV.ENCODING_LINEAR + self.port.setinfo(info) + if self.converter: + data = self.converter(data) + self.port.write(data) + + def wait(self): + if not self.port: + return + self.port.drain() + self.stop() + + def stop(self): + if self.port: + self.port.flush() + self.port.close() + self.port = None + + def getfilled(self): + if self.port: + return self.port.obufcount() + else: + return 0 + + def getfillable(self): + return BUFFERSIZE - self.getfilled() + +def AudioDev(): + try: + import al + return Play_Audio_sgi() + except ImportError: + try: + import sunaudiodev + return Play_Audio_sun() + except ImportError: + try: + import Audio_mac + return Audio_mac.Play_Audio_mac() + except ImportError: + raise error, 'no audio device' + +def test(fn = 'f:just samples:just.aif'): + import aifc + af = aifc.open(fn, 'r') + print fn, af.getparams() + p = AudioDev() + p.setoutrate(af.getframerate()) + p.setsampwidth(af.getsampwidth()) + p.setnchannels(af.getnchannels()) + BUFSIZ = af.getframerate()/af.getsampwidth()/af.getnchannels() + while 1: + data = af.readframes(BUFSIZ) + if not data: break + print len(data) + p.writeframes(data) + p.wait() + +if __name__ == '__main__': + test() diff --git a/Mac/Lib/test/aete.py b/Mac/Lib/test/aete.py new file mode 100644 index 0000000..5a91d89 --- /dev/null +++ b/Mac/Lib/test/aete.py @@ -0,0 +1,402 @@ +# Look for scriptable applications -- that is, applications with an 'aete' resource +# Also contains (partially) reverse engineered 'aete' resource decoding + +import MacOS +import os +import string +import sys +import types +import StringIO + +from Res import * + +def main(): + filename = raw_input("Listing file? (default stdout): ") + redirect(filename, realmain) + +def redirect(filename, func, *args): + f = filename and open(filename, 'w') + save_stdout = sys.stdout + try: + if f: sys.stdout = f + return apply(func, args) + finally: + sys.stdout = save_stdout + if f: f.close() + +def realmain(): + #list('C:Tao AppleScript:Finder Liaison:Finder Liaison 1.0') + #list('C:Internet:Eudora 1.4.2:Eudora1.4.2') + list('E:Excel 4.0:Microsoft Excel') + #list('C:Internet:Netscape 1.0N:Netscape 1.0N') + #find('C:') + #find('D:') + #find('E:') + #find('F:') + +def find(dir, maxlevel = 5): + hits = [] + cur = CurResFile() + names = os.listdir(dir) + tuples = map(lambda x: (os.path.normcase(x), x), names) + tuples.sort() + names = map(lambda (x, y): y, tuples) + for name in names: + if name in (os.curdir, os.pardir): continue + fullname = os.path.join(dir, name) + if os.path.islink(fullname): + pass + if os.path.isdir(fullname): + if maxlevel > 0: + sys.stderr.write(" %s\n" % `fullname`) + hits = hits + find(fullname, maxlevel-1) + else: + ctor, type = MacOS.GetCreatorAndType(fullname) + if type == 'APPL': + sys.stderr.write(" %s\n" % `fullname`) + try: + rf = OpenRFPerm(fullname, 0, '\1') + except MacOS.Error, msg: + print "Error:", fullname, msg + continue + UseResFile(rf) + n = Count1Resources('aete') + if rf <> cur: + CloseResFile(rf) + UseResFile(cur) + if n > 1: + hits.append(fullname) + sys.stderr.write("YES! %d in %s\n" % (n, `fullname`)) + list(fullname) + return hits + +def list(fullname): + cur = CurResFile() + rf = OpenRFPerm(fullname, 0, '\1') + try: + UseResFile(rf) + resources = [] + for i in range(Count1Resources('aete')): + res = Get1IndResource('aete', 1+i) + resources.append(res) + for i in range(Count1Resources('aeut')): + res = Get1IndResource('aeut', 1+i) + resources.append(res) + print "\nLISTING aete+aeut RESOURCE IN", `fullname` + for res in resources: + print res.GetResInfo() + data = res.data + try: + aete = decode(data) + showaete(aete) + f = StringIO.StringIO() + putaete(f, aete) + newdata = f.getvalue() + if len(newdata) == len(data): + if newdata == data: + print "putaete created identical data" + else: + newaete = decode(newdata) + if newaete == aete: + print "putaete created equivalent data" + else: + print "putaete failed the test:" + showaete(newaete) + else: + print "putaete created different data:" + print `newdata` + except: + import traceback + traceback.print_exc() + sys.stdout.flush() + finally: + if rf <> cur: + CloseResFile(rf) + UseResFile(cur) + +def decode(data): + f = StringIO.StringIO(data) + aete = generic(getaete, f) + aete = simplify(aete) + processed = f.tell() + unprocessed = len(f.read()) + total = f.tell() + if unprocessed: + sys.stderr.write("%d processed + %d unprocessed = %d total\n" % + (processed, unprocessed, total)) + return aete + +def simplify(item): + if type(item) is types.ListType: + return map(simplify, item) + elif type(item) == types.TupleType and len(item) == 2: + return simplify(item[1]) + else: + return item + + +# Here follows the aete resource decoder. +# It is presented bottom-up instead of top-down because there are direct +# references to the lower-level part-decoders from the high-level part-decoders. + +def getword(f, *args): + getalign(f) + s = f.read(2) + if len(s) < 2: + raise EOFError, 'in getword' + str(args) + return (ord(s[0])<<8) | ord(s[1]) + +def getlong(f, *args): + getalign(f) + s = f.read(4) + if len(s) < 4: + raise EOFError, 'in getlong' + str(args) + return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3]) + +def getostype(f, *args): + getalign(f) + s = f.read(4) + if len(s) < 4: + raise EOFError, 'in getostype' + str(args) + return s + +def getpstr(f, *args): + c = f.read(1) + if len(c) < 1: + raise EOFError, 'in getpstr[1]' + str(args) + nbytes = ord(c) + if nbytes == 0: return '' + s = f.read(nbytes) + if len(s) < nbytes: + raise EOFError, 'in getpstr[2]' + str(args) + return s + +def getalign(f): + if f.tell() & 1: + c = f.read(1) + ##if c <> '\0': + ## print 'align:', `c` + +def getlist(f, description, getitem): + count = getword(f) + list = [] + for i in range(count): + getalign(f) + list.append(generic(getitem, f)) + return list + +def alt_generic(what, f, *args): + print "generic", `what`, args + res = vageneric(what, f, args) + print '->', `res` + return res + +def generic(what, f, *args): + if type(what) == types.FunctionType: + return apply(what, (f,) + args) + if type(what) == types.ListType: + record = [] + for thing in what: + item = apply(generic, thing[:1] + (f,) + thing[1:]) + record.append((thing[1], item)) + return record + return "BAD GENERIC ARGS: %s" % `what` + +getdata = [(getostype, "type"), (getpstr, "description"), (getword, "flags")] +getoptarg = [(getpstr, "name"), (getostype, "keyword"), (getdata, "what")] +getcommand = [(getpstr, "name"), (getpstr, "description"), + (getostype, "suite code"), (getostype, "command code"), + (getdata, "returns"), + (getdata, "accepts"), + (getlist, "optional arguments", getoptarg)] +getprop = [(getpstr, "name"), (getostype, "code"), (getdata, "what")] +getelem = [(getostype, "type"), (getlist, "accessibility", getostype)] +getclass = [(getpstr, "name"), (getostype, "class code"), (getpstr, "description"), + (getlist, "properties", getprop), (getlist, "elements", getelem)] +getenumitem = [(getpstr, "name"), (getostype, "value"), (getpstr, "description")] +getenum = [(getostype, "enumtype"), (getlist, "enumitem", getenumitem)] +getsuite = [(getpstr, "name"), (getpstr, "description"), (getostype, "code"), + (getword, "flags1"), (getword, "flags2"), + (getlist, "commands", getcommand), + (getlist, "classes", getclass), + (getword, "count???"), (getlist, "enums", getenum)] +getaete = [(getword, "skip1"), (getword, "skip2"), (getword, "skip3"), + (getlist, "suites", getsuite)] + + +# Display 'aete' resources in a friendly manner. +# This one's done top-down again... + +def showaete(aete): + [flags1, flags2, flags3, suites] = aete + print "\nGlobal flags: x%x, x%x, x%x\n" % (flags1, flags2, flags3) + for suite in suites: + showsuite(suite) + +def showsuite(suite): + [name, desc, code, flags1, flags2, commands, classes, skip1, enums] = suite + print "\nSuite %s -- %s (%s)" % (`name`, `desc`, `code`) + for command in commands: + showcommand(command) + for classe in classes: + showclass(classe) + for enum in enums: + showenum(enum) + +def showcommand(command): + [name, desc, code, subcode, returns, accepts, arguments] = command + print "\n Command %s -- %s (%s, %s)" % (`name`, `desc`, `code`, `subcode`) + print " returns", showdata(returns) + print " accepts", showdata(accepts) + for arg in arguments: + showargument(arg) + +def showargument(arg): + [name, keyword, what] = arg + print " %s (%s)" % (name, `keyword`), showdata(what) + +def showclass(classe): + [name, code, desc, properties, elements] = classe + print "\n Class %s (%s) -- %s" % (`name`, `code`, `desc`) + for prop in properties: + showproperty(prop) + for elem in elements: + showelement(elem) + +def showproperty(prop): + [name, code, what] = prop + print " property %s (%s)" % (name, code), showdata(what) + +def showelement(elem): + [code, accessibility] = elem + print " element %s" % `code`, "as", accessibility + +def showenum(enum): + [code, items] = enum + print "\n Enum %s" % `code` + for item in items: + showitem(item) + +def showitem(item): + [name, code, desc] = item + print " %s (%s) -- %s" % (`name`, `code`, `desc`) + +def showdata(data): + [type, description, flags] = data + return "%s -- %s %s" % (`type`, `description`, showdataflags(flags)) + +dataflagdict = {15: "optional", 14: "list", 13: "enum", 12: "writable"} +def showdataflags(flags): + bits = [] + for i in range(16): + if flags & (1<<i): + if i in dataflagdict.keys(): + bits.append(dataflagdict[i]) + else: + bits.append(`i`) + return '[%s]' % string.join(bits) + + +# Write an 'aete' resource. +# Closedly modelled after showaete()... + +def putaete(f, aete): + [flags1, flags2, flags3, suites] = aete + putword(f, flags1) + putword(f, flags2) + putword(f, flags3) + putlist(f, suites, putsuite) + +def putsuite(f, suite): + [name, desc, code, flags1, flags2, commands, classes, skip1, enums] = suite + putpstr(f, name) + putpstr(f, desc) + putostype(f, code) + putword(f, flags1) + putword(f, flags2) + putlist(f, commands, putcommand) + putlist(f, classes, putclass) + putword(f, skip1) + putlist(f, enums, putenum) + +def putcommand(f, command): + [name, desc, code, subcode, returns, accepts, arguments] = command + putpstr(f, name) + putpstr(f, desc) + putostype(f, code) + putostype(f, subcode) + putdata(f, returns) + putdata(f, accepts) + putlist(f, arguments, putargument) + +def putargument(f, arg): + [name, keyword, what] = arg + putpstr(f, name) + putostype(f, keyword) + putdata(f, what) + +def putclass(f, classe): + [name, code, desc, properties, elements] = classe + putpstr(f, name) + putostype(f, code) + putpstr(f, desc) + putlist(f, properties, putproperty) + putlist(f, elements, putelement) + +putproperty = putargument + +def putelement(f, elem): + [code, parts] = elem + putostype(f, code) + putlist(f, parts, putostype) + +def putenum(f, enum): + [code, items] = enum + putostype(f, code) + putlist(f, items, putitem) + +def putitem(f, item): + [name, code, desc] = item + putpstr(f, name) + putostype(f, code) + putpstr(f, desc) + +def putdata(f, data): + [type, description, flags] = data + putostype(f, type) + putpstr(f, description) + putword(f, flags) + +def putlist(f, list, putitem): + putword(f, len(list)) + for item in list: + putalign(f) + putitem(f, item) + +def putalign(f): + if f.tell() & 1: + f.write('\0') + +def putword(f, value): + putalign(f) + f.write(chr((value>>8)&0xff)) + f.write(chr(value&0xff)) + +def putostype(f, value): + putalign(f) + if type(value) != types.StringType or len(value) != 4: + raise TypeError, "ostype must be 4-char string" + f.write(value) + +def putpstr(f, value): + if type(value) != types.StringType or len(value) > 255: + raise TypeError, "pstr must be string <= 255 chars" + f.write(chr(len(value)) + value) + + +# Call the main program + +if __name__ == '__main__': + main() +else: + realmain() diff --git a/Mac/Lib/test/tctl.py b/Mac/Lib/test/tctl.py new file mode 100644 index 0000000..862eeb5 --- /dev/null +++ b/Mac/Lib/test/tctl.py @@ -0,0 +1,17 @@ +# play with controls + +from Dlg import * +from Ctl import * +from Win import * +from Evt import * +import time + +def main(): + r = (40, 40, 400, 300) + w = NewWindow(r, "The Spanish Inquisition", 1, 0, -1, 1, 0x55555555) + w.DrawGrowIcon() + r = (40, 40, 100, 60) + c = NewControl(w, r, "SPAM!", 1, 0, 0, 1, 0, 0) + + +main() diff --git a/Mac/Lib/test/tdlg.py b/Mac/Lib/test/tdlg.py new file mode 100644 index 0000000..f234a70 --- /dev/null +++ b/Mac/Lib/test/tdlg.py @@ -0,0 +1,15 @@ +# This program requires that a DLOG resource with ID=128 exists. +# You can make one with ResEdit if necessary. + +from Res import * +from Dlg import * + +ires = 128 + +def filter(*args): print 'filter:', args + +d = GetNewDialog(ires, -1) +while 1: + n = ModalDialog(filter) + print 'item:', n + if n == 1: break diff --git a/Mac/Lib/test/tmenu.py b/Mac/Lib/test/tmenu.py new file mode 100644 index 0000000..1b156d7 --- /dev/null +++ b/Mac/Lib/test/tmenu.py @@ -0,0 +1,60 @@ +# Create hierarchical menus for some volumes. + +import os +from Menu import * + +# Since we can't (yet) list the mounted volumes, here's a list of some: +my_volumes = ['C:', 'D:', 'E:', 'F:'] + +def main(): + global oldbar + oldbar = GetMenuBar() + ClearMenuBar() + makevolmenus(my_volumes) + DrawMenuBar() + +def reset(): + oldbar.SetMenuBar() + DrawMenuBar() + +id = 1 +def nextid(): + global id + nid = id + id = id+1 + return nid + +def makevolmenus(volumes): + for vol in volumes: + makevolmenu(vol) + +def makevolmenu(vol): + menu = NewMenu(nextid(), vol) + adddirectory(menu, vol) + menu.InsertMenu(0) + +def adddirectory(menu, dir, maxdepth = 1): + print "adddirectory:", `dir`, maxdepth + files = os.listdir(dir) + item = 0 + for file in files: + item = item+1 + menu.AppendMenu('x') # add a dummy string + menu.SetItem(item, file) # set the actual text + fullname = os.path.join(dir, file) + if os.path.isdir(fullname): + menu.SetItem(item, ':' + file + ':') # append colons + if maxdepth > 0: + id = nextid() + submenu = NewMenu(id, fullname) + adddirectory(submenu, fullname, maxdepth-1) + submenu.InsertMenu(-1) + # If the 'Cmd' is 0x1B, then the 'Mark' is the submenu id + menu.SetItemMark(item, id) + menu.SetItemCmd(item, 0x1B) + if not files: + menu.AppendMenu(':') # dummy item to make it selectable + return menu + +if __name__ == '__main__': + main() diff --git a/Mac/Lib/test/tsnd.py b/Mac/Lib/test/tsnd.py new file mode 100644 index 0000000..ac347cb --- /dev/null +++ b/Mac/Lib/test/tsnd.py @@ -0,0 +1,18 @@ +# Show off SndPlay (and some resource manager functions). +# Get a list of all 'snd ' resources in the system and play them all. + +from Res import * +from Snd import * + +ch = SndNewChannel(0, 0, None) +print "Channel:", ch + +type = 'snd ' + +for i in range(CountResources(type)): + r = GetIndResource(type, i+1) + print r.GetResInfo(), r.size + if r.GetResInfo()[0] == 1: + print "Skipping simple beep" + continue + ch.SndPlay(r, 0) diff --git a/Mac/Lib/test/twin.py b/Mac/Lib/test/twin.py new file mode 100644 index 0000000..0904d32 --- /dev/null +++ b/Mac/Lib/test/twin.py @@ -0,0 +1,9 @@ +# Test Win module + +from Win import * + +r = (40, 40, 400, 300) +w = NewWindow(r, "Hello world", 1, 0, -1, 1, 0x55555555) +w.DrawGrowIcon() +import time +time.sleep(10) diff --git a/Mac/Lib/toolbox/AppleEvents.py b/Mac/Lib/toolbox/AppleEvents.py new file mode 100644 index 0000000..b3780d0 --- /dev/null +++ b/Mac/Lib/toolbox/AppleEvents.py @@ -0,0 +1,103 @@ +# Generated from 'D:Development:THINK C:Mac #includes:Apple #includes:AppleEvents.h' +typeBoolean = 'bool' +typeChar = 'TEXT' +typeSMInt = 'shor' +typeInteger = 'long' +typeSMFloat = 'sing' +typeFloat = 'doub' +typeLongInteger = 'long' +typeShortInteger = 'shor' +typeLongFloat = 'doub' +typeShortFloat = 'sing' +typeExtended = 'exte' +typeComp = 'comp' +typeMagnitude = 'magn' +typeAEList = 'list' +typeAERecord = 'reco' +typeAppleEvent = 'aevt' +typeTrue = 'true' +typeFalse = 'fals' +typeAlias = 'alis' +typeEnumerated = 'enum' +typeType = 'type' +typeAppParameters = 'appa' +typeProperty = 'prop' +typeFSS = 'fss ' +typeKeyword = 'keyw' +typeSectionH = 'sect' +typeWildCard = '****' +typeApplSignature = 'sign' +typeSessionID = 'ssid' +typeTargetID = 'targ' +typeProcessSerialNumber = 'psn ' +typeNull = 'null' +keyDirectObject = '----' +keyErrorNumber = 'errn' +keyErrorString = 'errs' +keyProcessSerialNumber = 'psn ' +keyTransactionIDAttr = 'tran' +keyReturnIDAttr = 'rtid' +keyEventClassAttr = 'evcl' +keyEventIDAttr = 'evid' +keyAddressAttr = 'addr' +keyOptionalKeywordAttr = 'optk' +keyTimeoutAttr = 'timo' +keyInteractLevelAttr = 'inte' +keyEventSourceAttr = 'esrc' +keyMissedKeywordAttr = 'miss' +keyOriginalAddressAttr = 'from' +keyPreDispatch = 'phac' +keySelectProc = 'selh' +keyAERecorderCount = 'recr' +keyAEVersion = 'vers' +kCoreEventClass = 'aevt' +kAEOpenApplication = 'oapp' +kAEOpenDocuments = 'odoc' +kAEPrintDocuments = 'pdoc' +kAEQuitApplication = 'quit' +kAEAnswer = 'ansr' +kAEApplicationDied = 'obit' +kAENoReply = 0x00000001 +kAEQueueReply = 0x00000002 +kAEWaitReply = 0x00000003 +kAENeverInteract = 0x00000010 +kAECanInteract = 0x00000020 +kAEAlwaysInteract = 0x00000030 +kAECanSwitchLayer = 0x00000040 +kAEDontReconnect = 0x00000080 +kAEDontRecord = 0x00001000 +kAEDontExecute = 0x00002000 +kAENormalPriority = 0x00000000 +kAEStartRecording = 'reca' +kAEStopRecording = 'recc' +kAENotifyStartRecording = 'rec1' +kAENotifyStopRecording = 'rec0' +kAENotifyRecording = 'recr' +kAutoGenerateReturnID = -1 +kAnyTransactionID = 0 +kAEDefaultTimeout = -1 +kNoTimeOut = -2 +kAENoDispatch = 0 +kAEUseStandardDispatch = -1 +errAECoercionFail = -1700 +errAEDescNotFound = -1701 +errAECorruptData = -1702 +errAEWrongDataType = -1703 +errAENotAEDesc = -1704 +errAEBadListItem = -1705 +errAENewerVersion = -1706 +errAENotAppleEvent = -1707 +errAEEventNotHandled = -1708 +errAEReplyNotValid = -1709 +errAEUnknownSendMode = -1710 +errAEWaitCanceled = -1711 +errAETimeout = -1712 +errAENoUserInteraction = -1713 +errAENotASpecialFunction = -1714 +errAEParamMissed = -1715 +errAEUnknownAddressType = -1716 +errAEHandlerNotFound = -1717 +errAEReplyNotArrived = -1718 +errAEIllegalIndex = -1719 +errAEUnknownObjectType = -1731 +errAERecordingIsAlreadyOn = -1732 diff --git a/Mac/Lib/toolbox/Controls.py b/Mac/Lib/toolbox/Controls.py new file mode 100644 index 0000000..c95ea11 --- /dev/null +++ b/Mac/Lib/toolbox/Controls.py @@ -0,0 +1,41 @@ +# Generated from 'D:Development:THINK C:Mac #includes:Apple #includes:Controls.h' +pushButProc = 0 +checkBoxProc = 1 +radioButProc = 2 +useWFont = 8 +scrollBarProc = 16 +inButton = 10 +inCheckBox = 11 +inUpButton = 20 +inDownButton = 21 +inPageUp = 22 +inPageDown = 23 +inThumb = 129 +popupMenuProc = 1008 +inLabel = 1 +inMenu = 2 +inTriangle = 4 +popupUseWFont = 1 << 3 +popupTitleOutline = 1 << 11 +popupTitleExtend = 1 << 14 +popupTitleLeftJust = 0x00000000 +popupTitleCenterJust = 0x00000001 +popupTitleRightJust = 0x000000FF +noConstraint = 0 +hAxisOnly = 1 +vAxisOnly = 2 +drawCntl = 0 +testCntl = 1 +calcCRgns = 2 +initCntl = 3 +dispCntl = 4 +posCntl = 5 +thumbCntl = 6 +dragCntl = 7 +autoTrack = 8 +calcCntlRgn = 10 +calcThumbRgn = 11 +cFrameColor = 0 +cBodyColor = 1 +cTextColor = 2 +cThumbColor = 3 diff --git a/Mac/Lib/toolbox/Dialogs.py b/Mac/Lib/toolbox/Dialogs.py new file mode 100644 index 0000000..297568c --- /dev/null +++ b/Mac/Lib/toolbox/Dialogs.py @@ -0,0 +1,20 @@ +# Generated from 'D:Development:THINK C:Mac #includes:Apple #includes:Dialogs.h' +ctrlItem = 4 +btnCtrl = 0 +chkCtrl = 1 +radCtrl = 2 +resCtrl = 3 +statText = 8 +editText = 16 +iconItem = 32 +picItem = 64 +userItem = 0 +itemDisable = 128 +ok = 1 +cancel = 2 +stopIcon = 0 +noteIcon = 1 +cautionIcon = 2 +overlayDITL = 0 +appendDITLRight = 1 +appendDITLBottom = 2 diff --git a/Mac/Lib/toolbox/Events.py b/Mac/Lib/toolbox/Events.py new file mode 100644 index 0000000..ac32c3f --- /dev/null +++ b/Mac/Lib/toolbox/Events.py @@ -0,0 +1,49 @@ +# Generated from 'D:Development:THINK C:Mac #includes:Apple #includes:Events.h' +nullEvent = 0 +mouseDown = 1 +mouseUp = 2 +keyDown = 3 +keyUp = 4 +autoKey = 5 +updateEvt = 6 +diskEvt = 7 +activateEvt = 8 +osEvt = 15 +mDownMask = 2 +mUpMask = 4 +keyDownMask = 8 +keyUpMask = 16 +autoKeyMask = 32 +updateMask = 64 +diskMask = 128 +activMask = 256 +highLevelEventMask = 1024 +osMask = -32768 +everyEvent = -1 +charCodeMask = 0x000000FF +keyCodeMask = 0x0000FF00 +adbAddrMask = 0x00FF0000 +osEvtMessageMask = 0xFF000000 +mouseMovedMessage = 0xFA +suspendResumeMessage = 0x01 +resumeFlag = 1 +convertClipboardFlag = 2 +activeFlag = 1 +btnState = 128 +cmdKey = 256 +shiftKey = 512 +alphaLock = 1024 +optionKey = 2048 +controlKey = 4096 +networkEvt = 10 +driverEvt = 11 +app1Evt = 12 +app2Evt = 13 +app3Evt = 14 +app4Evt = 15 +networkMask = 1024 +driverMask = 2048 +app1Mask = 4096 +app2Mask = 8192 +app3Mask = 16384 +app4Mask = -32768 diff --git a/Mac/Lib/toolbox/Menus.py b/Mac/Lib/toolbox/Menus.py new file mode 100644 index 0000000..11b9a48 --- /dev/null +++ b/Mac/Lib/toolbox/Menus.py @@ -0,0 +1,12 @@ +# Generated from 'D:Development:THINK C:Mac #includes:Apple #includes:Menus.h' +mDrawMsg = 0 +mChooseMsg = 1 +mSizeMsg = 2 +mDrawItemMsg = 4 +mCalcItemMsg = 5 +textMenuProc = 0 +hMenuCmd = 27 +hierMenu = -1 +mPopUpMsg = 3 +mctAllItems = -98 +mctLastIDIndic = -99 /*last color table entry has this in ID field*/ diff --git a/Mac/Lib/toolbox/Resources.py b/Mac/Lib/toolbox/Resources.py new file mode 100644 index 0000000..743c656 --- /dev/null +++ b/Mac/Lib/toolbox/Resources.py @@ -0,0 +1,12 @@ +# Generated from 'D:Development:THINK C:Mac #includes:Apple #includes:Resources.h' +resSysHeap = 64 +resPurgeable = 32 +resLocked = 16 +resProtected = 8 +resPreload = 4 +resChanged = 2 +mapReadOnly = 128 +mapCompact = 64 +mapChanged = 32 +mapTrue = 0xFFFF +mapFalse = 0xFF00 diff --git a/Mac/Lib/toolbox/Sound.py b/Mac/Lib/toolbox/Sound.py new file mode 100644 index 0000000..600adcd --- /dev/null +++ b/Mac/Lib/toolbox/Sound.py @@ -0,0 +1,101 @@ +# Generated from 'D:Development:THINK C:Mac #includes:Apple #includes:Sound.h' +swMode = -1 +ftMode = 1 +ffMode = 0 +rate22khz = 0x56EE8BA3 +rate11khz = 0x2B7745D1 +squareWaveSynth = 1 +waveTableSynth = 3 +sampledSynth = 5 +MACE3snthID = 11 +MACE6snthID = 13 +nullCmd = 0 +initCmd = 1 +freeCmd = 2 +quietCmd = 3 +flushCmd = 4 +reInitCmd = 5 +waitCmd = 10 +pauseCmd = 11 +resumeCmd = 12 +callBackCmd = 13 +syncCmd = 14 +emptyCmd = 15 +tickleCmd = 20 +requestNextCmd = 21 +howOftenCmd = 22 +wakeUpCmd = 23 +availableCmd = 24 +versionCmd = 25 +totalLoadCmd = 26 +loadCmd = 27 +scaleCmd = 30 +tempoCmd = 31 +freqDurationCmd = 40 +restCmd = 41 +freqCmd = 42 +ampCmd = 43 +timbreCmd = 44 +getAmpCmd = 45 +waveTableCmd = 60 +phaseCmd = 61 +soundCmd = 80 +bufferCmd = 81 +rateCmd = 82 +continueCmd = 83 +doubleBufferCmd = 84 +getRateCmd = 85 +sizeCmd = 90 +convertCmd = 91 +stdQLength = 128 +dataOffsetFlag = 0x8000 +waveInitChannelMask = 0x07 +waveInitChannel0 = 0x04 +waveInitChannel1 = 0x05 +waveInitChannel2 = 0x06 +waveInitChannel3 = 0x07 +initPanMask = 0x0003 +initSRateMask = 0x0030 +initStereoMask = 0x00C0 +initCompMask = 0xFF00 +initChanLeft = 0x0002 +initChanRight = 0x0003 +initNoInterp = 0x0004 +initNoDrop = 0x0008 +initMono = 0x0080 +initStereo = 0x00C0 +initMACE3 = 0x0300 +initMACE6 = 0x0400 +initChan0 = 0x0004 +initChan1 = 0x0005 +initChan2 = 0x0006 +initChan3 = 0x0007 +stdSH = 0x00 +extSH = 0xFF +cmpSH = 0xFE +notCompressed = 0 +twoToOne = 1 +eightToThree = 2 +threeToOne = 3 +sixToOne = 4 +outsideCmpSH = 0 +insideCmpSH = 1 +aceSuccess = 0 +aceMemFull = 1 +aceNilBlock = 2 +aceBadComp = 3 +aceBadEncode = 4 +aceBadDest = 5 +aceBadCmd = 6 +sixToOnePacketSize = 8 +threeToOnePacketSize = 16 +stateBlockSize = 64 +leftOverBlockSize = 32 +firstSoundFormat = 0x0001 +secondSoundFormat = 0x0002 +dbBufferReady = 0x00000001 +dbLastBuffer = 0x00000004 +sysBeepDisable = 0x0000 +sysBeepEnable = 0x0001 +unitTypeNoSelection = 0xFFFF +unitTypeSeconds = 0x0000 diff --git a/Mac/Lib/toolbox/Windows.py b/Mac/Lib/toolbox/Windows.py new file mode 100644 index 0000000..5d5bd7a --- /dev/null +++ b/Mac/Lib/toolbox/Windows.py @@ -0,0 +1,41 @@ +# Generated from 'D:Development:THINK C:Mac #includes:Apple #includes:Windows.h' +documentProc = 0 +dBoxProc = 1 +plainDBox = 2 +altDBoxProc = 3 +noGrowDocProc = 4 +movableDBoxProc = 5 +zoomDocProc = 8 +zoomNoGrow = 12 +rDocProc = 16 +dialogKind = 2 +userKind = 8 +inDesk = 0 +inMenuBar = 1 +inSysWindow = 2 +inContent = 3 +inDrag = 4 +inGrow = 5 +inGoAway = 6 +inZoomIn = 7 +inZoomOut = 8 +wDraw = 0 +wHit = 1 +wCalcRgns = 2 +wNew = 3 +wDispose = 4 +wGrow = 5 +wDrawGIcon = 6 +wNoHit = 0 +wInContent = 1 +wInDrag = 2 +wInGrow = 3 +wInGoAway = 4 +wInZoomIn = 5 +wInZoomOut = 6 +deskPatID = 16 +wContentColor = 0 +wFrameColor = 1 +wTextColor = 2 +wHiliteColor = 3 +wTitleBarColor = 4 diff --git a/Mac/Lib/toolbox/aetools.py b/Mac/Lib/toolbox/aetools.py new file mode 100644 index 0000000..745bce7 --- /dev/null +++ b/Mac/Lib/toolbox/aetools.py @@ -0,0 +1,296 @@ +import struct +import types +import AE +import MacOS +import StringIO + +AEDescType = type(AE.AECreateDesc('TEXT', '')) + +def pack(x): + if x == None: + return AE.AECreateDesc('null', '') + t = type(x) + if t == AEDescType: + return x + if t == types.IntType: + return AE.AECreateDesc('long', struct.pack('l', x)) + if t == types.FloatType: + return AE.AECreateDesc('exte', struct.pack('d', x)[2:]) + if t == types.StringType: + return AE.AECreateDesc('TEXT', x) + if t == types.ListType: + list = AE.AECreateList('', 0) + for item in x: + list.AEPutDesc(0, pack(item)) + return list + if t == types.TupleType: + t, d = x + return AE.AECreateDesc(t, d) + if t == types.DictionaryType: + record = AE.AECreateList('', 1) + for key, value in x.items(): + record.AEPutKeyDesc(key, pack(value)) + if t == types.InstanceType and hasattr(x, '__aepack__'): + return x.__aepack__() + return AE.AECreateDesc('TEXT', repr(x)) # Copout + +def unpack(desc): + t = desc.type + if t == 'TEXT': + return desc.data + if t == 'fals': + return 0 + if t == 'true': + return 1 + if t == 'long': + return struct.unpack('l', desc.data)[0] + if t == 'shor': + return struct.unpack('h', desc.data)[0] + if t == 'sing': + return struct.unpack('f', desc.data)[0] + if t == 'exte': + data = desc.data + return struct.unpack('d', data[:2] + data)[0] + if t in ('doub', 'comp', 'magn'): + return unpack(desc.AECoerceDesc('exte')) + if t == 'enum': + return ('enum', desc.data) + if t == 'null': + return None + if t == 'list': + l = [] + for i in range(desc.AECountItems()): + keyword, item = desc.AEGetNthDesc(i+1, '****') + l.append(unpack(item)) + return l + if t == 'reco': + d = {} + for i in range(desc.AECountItems()): + keyword, item = desc.AEGetNthDesc(i+1, '****') + d[keyword] = unpack(item) + return d + if t == 'obj ': + return unpackobject(desc.data) + return desc.type, desc.data # Copout + +class Object: + def __init__(self, dict = {}): + self.dict = dict + for key, value in dict.items(): + self.dict[key] = value + def __repr__(self): + return "Object(%s)" % `self.dict` + def __str__(self): + want = self.dict['want'] + form = self.dict['form'] + seld = self.dict['seld'] + s = "%s %s %s" % (nicewant(want), niceform(form), niceseld(seld)) + fr = self.dict['from'] + if fr: + s = s + " of " + str(fr) + return s + def __aepack__(self): + f = StringIO.StringIO() + putlong(f, len(self.dict)) + putlong(f, 0) + for key, value in self.dict.items(): + putcode(f, key) + desc = pack(value) + putcode(f, desc.type) + data = desc.data + putlong(f, len(data)) + f.write(data) + return AE.AECreateDesc('obj ', f.getvalue()) + +def nicewant(want): + if type(want) == types.TupleType and len(want) == 2: + return reallynicewant(want) + else: + return `want` + +def reallynicewant((t, w)): + if t != 'type': return `t, w` + # These should be taken from the "elements" of the 'aete' resource + if w == 'cins': return 'insertion point' + if w == 'cha ': return 'character' + if w == 'word': return 'word' + if w == 'para': return 'paragraph' + if w == 'ccel': return 'cell' + if w == 'ccol': return 'column' + if w == 'crow': return 'row' + if w == 'crng': return 'range' + if w == 'wind': return 'window' + if w == 'docu': return 'document' + return `w` + +def niceform(form): + if type(form) == types.TupleType and len(form) == 2: + return reallyniceform(form) + else: + return `form` + +def reallyniceform((t, f)): + if t <> 'enum': return `t, f` + if f == 'indx': return '' + if f == 'name': return '' + if f == 'rele': return '' + return `f` + +def niceseld(seld): + if type(seld) == types.TupleType and len(seld) == 2: + return reallyniceseld(seld) + else: + return `seld` + +def reallyniceseld((t, s)): + if t == 'long': return `s` + if t == 'TEXT': return `s` + if t == 'enum': + if s == 'next': return 'after' + if s == 'prev': return 'before' + return `t, s` + +def unpackobject(data): + f = StringIO.StringIO(data) + nkey = getlong(f) + dumm = getlong(f) + dict = {} + for i in range(nkey): + keyw = getcode(f) + type = getcode(f) + size = getlong(f) + if size: + data = f.read(size) + else: + data = '' + desc = AE.AECreateDesc(type, data) + dict[keyw] = unpack(desc) + return Object(dict) + + +# --- get various data types from a "file" + +def getword(f, *args): + getalgn(f) + s = f.read(2) + if len(s) < 2: + raise EOFError, 'in getword' + str(args) + return (ord(s[0])<<8) | ord(s[1]) + +def getlong(f, *args): + getalgn(f) + s = f.read(4) + if len(s) < 4: + raise EOFError, 'in getlong' + str(args) + return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3]) + +def getcode(f, *args): + getalgn(f) + s = f.read(4) + if len(s) < 4: + raise EOFError, 'in getcode' + str(args) + return s + +def getpstr(f, *args): + c = f.read(1) + if len(c) < 1: + raise EOFError, 'in getpstr[1]' + str(args) + nbytes = ord(c) + if nbytes == 0: return '' + s = f.read(nbytes) + if len(s) < nbytes: + raise EOFError, 'in getpstr[2]' + str(args) + return s + +def getalgn(f): + if f.tell() & 1: + c = f.read(1) + ##if c <> '\0': + ## print 'align:', `c` + +# ---- end get routines + + +# ---- put various data types to a "file" + +def putlong(f, value): + putalgn(f) + f.write(chr((value>>24)&0xff)) + f.write(chr((value>>16)&0xff)) + f.write(chr((value>>8)&0xff)) + f.write(chr(value&0xff)) + +def putword(f, value): + putalgn(f) + f.write(chr((value>>8)&0xff)) + f.write(chr(value&0xff)) + +def putcode(f, value): + if type(value) != types.StringType or len(value) != 4: + raise TypeError, "ostype must be 4-char string" + putalgn(f) + f.write(value) + +def putpstr(f, value): + if type(value) != types.StringType or len(value) > 255: + raise TypeError, "pstr must be string <= 255 chars" + f.write(chr(len(value)) + value) + +def putalgn(f): + if f.tell() & 1: + f.write('\0') + +# ---- end put routines + + +aekeywords = [ + 'tran', + 'rtid', + 'evcl', + 'evid', + 'addr', + 'optk', + 'timo', + 'inte', # this attribute is read only - will be set in AESend + 'esrc', # this attribute is read only + 'miss', # this attribute is read only + 'from' # new in 1.0.1 +] + +def missed(ae): + try: + desc = ae.AEGetAttributeDesc('miss', 'keyw') + except AE.Error, msg: + return None + return desc.data + +def unpackevent(ae): + parameters = {} + while 1: + key = missed(ae) + if not key: break + parameters[key] = unpack(ae.AEGetParamDesc(key, '****')) + attributes = {} + for key in aekeywords: + try: + desc = ae.AEGetAttributeDesc(key, '****') + except (AE.Error, MacOS.Error), msg: + if msg[0] != -1701: + raise sys.exc_type, sys.exc_value + continue + attributes[key] = unpack(desc) + return parameters, attributes + +def packevent(ae, parameters = {}, attributes = {}): + for key, value in parameters.items(): + ae.AEPutParamDesc(key, pack(value)) + for key, value in attributes.items(): + ae.AEPutAttributeDesc(key, pack(value)) + +def test(): + target = AE.AECreateDesc('sign', 'KAHL') + ae = AE.AECreateAppleEvent('aevt', 'oapp', target, -1, 0) + print unpackevent(ae) + +if __name__ == '__main__': + test() |