1# Scan an Apple header file, generating a Python file of generator calls.
2
3import sys
4from bgenlocations import TOOLBOXDIR, BGENDIR
5sys.path.append(BGENDIR)
6from scantools import Scanner
7
8LONG = "QuickTime"
9SHORT = "qt"
10HEADERFILES= (
11#       "Components.h"  -- In Carbon.Cm
12        "Movies.h",
13        "ImageCompression.h",
14        "QuickTimeComponents.h",
15#       "ImageCodec.h"  -- seems not too useful, and difficult.
16#       "IsochronousDataHandlers.h" -- Is this useful?
17        "MediaHandlers.h",
18#       "QTML.h", -- Windows only, needs separate module
19#       "QuickTimeStreaming.h", -- Difficult
20#       "QTStreamingComponents.h", -- Needs QTStreaming
21        "QuickTimeMusic.h",
22#       "QuickTimeVR.h", -- Not done yet
23#       "Sound.h", -- In Carbon.Snd
24        )
25OBJECTS = ("Movie", "Track", "Media", "UserData", "TimeBase", "MovieController",
26        "IdleManager", "SGOutput")
27
28def main():
29    input = HEADERFILES
30    output = SHORT + "gen.py"
31    defsoutput = TOOLBOXDIR + LONG + ".py"
32    scanner = MyScanner(input, output, defsoutput)
33    scanner.scan()
34    scanner.close()
35    scanner.gentypetest(SHORT+"typetest.py")
36    print "=== Testing definitions output code ==="
37    execfile(defsoutput, {}, {})
38    print "=== Done scanning and generating, now importing the generated code... ==="
39    exec "import " + SHORT + "support"
40    print "=== Done.  It's up to you to compile it now! ==="
41
42class MyScanner(Scanner):
43
44    def destination(self, type, name, arglist):
45        classname = "Function"
46        listname = "functions"
47        if arglist:
48            t, n, m = arglist[0]
49            if t in OBJECTS and m == "InMode":
50                classname = "Method"
51                listname = t + "_methods"
52        return classname, listname
53
54    def writeinitialdefs(self):
55        self.defsfile.write("def FOUR_CHAR_CODE(x): return x\n")
56        self.defsfile.write("xmlIdentifierUnrecognized = -1\n")
57        self.defsfile.write("kControllerMinimum = -0xf777\n")
58        self.defsfile.write("notImplementedMusicOSErr      = -2071\n")
59        self.defsfile.write("cantSendToSynthesizerOSErr    = -2072\n")
60        self.defsfile.write("cantReceiveFromSynthesizerOSErr = -2073\n")
61        self.defsfile.write("illegalVoiceAllocationOSErr   = -2074\n")
62        self.defsfile.write("illegalPartOSErr              = -2075\n")
63        self.defsfile.write("illegalChannelOSErr           = -2076\n")
64        self.defsfile.write("illegalKnobOSErr              = -2077\n")
65        self.defsfile.write("illegalKnobValueOSErr         = -2078\n")
66        self.defsfile.write("illegalInstrumentOSErr        = -2079\n")
67        self.defsfile.write("illegalControllerOSErr        = -2080\n")
68        self.defsfile.write("midiManagerAbsentOSErr        = -2081\n")
69        self.defsfile.write("synthesizerNotRespondingOSErr = -2082\n")
70        self.defsfile.write("synthesizerOSErr              = -2083\n")
71        self.defsfile.write("illegalNoteChannelOSErr       = -2084\n")
72        self.defsfile.write("noteChannelNotAllocatedOSErr  = -2085\n")
73        self.defsfile.write("tunePlayerFullOSErr           = -2086\n")
74        self.defsfile.write("tuneParseOSErr                = -2087\n")
75
76    def makeblacklistnames(self):
77        return [
78                "xmlIdentifierUnrecognized", # const with incompatible definition
79                "DisposeMovie",         # Done on python-object disposal
80                "DisposeMovieTrack",    # ditto
81                "DisposeTrackMedia",    # ditto
82                "DisposeUserData",              # ditto
83#                       "DisposeTimeBase",              # ditto
84                "DisposeMovieController", # ditto
85
86                # The following 4 use 'void *' in an uncontrolled way
87                # TBD when I've read the manual...
88                "GetUserDataItem",
89                "SetUserDataItem",
90                "SetTextSampleData",
91                "BeginFullScreen",
92                # bgen gets the argument in/out wrong..
93                "AddTextSample",
94                "AddTESample",
95                "AddHiliteSample",
96                "HiliteTextSample",
97
98                "MakeTrackTimeTable", # Uses long * return?
99                "MakeMediaTimeTable", # ditto
100##                      "VideoMediaGetStallCount", # Undefined in CW Pro 3 library
101                # OS8 only:
102                'SpriteMediaGetIndImageProperty',       # XXXX Why isn't this in carbon?
103                'CheckQuickTimeRegistration',
104                'SetMovieAnchorDataRef',
105                'GetMovieAnchorDataRef',
106                'GetMovieLoadState',
107                'OpenADataHandler',
108                'MovieMediaGetCurrentMovieProperty',
109                'MovieMediaGetCurrentTrackProperty',
110                'MovieMediaGetChildMovieDataReference',
111                'MovieMediaSetChildMovieDataReference',
112                'MovieMediaLoadChildMovieFromDataReference',
113                'Media3DGetViewObject',
114
115    # these are ImageCompression blacklists
116                "GraphicsExportGetInputPtr",
117
118                # QuickTimeComponents
119                # These two need some help: the first returns a point to a databuffer that
120                # the second disposes. Generate manually?
121                "VDCompressDone",
122                "VDReleaseCompressBuffer",
123                "QTVideoOutputGetGWorldParameters", # How useful is this?
124
125                # MediaHandlers
126                "MediaMakeMediaTimeTable", # just lazy
127                "MediaGetSampleDataPointer", # funny output pointer
128
129                # QuickTimeMusic
130                "kControllerMinimum",
131                # These are artefacts of a macro definition
132                "ulen",
133                "_ext",
134                "x",
135                "w1",
136                "w2",
137                ]
138
139    def makeblacklisttypes(self):
140        return [
141                # I don't think we want to do these
142                "QTSyncTaskPtr",
143                # We dont do callbacks yet, so no need for these
144                "QTCallBack",
145                # Skipped for now, due to laziness
146                "TrackEditState",
147                "MovieEditState",
148                "MatrixRecord",
149                "MatrixRecord_ptr",
150                "SampleReferencePtr",
151                "QTTweener",
152                "QTErrorReplacementPtr",
153                "QTRestrictionSet",
154                "QTUUID",
155                "QTUUID_ptr",
156
157                # Routine pointers, not yet.
158                "MoviesErrorUPP",
159                "MoviePreviewCallOutUPP",
160                "MovieDrawingCompleteUPP",
161                "QTCallBackUPP",
162                "TextMediaUPP",
163                "MovieProgressUPP",
164                "MovieRgnCoverUPP",
165                "MCActionFilterUPP",
166                "MCActionFilterWithRefConUPP",
167                "GetMovieUPP",
168                "ModalFilterUPP",
169                "TrackTransferUPP",
170                "MoviePrePrerollCompleteUPP",
171                "MovieExecuteWiredActionsUPP",
172                "QTBandwidthNotificationUPP",
173                "DoMCActionUPP",
174                "QTNextTaskNeededSoonerCallbackUPP",
175
176                "SampleReference64Ptr", # Don't know what this does, yet
177                "QTRuntimeSpriteDescPtr",
178                "QTBandwidthReference",
179                "QTScheduledBandwidthReference",
180                "QTAtomContainer",
181                "SpriteWorld",
182                "Sprite",
183
184    # these are ImageCompression blacklists
185    "ICMDataUPP",
186    "ICMFlushUPP",
187    "ICMCompletionUPP",
188    "ICMProgressUPP",
189    "StdPixUPP",
190    "QDPixUPP",
191    "ICMAlignmentUPP",
192    "ICMCursorShieldedUPP",
193    "ICMMemoryDisposedUPP",
194    "ICMConvertDataFormatUPP",
195    "ModalFilterYDUPP",
196                "FileFilterUPP",
197
198    "CodecNameSpecListPtr",
199    "CodecInfo",
200     "ImageSequence",
201    "MatrixRecordPtr",
202    "ICMDataProcRecordPtr",
203    "OpenCPicParams",
204    "ICMProgressProcRecordPtr",
205    "ICMAlignmentProcRecordPtr",
206    "ICMPixelFormatInfoPtr",
207    "ImageSequenceDataSource",
208    "ConstStrFileNameParam",
209    "ImageTranscodeSequence",
210    "ImageFieldSequence",
211    "Fract",
212    "PixMapPtr",
213    "GWorldFlags",
214    "void_ptr",   # XXX Being lazy, this one is doable.
215
216    # These are from QuickTimeComponents
217    "CDataHandlerUPP",
218    "CharDataHandlerUPP",
219    "CommentHandlerUPP",
220    "DataHCompletionUPP",
221    "'MovieExportGetDataUPP",
222    "MovieExportGetPropertyUPP",
223    "PreprocessInstructionHandlerUPP",
224    "SGModalFilterUPP",
225    "StartDocumentHandlerUPP",
226    "StartElementHandlerUPP",
227    "VdigIntUPP",
228    "SGDataUPP",
229    "EndDocumentHandlerUPP",
230    "EndElementHandlerUPP",
231    "VideoBottles", # Record full of UPPs
232
233    "SCParams",
234    "ICMCompletionProcRecordPtr",
235    "DataHVolumeList",
236    "DigitizerInfo",
237    "SGCompressInfo",
238    "SeqGrabExtendedFrameInfoPtr",
239    "SeqGrabFrameInfoPtr",
240    "TCTextOptionsPtr",
241    "SGCompressInfo_ptr",
242    "SGDeviceList",
243    "TextDisplayData",
244    "TimeCodeDef",
245    "TimeCodeRecord",
246    "TweenRecord",
247    "VDGamRecPtr",
248    "ToneDescription",  # XXXX Just lazy: this one is easy.
249    "XMLDoc",
250    "UInt64",   # XXXX lazy
251    "UInt64_ptr", # XXXX lazy
252
253    # From MediaHandlers
254    "ActionsUPP",
255    "PrePrerollCompleteUPP",
256    "CodecComponentHandle", # Difficult: handle containing list of components.
257    "GetMovieCompleteParams", # Immense struct
258    "LevelMeterInfoPtr", # Lazy. Also: can be an output parameter!!
259    "MediaEQSpectrumBandsRecordPtr", # ditto
260
261    # From QuickTimeMusic
262    "MusicMIDISendUPP",
263    "MusicOfflineDataUPP",
264    "TuneCallBackUPP",
265    "TunePlayCallBackUPP",
266    "GCPart", # Struct with lots of fields
267    "GCPart_ptr",
268    "GenericKnobDescription", # Struct with lots of fields
269    "KnobDescription",  # Struct with lots of fields
270    "InstrumentAboutInfo", # Struct, not too difficult
271    "NoteChannel", # XXXX Lazy. Could be opaque, I think
272    "NoteRequest", # XXXX Lazy. Not-too-difficult struct
273    "SynthesizerConnections", # Struct with lots of fields
274    "SynthesizerDescription", # Struct with lots of fields
275    "TuneStatus", # Struct with lots of fields
276
277                ]
278
279    def makerepairinstructions(self):
280        return [
281                ([('FSSpec', '*', 'OutMode')], [('FSSpec_ptr', '*', 'InMode')]),
282
283                # Movie controller creation
284                ([('ComponentInstance', 'NewMovieController', 'ReturnMode')],
285                 [('MovieController', '*', 'ReturnMode')]),
286
287                # NewMovieFromFile
288                ([('short', 'resId', 'OutMode'), ('StringPtr', 'resName', 'InMode')],
289                 [('short', 'resId', 'InOutMode'), ('dummyStringPtr', 'resName', 'InMode')]),
290
291                # MCDoAction and more
292                ([('void', '*', 'OutMode')], [('mcactionparams', '*', 'InMode')]),
293
294                # SetTimeBaseZero. Does not handle NULLs, unfortunately
295                ([('TimeRecord', 'zero', 'OutMode')], [('TimeRecord', 'zero', 'InMode')]),
296
297                # ConvertTime and ConvertTimeScale
298                ([('TimeRecord', 'inout', 'OutMode')], [('TimeRecord', 'inout', 'InOutMode')]),
299                ([('TimeRecord', 'theTime', 'OutMode')], [('TimeRecord', 'theTime', 'InOutMode')]),
300
301                # AddTime and SubtractTime
302                ([('TimeRecord', 'dst', 'OutMode')], [('TimeRecord', 'dst', 'InOutMode')]),
303
304                # Funny definitions
305                ([('char_ptr', '*', 'InMode')], [('stringptr', '*', 'InMode')]),
306                ([('FSSpecPtr', '*', 'InMode')], [('FSSpec_ptr', '*', 'InMode')]),
307                ([('unsigned_char', 'swfVersion', 'OutMode')], [('UInt8', 'swfVersion', 'OutMode')]),
308
309                # It seems MusicMIDIPacket if never flagged with const but always used
310                # for sending only. If that ever changes this needs to be fixed.
311                ([('MusicMIDIPacket', '*', 'OutMode')], [('MusicMIDIPacket_ptr', '*', 'InMode')]),
312
313                # QTMusic const-less input parameters
314                ([('unsigned_long', 'header', 'OutMode')], [('UnsignedLongPtr', 'header', 'InMode')]),
315                ]
316
317if __name__ == "__main__":
318    main()
319