1"""\
2Augment the "bgen" package with definitions that are useful on the Apple Macintosh.
3
4Intended usage is "from macsupport import *" -- this implies all bgen's goodies.
5"""
6
7
8# Import everything from bgen (for ourselves as well as for re-export)
9from bgen import *
10
11
12# Simple types
13Boolean = Type("Boolean", "b")
14SignedByte = Type("SignedByte", "b")
15Size = Type("Size", "l")
16Style = Type("Style", "b")
17StyleParameter = Type("StyleParameter", "h")
18CharParameter = Type("CharParameter", "h")
19TextEncoding = Type("TextEncoding", "l")
20ByteCount = Type("ByteCount", "l")
21Duration = Type("Duration", "l")
22ByteOffset = Type("ByteOffset", "l")
23OptionBits = Type("OptionBits", "l")
24ItemCount = Type("ItemCount", "l")
25PBVersion = Type("PBVersion", "l")
26ScriptCode = Type("ScriptCode", "h")
27LangCode = Type("LangCode", "h")
28RegionCode = Type("RegionCode", "h")
29
30UInt8 = Type("UInt8", "b")
31SInt8 = Type("SInt8", "b")
32UInt16 = Type("UInt16", "H")
33SInt16 = Type("SInt16", "h")
34UInt32 = Type("UInt32", "l")
35SInt32 = Type("SInt32", "l")
36Float32 = Type("Float32", "f")
37
38wide = OpaqueByValueType("wide", "PyMac_Buildwide", "PyMac_Getwide")
39wide_ptr = OpaqueType("wide", "PyMac_Buildwide", "PyMac_Getwide")
40
41# Pascal strings
42ConstStr255Param = OpaqueArrayType("Str255", "PyMac_BuildStr255", "PyMac_GetStr255")
43Str255 = OpaqueArrayType("Str255", "PyMac_BuildStr255", "PyMac_GetStr255")
44StringPtr = OpaqueByValueType("StringPtr", "PyMac_BuildStr255", "PyMac_GetStr255")
45ConstStringPtr = StringPtr
46
47# File System Specifications
48FSSpec_ptr = OpaqueType("FSSpec", "PyMac_BuildFSSpec", "PyMac_GetFSSpec")
49FSSpec = OpaqueByValueStructType("FSSpec", "PyMac_BuildFSSpec", "PyMac_GetFSSpec")
50FSRef_ptr = OpaqueType("FSRef", "PyMac_BuildFSRef", "PyMac_GetFSRef")
51FSRef = OpaqueByValueStructType("FSRef", "PyMac_BuildFSRef", "PyMac_GetFSRef")
52
53# OSType and ResType: 4-byte character strings
54def OSTypeType(typename):
55    return OpaqueByValueType(typename, "PyMac_BuildOSType", "PyMac_GetOSType")
56OSType = OSTypeType("OSType")
57ResType = OSTypeType("ResType")
58FourCharCode = OSTypeType("FourCharCode")
59
60# Version numbers
61NumVersion = OpaqueByValueType("NumVersion", "PyMac_BuildNumVersion", "BUG")
62
63# Handles (always resources in our case)
64Handle = OpaqueByValueType("Handle", "ResObj")
65MenuHandle = OpaqueByValueType("MenuHandle", "MenuObj")
66MenuRef = MenuHandle
67ControlHandle = OpaqueByValueType("ControlHandle", "CtlObj")
68ControlRef = ControlHandle
69
70# Windows and Dialogs
71WindowPtr = OpaqueByValueType("WindowPtr", "WinObj")
72WindowRef = WindowPtr
73DialogPtr = OpaqueByValueType("DialogPtr", "DlgObj")
74DialogRef = DialogPtr
75ExistingWindowPtr = OpaqueByValueType("WindowPtr", "WinObj_WhichWindow", "BUG")
76ExistingDialogPtr = OpaqueByValueType("DialogPtr", "DlgObj_WhichDialog", "BUG")
77
78# NULL pointer passed in as optional storage -- not present in Python version
79NullStorage = FakeType("(void *)0")
80
81# More standard datatypes
82Fixed = OpaqueByValueType("Fixed", "PyMac_BuildFixed", "PyMac_GetFixed")
83
84# Quickdraw data types
85Rect = Rect_ptr = OpaqueType("Rect", "PyMac_BuildRect", "PyMac_GetRect")
86Point = OpaqueByValueType("Point", "PyMac_BuildPoint", "PyMac_GetPoint")
87Point_ptr = OpaqueType("Point", "PyMac_BuildPoint", "PyMac_GetPoint")
88
89# Event records
90EventRecord = OpaqueType("EventRecord", "PyMac_BuildEventRecord", "PyMac_GetEventRecord")
91EventRecord_ptr = EventRecord
92
93# CoreFoundation datatypes
94CFTypeRef = OpaqueByValueType("CFTypeRef", "CFTypeRefObj")
95CFStringRef = OpaqueByValueType("CFStringRef", "CFStringRefObj")
96CFMutableStringRef = OpaqueByValueType("CFMutableStringRef", "CFMutableStringRefObj")
97CFArrayRef = OpaqueByValueType("CFArrayRef", "CFArrayRefObj")
98CFMutableArrayRef = OpaqueByValueType("CFMutableArrayRef", "CFMutableArrayRefObj")
99CFDictionaryRef = OpaqueByValueType("CFDictionaryRef", "CFDictionaryRefObj")
100CFMutableDictionaryRef = OpaqueByValueType("CFMutableDictionaryRef", "CFMutableDictionaryRefObj")
101CFURLRef = OpaqueByValueType("CFURLRef", "CFURLRefObj")
102OptionalCFURLRef = OpaqueByValueType("CFURLRef", "OptionalCFURLRefObj")
103
104# OSErr is special because it is turned into an exception
105# (Could do this with less code using a variant of mkvalue("O&")?)
106class OSErrType(Type):
107    def errorCheck(self, name):
108        Output("if (%s != noErr) return PyMac_Error(%s);", name, name)
109        self.used = 1
110OSErr = OSErrType("OSErr", 'h')
111OSStatus = OSErrType("OSStatus", 'l')
112
113
114# Various buffer types
115
116InBuffer = VarInputBufferType('char', 'long', 'l')      # (buf, len)
117UcharInBuffer  = VarInputBufferType('unsigned char', 'long', 'l')       # (buf, len)
118OptionalInBuffer = OptionalVarInputBufferType('char', 'long', 'l')      # (buf, len)
119
120InOutBuffer = HeapInputOutputBufferType('char', 'long', 'l')    # (inbuf, outbuf, len)
121VarInOutBuffer = VarHeapInputOutputBufferType('char', 'long', 'l') # (inbuf, outbuf, &len)
122
123OutBuffer = HeapOutputBufferType('char', 'long', 'l')       # (buf, len)
124VarOutBuffer = VarHeapOutputBufferType('char', 'long', 'l') # (buf, &len)
125VarVarOutBuffer = VarVarHeapOutputBufferType('char', 'long', 'l') # (buf, len, &len)
126
127# Unicode arguments sometimes have reversed len, buffer (don't understand why Apple did this...)
128class VarUnicodeInputBufferType(VarInputBufferType):
129
130    def getargsFormat(self):
131        return "u#"
132
133class VarUnicodeReverseInputBufferType(ReverseInputBufferMixin, VarUnicodeInputBufferType):
134    pass
135
136UnicodeInBuffer = VarUnicodeInputBufferType('UniChar', 'UniCharCount', 'l')
137UnicodeReverseInBuffer = VarUnicodeReverseInputBufferType('UniChar', 'UniCharCount', 'l')
138UniChar_ptr = InputOnlyType("UniCharPtr", "u")
139
140
141# Predefine various pieces of program text to be passed to Module() later:
142
143# Stuff added immediately after the system include files
144includestuff = """
145#include "pymactoolbox.h"
146
147/* Macro to test whether a weak-loaded CFM function exists */
148#define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL )  {\\
149        PyErr_SetString(PyExc_NotImplementedError, \\
150        "Not available in this shared library/OS version"); \\
151        return NULL; \\
152    }} while(0)
153
154"""
155
156# Stuff added just before the module's init function
157finalstuff = """
158"""
159
160# Stuff added inside the module's init function
161initstuff = """
162"""
163
164
165# Generator classes with a twist -- if the function returns OSErr,
166# its mode is manipulated so that it turns into an exception or disappears
167# (and its name is changed to _err, for documentation purposes).
168# This requires that the OSErr type (defined above) has a non-trivial
169# errorCheck method.
170class OSErrMixIn:
171    "Mix-in class to treat OSErr/OSStatus return values special"
172    def makereturnvar(self):
173        if self.returntype.__class__ == OSErrType:
174            return Variable(self.returntype, "_err", ErrorMode)
175        else:
176            return Variable(self.returntype, "_rv", OutMode)
177
178class OSErrFunctionGenerator(OSErrMixIn, FunctionGenerator): pass
179class OSErrMethodGenerator(OSErrMixIn, MethodGenerator): pass
180
181class WeakLinkMixIn:
182    "Mix-in to test the function actually exists (!= NULL) before calling"
183
184    def precheck(self):
185        Output('#ifndef %s', self.name)
186        Output('PyMac_PRECHECK(%s);', self.name)
187        Output('#endif')
188
189class WeakLinkFunctionGenerator(WeakLinkMixIn, FunctionGenerator): pass
190class WeakLinkMethodGenerator(WeakLinkMixIn, MethodGenerator): pass
191class OSErrWeakLinkFunctionGenerator(OSErrMixIn, WeakLinkMixIn, FunctionGenerator): pass
192class OSErrWeakLinkMethodGenerator(OSErrMixIn, WeakLinkMixIn, MethodGenerator): pass
193
194class MacModule(Module):
195    "Subclass which gets the exception initializer from macglue.c"
196    def exceptionInitializer(self):
197        return "PyMac_GetOSErrException()"
198