blob: 4ec56e455095286d561b34e9196e3c111d562665 [file] [log] [blame]
Just van Rossum79e71f72001-12-13 13:17:20 +00001# This script generates a Python interface for an Apple Macintosh Manager.
2# It uses the "bgen" package to generate C code.
3# The function specifications are generated by scanning the mamager's header file,
4# using the "scantools" package (customized for this particular manager).
5
6#error missing SetActionFilter
7
8import string
9
10# Declarations that change for each manager
11MODNAME = '_CG' # The name of the module
12
13# The following is *usually* unchanged but may still require tuning
14MODPREFIX = 'CG' # The prefix for module-wide routines
15INPUTFILE = string.lower(MODPREFIX) + 'gen.py' # The file generated by the scanner
16OUTPUTFILE = MODNAME + "module.c" # The file generated by this program
17
18from macsupport import *
19
20
21# Create the type objects
22
23includestuff = includestuff + """
24#ifdef WITHOUT_FRAMEWORKS
25#include <Quickdraw.h>
26#include <CGContext.h>
27#else
28#include <CoreGraphics/CoreGraphics.h>
29#endif
30
31#if !TARGET_API_MAC_OSX
32 /* This code is adapted from the CallMachOFramework demo at:
33 http://developer.apple.com/samplecode/Sample_Code/Runtime_Architecture/CallMachOFramework.htm
34 It allows us to call Mach-O functions from CFM apps. */
35
36 #include <Folders.h>
37 #include "CFMLateImport.h"
38
39 static OSStatus LoadFrameworkBundle(CFStringRef framework, CFBundleRef *bundlePtr)
40 // This routine finds a the named framework and creates a CFBundle
41 // object for it. It looks for the framework in the frameworks folder,
42 // as defined by the Folder Manager. Currently this is
43 // "/System/Library/Frameworks", but we recommend that you avoid hard coded
44 // paths to ensure future compatibility.
45 //
46 // You might think that you could use CFBundleGetBundleWithIdentifier but
47 // that only finds bundles that are already loaded into your context.
48 // That would work in the case of the System framework but it wouldn't
49 // work if you're using some other, less-obvious, framework.
50 {
51 OSStatus err;
52 FSRef frameworksFolderRef;
53 CFURLRef baseURL;
54 CFURLRef bundleURL;
55
56 *bundlePtr = nil;
57
58 baseURL = nil;
59 bundleURL = nil;
60
61 // Find the frameworks folder and create a URL for it.
62
63 err = FSFindFolder(kOnAppropriateDisk, kFrameworksFolderType, true, &frameworksFolderRef);
64 if (err == noErr) {
65 baseURL = CFURLCreateFromFSRef(kCFAllocatorSystemDefault, &frameworksFolderRef);
66 if (baseURL == nil) {
67 err = coreFoundationUnknownErr;
68 }
69 }
70
71 // Append the name of the framework to the URL.
72
73 if (err == noErr) {
74 bundleURL = CFURLCreateCopyAppendingPathComponent(kCFAllocatorSystemDefault, baseURL, framework, false);
75 if (bundleURL == nil) {
76 err = coreFoundationUnknownErr;
77 }
78 }
79
80 // Create a bundle based on that URL and load the bundle into memory.
81 // We never unload the bundle, which is reasonable in this case because
82 // the sample assumes that you'll be calling functions from this
83 // framework throughout the life of your application.
84
85 if (err == noErr) {
86 *bundlePtr = CFBundleCreate(kCFAllocatorSystemDefault, bundleURL);
87 if (*bundlePtr == nil) {
88 err = coreFoundationUnknownErr;
89 }
90 }
91 if (err == noErr) {
92 if ( ! CFBundleLoadExecutable( *bundlePtr ) ) {
93 err = coreFoundationUnknownErr;
94 }
95 }
96
97 // Clean up.
98
99 if (err != noErr && *bundlePtr != nil) {
100 CFRelease(*bundlePtr);
101 *bundlePtr = nil;
102 }
103 if (bundleURL != nil) {
104 CFRelease(bundleURL);
105 }
106 if (baseURL != nil) {
107 CFRelease(baseURL);
108 }
109
110 return err;
111 }
112
113
114
115 // The CFMLateImport approach requires that you define a fragment
116 // initialisation routine that latches the fragment's connection
117 // ID and locator. If your code already has a fragment initialiser
118 // you will have to integrate the following into it.
119
120 static CFragConnectionID gFragToFixConnID;
121 static FSSpec gFragToFixFile;
122 static CFragSystem7DiskFlatLocator gFragToFixLocator;
123
124 extern OSErr FragmentInit(const CFragInitBlock *initBlock);
125 extern OSErr FragmentInit(const CFragInitBlock *initBlock)
126 {
127 __initialize(initBlock); /* call the "original" initializer */
128 gFragToFixConnID = (CFragConnectionID) initBlock->closureID;
129 gFragToFixFile = *(initBlock->fragLocator.u.onDisk.fileSpec);
130 gFragToFixLocator = initBlock->fragLocator.u.onDisk;
131 gFragToFixLocator.fileSpec = &gFragToFixFile;
132
133 return noErr;
134 }
135
136#endif
137
138extern int GrafObj_Convert(PyObject *, GrafPtr *);
139
140/*
141** Manual converters
142*/
143
144PyObject *CGPoint_New(CGPoint *itself)
145{
146
147 return Py_BuildValue("(ff)",
148 itself->x,
149 itself->y);
150}
151
152int
153CGPoint_Convert(PyObject *v, CGPoint *p_itself)
154{
155 if( !PyArg_Parse(v, "(ff)",
156 &p_itself->x,
157 &p_itself->y) )
158 return 0;
159 return 1;
160}
161
162PyObject *CGRect_New(CGRect *itself)
163{
164
165 return Py_BuildValue("(ffff)",
166 itself->origin.x,
167 itself->origin.y,
168 itself->size.width,
169 itself->size.height);
170}
171
172int
173CGRect_Convert(PyObject *v, CGRect *p_itself)
174{
175 if( !PyArg_Parse(v, "(ffff)",
176 &p_itself->origin.x,
177 &p_itself->origin.y,
178 &p_itself->size.width,
179 &p_itself->size.height) )
180 return 0;
181 return 1;
182}
183
184PyObject *CGAffineTransform_New(CGAffineTransform *itself)
185{
186
187 return Py_BuildValue("(ffffff)",
188 itself->a,
189 itself->b,
190 itself->c,
191 itself->d,
192 itself->tx,
193 itself->ty);
194}
195
196int
197CGAffineTransform_Convert(PyObject *v, CGAffineTransform *p_itself)
198{
199 if( !PyArg_Parse(v, "(ffffff)",
200 &p_itself->a,
201 &p_itself->b,
202 &p_itself->c,
203 &p_itself->d,
204 &p_itself->tx,
205 &p_itself->ty) )
206 return 0;
207 return 1;
208}
209"""
210
211initstuff = initstuff + """
212#if !TARGET_API_MAC_OSX
213CFBundleRef sysBundle;
214OSStatus err;
215
216if (&LoadFrameworkBundle == NULL) {
217 PyErr_SetString(PyExc_ImportError, "CoreCraphics not supported");
218 return;
219}
220err = LoadFrameworkBundle(CFSTR("ApplicationServices.framework"), &sysBundle);
221if (err == noErr)
222 err = CFMLateImportBundle(&gFragToFixLocator, gFragToFixConnID, FragmentInit, "\pCGStubLib", sysBundle);
223if (err != noErr) {
224 PyErr_SetString(PyExc_ImportError, "CoreCraphics not supported");
225 return;
226};
227#endif /* !TARGET_API_MAC_OSX */
228"""
229
230class MyOpaqueByValueType(OpaqueByValueType):
231 """Sort of a mix between OpaqueByValueType and OpaqueType."""
232 def mkvalueArgs(self, name):
233 return "%s, &%s" % (self.new, name)
234
235CGPoint = MyOpaqueByValueType('CGPoint', 'CGPoint')
236CGRect = MyOpaqueByValueType('CGRect', 'CGRect')
237CGAffineTransform = MyOpaqueByValueType('CGAffineTransform', 'CGAffineTransform')
238
239char_ptr = Type("char *", "s")
240
241CGTextEncoding = int
242CGLineCap = int
243CGLineJoin = int
244CGTextDrawingMode = int
245CGPathDrawingMode = int
246
247# The real objects
248CGContextRef = OpaqueByValueType("CGContextRef", "CGContextRefObj")
249
250
251class MyObjectDefinition(GlobalObjectDefinition):
252 def outputStructMembers(self):
253 ObjectDefinition.outputStructMembers(self)
254 def outputCleanupStructMembers(self):
255 Output("CGContextRelease(self->ob_itself);")
256
257
258# Create the generator groups and link them
259module = MacModule(MODNAME, MODPREFIX, includestuff, finalstuff, initstuff)
260
261CGContextRef_object = MyObjectDefinition('CGContextRef', 'CGContextRefObj', 'CGContextRef')
262
263
264# ADD object here
265
266module.addobject(CGContextRef_object)
267
268
269
270Function = FunctionGenerator
271Method = MethodGenerator
272
273CGContextRef_methods = []
274
275# ADD _methods initializer here
276execfile(INPUTFILE)
277
278CreateCGContextForPort_body = """\
279GrafPtr port;
280CGContextRef ctx;
281OSStatus _err;
282
283if (!PyArg_ParseTuple(_args, "O&", GrafObj_Convert, &port))
284 return NULL;
285
286_err = CreateCGContextForPort(port, &ctx);
287if (_err != noErr)
288 if (_err != noErr) return PyMac_Error(_err);
289_res = Py_BuildValue("O&", CGContextRefObj_New, ctx);
290return _res;
291"""
292
293f = ManualGenerator("CreateCGContextForPort", CreateCGContextForPort_body);
294f.docstring = lambda: "(CGrafPtr) -> CGContextRef"
295module.add(f)
296
297
298# ADD add forloop here
299for f in CGContextRef_methods:
300 CGContextRef_object.add(f)
301
302# generate output (open the output file as late as possible)
303SetOutputFileName(OUTPUTFILE)
304module.generate()
305