1 /***********************************************************
2 Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI not be used in advertising or publicity pertaining to
13 distribution of the software without specific, written prior permission.
15 STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18 FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21 OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 ******************************************************************/
27 #include "pymactoolbox.h"
28 #include <arpa/inet.h> /* for ntohl, htonl */
31 /* Like strerror() but for Mac OS error numbers */
33 PyMac_StrError(int err
)
39 m
= PyImport_ImportModuleNoBlock("MacOS");
47 rv
= PyObject_CallMethod(m
, "GetErrorString", "i", err
);
55 char *input
= PyString_AsString(rv
);
60 strncpy(buf
, input
, sizeof(buf
) - 1);
61 buf
[sizeof(buf
) - 1] = '\0';
69 /* Exception object shared by all Mac specific modules for Mac OS errors */
70 PyObject
*PyMac_OSErrException
;
72 /* Initialize and return PyMac_OSErrException */
74 PyMac_GetOSErrException(void)
76 if (PyMac_OSErrException
== NULL
)
77 PyMac_OSErrException
= PyErr_NewException("MacOS.Error", NULL
, NULL
);
78 return PyMac_OSErrException
;
81 /* Set a MAC-specific error from errno, and return NULL; return None if no error */
83 PyErr_Mac(PyObject
*eobj
, int err
)
88 if (err
== 0 && !PyErr_Occurred()) {
92 if (err
== -1 && PyErr_Occurred())
94 msg
= PyMac_StrError(err
);
95 v
= Py_BuildValue("(is)", err
, msg
);
96 PyErr_SetObject(eobj
, v
);
101 /* Call PyErr_Mac with PyMac_OSErrException */
103 PyMac_Error(OSErr err
)
105 return PyErr_Mac(PyMac_GetOSErrException(), err
);
111 PyMac_GetFullPathname(FSSpec
*fss
, char *path
, int len
)
120 fs
= PyMac_BuildFSSpec(fss
);
124 rv
= PyObject_CallMethod(fs
, "as_pathname", "");
128 input
= PyString_AsString(rv
);
132 strncpy(path
, input
, len
- 1);
133 path
[len
- 1] = '\0';
140 exc
= PyErr_Occurred();
141 if (exc
&& PyErr_GivenExceptionMatches(exc
,
142 PyMac_GetOSErrException())) {
143 PyObject
*args
= PyObject_GetAttrString(exc
, "args");
146 PyArg_ParseTuple(args
, "is", &err
, &ignore
);
157 #endif /* !__LP64__ */
159 /* Convert a 4-char string object argument to an OSType value */
161 PyMac_GetOSType(PyObject
*v
, OSType
*pr
)
164 if (!PyString_Check(v
) || PyString_Size(v
) != 4) {
165 PyErr_SetString(PyExc_TypeError
,
166 "OSType arg must be string of 4 chars");
169 memcpy((char *)&tmp
, PyString_AsString(v
), 4);
170 *pr
= (OSType
)ntohl(tmp
);
174 /* Convert an OSType value to a 4-char string object */
176 PyMac_BuildOSType(OSType t
)
178 uint32_t tmp
= htonl((uint32_t)t
);
179 return PyString_FromStringAndSize((char *)&tmp
, 4);
182 /* Convert an NumVersion value to a 4-element tuple */
184 PyMac_BuildNumVersion(NumVersion t
)
186 return Py_BuildValue("(hhhh)", t
.majorRev
, t
.minorAndBugRev
, t
.stage
, t
.nonRelRev
);
190 /* Convert a Python string object to a Str255 */
192 PyMac_GetStr255(PyObject
*v
, Str255 pbuf
)
195 if (!PyString_Check(v
) || (len
= PyString_Size(v
)) > 255) {
196 PyErr_SetString(PyExc_TypeError
,
197 "Str255 arg must be string of at most 255 chars");
201 memcpy((char *)(pbuf
+1), PyString_AsString(v
), len
);
205 /* Convert a Str255 to a Python string object */
207 PyMac_BuildStr255(Str255 s
)
210 PyErr_SetString(PyExc_SystemError
, "Str255 pointer is NULL");
213 return PyString_FromStringAndSize((char *)&s
[1], (int)s
[0]);
217 PyMac_BuildOptStr255(Str255 s
)
223 return PyString_FromStringAndSize((char *)&s
[1], (int)s
[0]);
228 /* Convert a Python object to a Rect.
229 The object must be a (left, top, right, bottom) tuple.
230 (This differs from the order in the struct but is consistent with
231 the arguments to SetRect(), and also with STDWIN). */
233 PyMac_GetRect(PyObject
*v
, Rect
*r
)
235 return PyArg_Parse(v
, "(hhhh)", &r
->left
, &r
->top
, &r
->right
, &r
->bottom
);
238 /* Convert a Rect to a Python object */
240 PyMac_BuildRect(Rect
*r
)
242 return Py_BuildValue("(hhhh)", r
->left
, r
->top
, r
->right
, r
->bottom
);
246 /* Convert a Python object to a Point.
247 The object must be a (h, v) tuple.
248 (This differs from the order in the struct but is consistent with
249 the arguments to SetPoint(), and also with STDWIN). */
251 PyMac_GetPoint(PyObject
*v
, Point
*p
)
253 return PyArg_Parse(v
, "(hh)", &p
->h
, &p
->v
);
256 /* Convert a Point to a Python object */
258 PyMac_BuildPoint(Point p
)
260 return Py_BuildValue("(hh)", p
.h
, p
.v
);
264 /* Convert a Python object to an EventRecord.
265 The object must be a (what, message, when, (v, h), modifiers) tuple. */
267 PyMac_GetEventRecord(PyObject
*v
, EventRecord
*e
)
269 return PyArg_Parse(v
, "(Hkk(hh)H)",
278 /* Convert a Rect to an EventRecord object */
280 PyMac_BuildEventRecord(EventRecord
*e
)
282 return Py_BuildValue("(hll(hh)h)",
291 /* Convert Python object to Fixed */
293 PyMac_GetFixed(PyObject
*v
, Fixed
*f
)
297 if( !PyArg_Parse(v
, "d", &d
))
299 *f
= (Fixed
)(d
* 0x10000);
303 /* Convert a Fixed to a Python object */
305 PyMac_BuildFixed(Fixed f
)
311 return Py_BuildValue("d", d
);
314 /* Convert wide to/from Python int or (hi, lo) tuple. XXXX Should use Python longs */
316 PyMac_Getwide(PyObject
*v
, wide
*rv
)
318 if (PyInt_Check(v
)) {
320 rv
->lo
= PyInt_AsLong(v
);
321 if( rv
->lo
& 0x80000000 )
325 return PyArg_Parse(v
, "(kk)", &rv
->hi
, &rv
->lo
);
330 PyMac_Buildwide(wide
*w
)
332 if ( (w
->hi
== 0 && (w
->lo
& 0x80000000) == 0) ||
333 (w
->hi
== -1 && (w
->lo
& 0x80000000) ) )
334 return PyInt_FromLong(w
->lo
);
335 return Py_BuildValue("(ll)", w
->hi
, w
->lo
);
338 #ifdef USE_TOOLBOX_OBJECT_GLUE
340 ** Glue together the toolbox objects.
342 ** Because toolbox modules interdepend on each other, they use each others
343 ** object types, on MacOSX/MachO this leads to the situation that they
344 ** cannot be dynamically loaded (or they would all have to be lumped into
345 ** a single .so, but this would be bad for extensibility).
347 ** This file defines wrappers for all the _New and _Convert functions,
348 ** which are the Py_BuildValue and PyArg_ParseTuple helpers. The wrappers
349 ** check an indirection function pointer, and if it isn't filled in yet
350 ** they import the appropriate module, whose init routine should fill in
354 #define GLUE_NEW(object, routinename, module) \
355 PyObject *(*PyMacGluePtr_##routinename)(object); \
357 PyObject *routinename(object cobj) { \
358 if (!PyMacGluePtr_##routinename) { \
359 if (!PyImport_ImportModule(module)) return NULL; \
360 if (!PyMacGluePtr_##routinename) { \
361 PyErr_SetString(PyExc_ImportError, "Module did not provide routine: " module ": " #routinename); \
365 return (*PyMacGluePtr_##routinename)(cobj); \
368 #define GLUE_CONVERT(object, routinename, module) \
369 int (*PyMacGluePtr_##routinename)(PyObject *, object *); \
371 int routinename(PyObject *pyobj, object *cobj) { \
372 if (!PyMacGluePtr_##routinename) { \
373 if (!PyImport_ImportModule(module)) return 0; \
374 if (!PyMacGluePtr_##routinename) { \
375 PyErr_SetString(PyExc_ImportError, "Module did not provide routine: " module ": " #routinename); \
379 return (*PyMacGluePtr_##routinename)(pyobj, cobj); \
382 GLUE_NEW(FSSpec
*, PyMac_BuildFSSpec
, "Carbon.File")
383 GLUE_CONVERT(FSSpec
, PyMac_GetFSSpec
, "Carbon.File")
384 GLUE_NEW(FSRef
*, PyMac_BuildFSRef
, "Carbon.File")
385 GLUE_CONVERT(FSRef
, PyMac_GetFSRef
, "Carbon.File")
387 GLUE_NEW(AppleEvent
*, AEDesc_New
, "Carbon.AE") /* XXXX Why by address? */
388 GLUE_NEW(AppleEvent
*, AEDesc_NewBorrowed
, "Carbon.AE")
389 GLUE_CONVERT(AppleEvent
, AEDesc_Convert
, "Carbon.AE")
391 GLUE_NEW(Component
, CmpObj_New
, "Carbon.Cm")
392 GLUE_CONVERT(Component
, CmpObj_Convert
, "Carbon.Cm")
393 GLUE_NEW(ComponentInstance
, CmpInstObj_New
, "Carbon.Cm")
394 GLUE_CONVERT(ComponentInstance
, CmpInstObj_Convert
, "Carbon.Cm")
396 GLUE_NEW(ControlHandle
, CtlObj_New
, "Carbon.Ctl")
397 GLUE_CONVERT(ControlHandle
, CtlObj_Convert
, "Carbon.Ctl")
399 GLUE_NEW(DialogPtr
, DlgObj_New
, "Carbon.Dlg")
400 GLUE_CONVERT(DialogPtr
, DlgObj_Convert
, "Carbon.Dlg")
401 GLUE_NEW(DialogPtr
, DlgObj_WhichDialog
, "Carbon.Dlg")
403 GLUE_NEW(DragReference
, DragObj_New
, "Carbon.Drag")
404 GLUE_CONVERT(DragReference
, DragObj_Convert
, "Carbon.Drag")
406 GLUE_NEW(ListHandle
, ListObj_New
, "Carbon.List")
407 GLUE_CONVERT(ListHandle
, ListObj_Convert
, "Carbon.List")
409 GLUE_NEW(MenuHandle
, MenuObj_New
, "Carbon.Menu")
410 GLUE_CONVERT(MenuHandle
, MenuObj_Convert
, "Carbon.Menu")
412 GLUE_NEW(GrafPtr
, GrafObj_New
, "Carbon.Qd")
413 GLUE_CONVERT(GrafPtr
, GrafObj_Convert
, "Carbon.Qd")
414 GLUE_NEW(BitMapPtr
, BMObj_New
, "Carbon.Qd")
415 GLUE_CONVERT(BitMapPtr
, BMObj_Convert
, "Carbon.Qd")
416 GLUE_NEW(RGBColor
*, QdRGB_New
, "Carbon.Qd") /* XXXX Why? */
417 GLUE_CONVERT(RGBColor
, QdRGB_Convert
, "Carbon.Qd")
419 GLUE_NEW(GWorldPtr
, GWorldObj_New
, "Carbon.Qdoffs")
420 GLUE_CONVERT(GWorldPtr
, GWorldObj_Convert
, "Carbon.Qdoffs")
423 GLUE_NEW(Track
, TrackObj_New
, "Carbon.Qt")
424 GLUE_CONVERT(Track
, TrackObj_Convert
, "Carbon.Qt")
425 GLUE_NEW(Movie
, MovieObj_New
, "Carbon.Qt")
426 GLUE_CONVERT(Movie
, MovieObj_Convert
, "Carbon.Qt")
427 GLUE_NEW(MovieController
, MovieCtlObj_New
, "Carbon.Qt")
428 GLUE_CONVERT(MovieController
, MovieCtlObj_Convert
, "Carbon.Qt")
429 GLUE_NEW(TimeBase
, TimeBaseObj_New
, "Carbon.Qt")
430 GLUE_CONVERT(TimeBase
, TimeBaseObj_Convert
, "Carbon.Qt")
431 GLUE_NEW(UserData
, UserDataObj_New
, "Carbon.Qt")
432 GLUE_CONVERT(UserData
, UserDataObj_Convert
, "Carbon.Qt")
433 GLUE_NEW(Media
, MediaObj_New
, "Carbon.Qt")
434 GLUE_CONVERT(Media
, MediaObj_Convert
, "Carbon.Qt")
435 #endif /* !__LP64__ */
437 GLUE_NEW(Handle
, ResObj_New
, "Carbon.Res")
438 GLUE_CONVERT(Handle
, ResObj_Convert
, "Carbon.Res")
439 GLUE_NEW(Handle
, OptResObj_New
, "Carbon.Res")
440 GLUE_CONVERT(Handle
, OptResObj_Convert
, "Carbon.Res")
442 GLUE_NEW(TEHandle
, TEObj_New
, "Carbon.TE")
443 GLUE_CONVERT(TEHandle
, TEObj_Convert
, "Carbon.TE")
445 GLUE_NEW(WindowPtr
, WinObj_New
, "Carbon.Win")
446 GLUE_CONVERT(WindowPtr
, WinObj_Convert
, "Carbon.Win")
447 GLUE_NEW(WindowPtr
, WinObj_WhichWindow
, "Carbon.Win")
449 GLUE_CONVERT(CFTypeRef
, CFObj_Convert
, "Carbon.CF")
450 GLUE_NEW(CFTypeRef
, CFObj_New
, "Carbon.CF")
452 GLUE_CONVERT(CFTypeRef
, CFTypeRefObj_Convert
, "Carbon.CF")
453 GLUE_NEW(CFTypeRef
, CFTypeRefObj_New
, "Carbon.CF")
455 GLUE_CONVERT(CFStringRef
, CFStringRefObj_Convert
, "Carbon.CF")
456 GLUE_NEW(CFStringRef
, CFStringRefObj_New
, "Carbon.CF")
457 GLUE_CONVERT(CFMutableStringRef
, CFMutableStringRefObj_Convert
, "Carbon.CF")
458 GLUE_NEW(CFMutableStringRef
, CFMutableStringRefObj_New
, "Carbon.CF")
460 GLUE_CONVERT(CFArrayRef
, CFArrayRefObj_Convert
, "Carbon.CF")
461 GLUE_NEW(CFArrayRef
, CFArrayRefObj_New
, "Carbon.CF")
462 GLUE_CONVERT(CFMutableArrayRef
, CFMutableArrayRefObj_Convert
, "Carbon.CF")
463 GLUE_NEW(CFMutableArrayRef
, CFMutableArrayRefObj_New
, "Carbon.CF")
465 GLUE_CONVERT(CFDictionaryRef
, CFDictionaryRefObj_Convert
, "Carbon.CF")
466 GLUE_NEW(CFDictionaryRef
, CFDictionaryRefObj_New
, "Carbon.CF")
467 GLUE_CONVERT(CFMutableDictionaryRef
, CFMutableDictionaryRefObj_Convert
, "Carbon.CF")
468 GLUE_NEW(CFMutableDictionaryRef
, CFMutableDictionaryRefObj_New
, "Carbon.CF")
470 GLUE_CONVERT(CFURLRef
, CFURLRefObj_Convert
, "Carbon.CF")
471 GLUE_CONVERT(CFURLRef
, OptionalCFURLRefObj_Convert
, "Carbon.CF")
472 GLUE_NEW(CFURLRef
, CFURLRefObj_New
, "Carbon.CF")
474 #endif /* USE_TOOLBOX_OBJECT_GLUE */