source: vendor/python/2.5/Python/mactoolboxglue.c

Last change on this file was 3225, checked in by bird, 18 years ago

Python 2.5

File size: 13.0 KB
Line 
1/***********************************************************
2Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
25
26#include "Python.h"
27#include "pymactoolbox.h"
28#include <arpa/inet.h> /* for ntohl, htonl */
29
30
31/* Like strerror() but for Mac OS error numbers */
32char *
33PyMac_StrError(int err)
34{
35 static char buf[256];
36 PyObject *m;
37 PyObject *rv;
38
39 m = PyImport_ImportModule("MacOS");
40 if (!m) {
41 if (Py_VerboseFlag)
42 PyErr_Print();
43 PyErr_Clear();
44 rv = NULL;
45 }
46 else {
47 rv = PyObject_CallMethod(m, "GetErrorString", "i", err);
48 if (!rv)
49 PyErr_Clear();
50 }
51 if (!rv) {
52 buf[0] = '\0';
53 }
54 else {
55 char *input = PyString_AsString(rv);
56 if (!input) {
57 PyErr_Clear();
58 buf[0] = '\0';
59 } else {
60 strncpy(buf, input, sizeof(buf) - 1);
61 buf[sizeof(buf) - 1] = '\0';
62 }
63 Py_DECREF(rv);
64 }
65 Py_XDECREF(m);
66 return buf;
67}
68
69/* Exception object shared by all Mac specific modules for Mac OS errors */
70PyObject *PyMac_OSErrException;
71
72/* Initialize and return PyMac_OSErrException */
73PyObject *
74PyMac_GetOSErrException(void)
75{
76 if (PyMac_OSErrException == NULL)
77 PyMac_OSErrException = PyErr_NewException("MacOS.Error", NULL, NULL);
78 return PyMac_OSErrException;
79}
80
81/* Set a MAC-specific error from errno, and return NULL; return None if no error */
82PyObject *
83PyErr_Mac(PyObject *eobj, int err)
84{
85 char *msg;
86 PyObject *v;
87
88 if (err == 0 && !PyErr_Occurred()) {
89 Py_INCREF(Py_None);
90 return Py_None;
91 }
92 if (err == -1 && PyErr_Occurred())
93 return NULL;
94 msg = PyMac_StrError(err);
95 v = Py_BuildValue("(is)", err, msg);
96 PyErr_SetObject(eobj, v);
97 Py_DECREF(v);
98 return NULL;
99}
100
101/* Call PyErr_Mac with PyMac_OSErrException */
102PyObject *
103PyMac_Error(OSErr err)
104{
105 return PyErr_Mac(PyMac_GetOSErrException(), err);
106}
107
108
109OSErr
110PyMac_GetFullPathname(FSSpec *fss, char *path, int len)
111{
112 PyObject *fs, *exc;
113 PyObject *rv = NULL;
114 char *input;
115 OSErr err = noErr;
116
117 *path = '\0';
118
119 fs = PyMac_BuildFSSpec(fss);
120 if (!fs)
121 goto error;
122
123 rv = PyObject_CallMethod(fs, "as_pathname", "");
124 if (!rv)
125 goto error;
126
127 input = PyString_AsString(rv);
128 if (!input)
129 goto error;
130
131 strncpy(path, input, len - 1);
132 path[len - 1] = '\0';
133
134 Py_XDECREF(rv);
135 Py_XDECREF(fs);
136 return err;
137
138 error:
139 exc = PyErr_Occurred();
140 if (exc && PyErr_GivenExceptionMatches(exc,
141 PyMac_GetOSErrException())) {
142 PyObject *args = PyObject_GetAttrString(exc, "args");
143 if (args) {
144 char *ignore;
145 PyArg_ParseTuple(args, "is", &err, &ignore);
146 Py_XDECREF(args);
147 }
148 }
149 if (err == noErr)
150 err = -1;
151 PyErr_Clear();
152 Py_XDECREF(rv);
153 Py_XDECREF(fs);
154 return err;
155}
156
157/* Convert a 4-char string object argument to an OSType value */
158int
159PyMac_GetOSType(PyObject *v, OSType *pr)
160{
161 uint32_t tmp;
162 if (!PyString_Check(v) || PyString_Size(v) != 4) {
163 PyErr_SetString(PyExc_TypeError,
164 "OSType arg must be string of 4 chars");
165 return 0;
166 }
167 memcpy((char *)&tmp, PyString_AsString(v), 4);
168 *pr = (OSType)ntohl(tmp);
169 return 1;
170}
171
172/* Convert an OSType value to a 4-char string object */
173PyObject *
174PyMac_BuildOSType(OSType t)
175{
176 uint32_t tmp = htonl((uint32_t)t);
177 return PyString_FromStringAndSize((char *)&tmp, 4);
178}
179
180/* Convert an NumVersion value to a 4-element tuple */
181PyObject *
182PyMac_BuildNumVersion(NumVersion t)
183{
184 return Py_BuildValue("(hhhh)", t.majorRev, t.minorAndBugRev, t.stage, t.nonRelRev);
185}
186
187
188/* Convert a Python string object to a Str255 */
189int
190PyMac_GetStr255(PyObject *v, Str255 pbuf)
191{
192 int len;
193 if (!PyString_Check(v) || (len = PyString_Size(v)) > 255) {
194 PyErr_SetString(PyExc_TypeError,
195 "Str255 arg must be string of at most 255 chars");
196 return 0;
197 }
198 pbuf[0] = len;
199 memcpy((char *)(pbuf+1), PyString_AsString(v), len);
200 return 1;
201}
202
203/* Convert a Str255 to a Python string object */
204PyObject *
205PyMac_BuildStr255(Str255 s)
206{
207 if ( s == NULL ) {
208 PyErr_SetString(PyExc_SystemError, "Str255 pointer is NULL");
209 return NULL;
210 }
211 return PyString_FromStringAndSize((char *)&s[1], (int)s[0]);
212}
213
214PyObject *
215PyMac_BuildOptStr255(Str255 s)
216{
217 if ( s == NULL ) {
218 Py_INCREF(Py_None);
219 return Py_None;
220 }
221 return PyString_FromStringAndSize((char *)&s[1], (int)s[0]);
222}
223
224
225
226/* Convert a Python object to a Rect.
227 The object must be a (left, top, right, bottom) tuple.
228 (This differs from the order in the struct but is consistent with
229 the arguments to SetRect(), and also with STDWIN). */
230int
231PyMac_GetRect(PyObject *v, Rect *r)
232{
233 return PyArg_Parse(v, "(hhhh)", &r->left, &r->top, &r->right, &r->bottom);
234}
235
236/* Convert a Rect to a Python object */
237PyObject *
238PyMac_BuildRect(Rect *r)
239{
240 return Py_BuildValue("(hhhh)", r->left, r->top, r->right, r->bottom);
241}
242
243
244/* Convert a Python object to a Point.
245 The object must be a (h, v) tuple.
246 (This differs from the order in the struct but is consistent with
247 the arguments to SetPoint(), and also with STDWIN). */
248int
249PyMac_GetPoint(PyObject *v, Point *p)
250{
251 return PyArg_Parse(v, "(hh)", &p->h, &p->v);
252}
253
254/* Convert a Point to a Python object */
255PyObject *
256PyMac_BuildPoint(Point p)
257{
258 return Py_BuildValue("(hh)", p.h, p.v);
259}
260
261
262/* Convert a Python object to an EventRecord.
263 The object must be a (what, message, when, (v, h), modifiers) tuple. */
264int
265PyMac_GetEventRecord(PyObject *v, EventRecord *e)
266{
267 return PyArg_Parse(v, "(Hkk(hh)H)",
268 &e->what,
269 &e->message,
270 &e->when,
271 &e->where.h,
272 &e->where.v,
273 &e->modifiers);
274}
275
276/* Convert a Rect to an EventRecord object */
277PyObject *
278PyMac_BuildEventRecord(EventRecord *e)
279{
280 return Py_BuildValue("(hll(hh)h)",
281 e->what,
282 e->message,
283 e->when,
284 e->where.h,
285 e->where.v,
286 e->modifiers);
287}
288
289/* Convert Python object to Fixed */
290int
291PyMac_GetFixed(PyObject *v, Fixed *f)
292{
293 double d;
294
295 if( !PyArg_Parse(v, "d", &d))
296 return 0;
297 *f = (Fixed)(d * 0x10000);
298 return 1;
299}
300
301/* Convert a Fixed to a Python object */
302PyObject *
303PyMac_BuildFixed(Fixed f)
304{
305 double d;
306
307 d = f;
308 d = d / 0x10000;
309 return Py_BuildValue("d", d);
310}
311
312/* Convert wide to/from Python int or (hi, lo) tuple. XXXX Should use Python longs */
313int
314PyMac_Getwide(PyObject *v, wide *rv)
315{
316 if (PyInt_Check(v)) {
317 rv->hi = 0;
318 rv->lo = PyInt_AsLong(v);
319 if( rv->lo & 0x80000000 )
320 rv->hi = -1;
321 return 1;
322 }
323 return PyArg_Parse(v, "(kk)", &rv->hi, &rv->lo);
324}
325
326
327PyObject *
328PyMac_Buildwide(wide *w)
329{
330 if ( (w->hi == 0 && (w->lo & 0x80000000) == 0) ||
331 (w->hi == -1 && (w->lo & 0x80000000) ) )
332 return PyInt_FromLong(w->lo);
333 return Py_BuildValue("(ll)", w->hi, w->lo);
334}
335
336#ifdef USE_TOOLBOX_OBJECT_GLUE
337/*
338** Glue together the toolbox objects.
339**
340** Because toolbox modules interdepend on each other, they use each others
341** object types, on MacOSX/MachO this leads to the situation that they
342** cannot be dynamically loaded (or they would all have to be lumped into
343** a single .so, but this would be bad for extensibility).
344**
345** This file defines wrappers for all the _New and _Convert functions,
346** which are the Py_BuildValue and PyArg_ParseTuple helpers. The wrappers
347** check an indirection function pointer, and if it isn't filled in yet
348** they import the appropriate module, whose init routine should fill in
349** the pointer.
350*/
351
352#define GLUE_NEW(object, routinename, module) \
353PyObject *(*PyMacGluePtr_##routinename)(object); \
354\
355PyObject *routinename(object cobj) { \
356 if (!PyMacGluePtr_##routinename) { \
357 if (!PyImport_ImportModule(module)) return NULL; \
358 if (!PyMacGluePtr_##routinename) { \
359 PyErr_SetString(PyExc_ImportError, "Module did not provide routine: " module ": " #routinename); \
360 return NULL; \
361 } \
362 } \
363 return (*PyMacGluePtr_##routinename)(cobj); \
364}
365
366#define GLUE_CONVERT(object, routinename, module) \
367int (*PyMacGluePtr_##routinename)(PyObject *, object *); \
368\
369int routinename(PyObject *pyobj, object *cobj) { \
370 if (!PyMacGluePtr_##routinename) { \
371 if (!PyImport_ImportModule(module)) return 0; \
372 if (!PyMacGluePtr_##routinename) { \
373 PyErr_SetString(PyExc_ImportError, "Module did not provide routine: " module ": " #routinename); \
374 return 0; \
375 } \
376 } \
377 return (*PyMacGluePtr_##routinename)(pyobj, cobj); \
378}
379
380GLUE_NEW(FSSpec *, PyMac_BuildFSSpec, "Carbon.File")
381GLUE_CONVERT(FSSpec, PyMac_GetFSSpec, "Carbon.File")
382GLUE_NEW(FSRef *, PyMac_BuildFSRef, "Carbon.File")
383GLUE_CONVERT(FSRef, PyMac_GetFSRef, "Carbon.File")
384
385GLUE_NEW(AppleEvent *, AEDesc_New, "Carbon.AE") /* XXXX Why by address? */
386GLUE_NEW(AppleEvent *, AEDesc_NewBorrowed, "Carbon.AE")
387GLUE_CONVERT(AppleEvent, AEDesc_Convert, "Carbon.AE")
388
389GLUE_NEW(Component, CmpObj_New, "Carbon.Cm")
390GLUE_CONVERT(Component, CmpObj_Convert, "Carbon.Cm")
391GLUE_NEW(ComponentInstance, CmpInstObj_New, "Carbon.Cm")
392GLUE_CONVERT(ComponentInstance, CmpInstObj_Convert, "Carbon.Cm")
393
394GLUE_NEW(ControlHandle, CtlObj_New, "Carbon.Ctl")
395GLUE_CONVERT(ControlHandle, CtlObj_Convert, "Carbon.Ctl")
396
397GLUE_NEW(DialogPtr, DlgObj_New, "Carbon.Dlg")
398GLUE_CONVERT(DialogPtr, DlgObj_Convert, "Carbon.Dlg")
399GLUE_NEW(DialogPtr, DlgObj_WhichDialog, "Carbon.Dlg")
400
401GLUE_NEW(DragReference, DragObj_New, "Carbon.Drag")
402GLUE_CONVERT(DragReference, DragObj_Convert, "Carbon.Drag")
403
404GLUE_NEW(ListHandle, ListObj_New, "Carbon.List")
405GLUE_CONVERT(ListHandle, ListObj_Convert, "Carbon.List")
406
407GLUE_NEW(MenuHandle, MenuObj_New, "Carbon.Menu")
408GLUE_CONVERT(MenuHandle, MenuObj_Convert, "Carbon.Menu")
409
410GLUE_NEW(GrafPtr, GrafObj_New, "Carbon.Qd")
411GLUE_CONVERT(GrafPtr, GrafObj_Convert, "Carbon.Qd")
412GLUE_NEW(BitMapPtr, BMObj_New, "Carbon.Qd")
413GLUE_CONVERT(BitMapPtr, BMObj_Convert, "Carbon.Qd")
414GLUE_NEW(RGBColor *, QdRGB_New, "Carbon.Qd") /* XXXX Why? */
415GLUE_CONVERT(RGBColor, QdRGB_Convert, "Carbon.Qd")
416
417GLUE_NEW(GWorldPtr, GWorldObj_New, "Carbon.Qdoffs")
418GLUE_CONVERT(GWorldPtr, GWorldObj_Convert, "Carbon.Qdoffs")
419
420GLUE_NEW(Track, TrackObj_New, "Carbon.Qt")
421GLUE_CONVERT(Track, TrackObj_Convert, "Carbon.Qt")
422GLUE_NEW(Movie, MovieObj_New, "Carbon.Qt")
423GLUE_CONVERT(Movie, MovieObj_Convert, "Carbon.Qt")
424GLUE_NEW(MovieController, MovieCtlObj_New, "Carbon.Qt")
425GLUE_CONVERT(MovieController, MovieCtlObj_Convert, "Carbon.Qt")
426GLUE_NEW(TimeBase, TimeBaseObj_New, "Carbon.Qt")
427GLUE_CONVERT(TimeBase, TimeBaseObj_Convert, "Carbon.Qt")
428GLUE_NEW(UserData, UserDataObj_New, "Carbon.Qt")
429GLUE_CONVERT(UserData, UserDataObj_Convert, "Carbon.Qt")
430GLUE_NEW(Media, MediaObj_New, "Carbon.Qt")
431GLUE_CONVERT(Media, MediaObj_Convert, "Carbon.Qt")
432
433GLUE_NEW(Handle, ResObj_New, "Carbon.Res")
434GLUE_CONVERT(Handle, ResObj_Convert, "Carbon.Res")
435GLUE_NEW(Handle, OptResObj_New, "Carbon.Res")
436GLUE_CONVERT(Handle, OptResObj_Convert, "Carbon.Res")
437
438GLUE_NEW(TEHandle, TEObj_New, "Carbon.TE")
439GLUE_CONVERT(TEHandle, TEObj_Convert, "Carbon.TE")
440
441GLUE_NEW(WindowPtr, WinObj_New, "Carbon.Win")
442GLUE_CONVERT(WindowPtr, WinObj_Convert, "Carbon.Win")
443GLUE_NEW(WindowPtr, WinObj_WhichWindow, "Carbon.Win")
444
445GLUE_CONVERT(CFTypeRef, CFObj_Convert, "Carbon.CF")
446GLUE_NEW(CFTypeRef, CFObj_New, "Carbon.CF")
447
448GLUE_CONVERT(CFTypeRef, CFTypeRefObj_Convert, "Carbon.CF")
449GLUE_NEW(CFTypeRef, CFTypeRefObj_New, "Carbon.CF")
450
451GLUE_CONVERT(CFStringRef, CFStringRefObj_Convert, "Carbon.CF")
452GLUE_NEW(CFStringRef, CFStringRefObj_New, "Carbon.CF")
453GLUE_CONVERT(CFMutableStringRef, CFMutableStringRefObj_Convert, "Carbon.CF")
454GLUE_NEW(CFMutableStringRef, CFMutableStringRefObj_New, "Carbon.CF")
455
456GLUE_CONVERT(CFArrayRef, CFArrayRefObj_Convert, "Carbon.CF")
457GLUE_NEW(CFArrayRef, CFArrayRefObj_New, "Carbon.CF")
458GLUE_CONVERT(CFMutableArrayRef, CFMutableArrayRefObj_Convert, "Carbon.CF")
459GLUE_NEW(CFMutableArrayRef, CFMutableArrayRefObj_New, "Carbon.CF")
460
461GLUE_CONVERT(CFDictionaryRef, CFDictionaryRefObj_Convert, "Carbon.CF")
462GLUE_NEW(CFDictionaryRef, CFDictionaryRefObj_New, "Carbon.CF")
463GLUE_CONVERT(CFMutableDictionaryRef, CFMutableDictionaryRefObj_Convert, "Carbon.CF")
464GLUE_NEW(CFMutableDictionaryRef, CFMutableDictionaryRefObj_New, "Carbon.CF")
465
466GLUE_CONVERT(CFURLRef, CFURLRefObj_Convert, "Carbon.CF")
467GLUE_CONVERT(CFURLRef, OptionalCFURLRefObj_Convert, "Carbon.CF")
468GLUE_NEW(CFURLRef, CFURLRefObj_New, "Carbon.CF")
469
470#endif /* USE_TOOLBOX_OBJECT_GLUE */
Note: See TracBrowser for help on using the repository browser.