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_ImportModule("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';
68 /* Exception object shared by all Mac specific modules for Mac OS errors */
69 PyObject
*PyMac_OSErrException
;
71 /* Initialize and return PyMac_OSErrException */
73 PyMac_GetOSErrException(void)
75 if (PyMac_OSErrException
== NULL
)
76 PyMac_OSErrException
= PyErr_NewException("MacOS.Error", NULL
, NULL
);
77 return PyMac_OSErrException
;
80 /* Set a MAC-specific error from errno, and return NULL; return None if no error */
82 PyErr_Mac(PyObject
*eobj
, int err
)
87 if (err
== 0 && !PyErr_Occurred()) {
91 if (err
== -1 && PyErr_Occurred())
93 msg
= PyMac_StrError(err
);
94 v
= Py_BuildValue("(is)", err
, msg
);
95 PyErr_SetObject(eobj
, v
);
100 /* Call PyErr_Mac with PyMac_OSErrException */
102 PyMac_Error(OSErr err
)
104 return PyErr_Mac(PyMac_GetOSErrException(), err
);
109 PyMac_GetFullPathname(FSSpec
*fss
, char *path
, int len
)
118 fs
= PyMac_BuildFSSpec(fss
);
122 rv
= PyObject_CallMethod(fs
, "as_pathname", "");
126 input
= PyString_AsString(rv
);
130 strncpy(path
, input
, len
- 1);
131 path
[len
- 1] = '\0';
138 exc
= PyErr_Occurred();
139 if (exc
&& PyErr_GivenExceptionMatches(exc
,
140 PyMac_GetOSErrException())) {
141 PyObject
*args
= PyObject_GetAttrString(exc
, "args");
144 PyArg_ParseTuple(args
, "is", &err
, &ignore
);
156 /* Convert a 4-char string object argument to an OSType value */
158 PyMac_GetOSType(PyObject
*v
, OSType
*pr
)
161 if (!PyString_Check(v
) || PyString_Size(v
) != 4) {
162 PyErr_SetString(PyExc_TypeError
,
163 "OSType arg must be string of 4 chars");
166 memcpy((char *)&tmp
, PyString_AsString(v
), 4);
167 *pr
= (OSType
)ntohl(tmp
);
171 /* Convert an OSType value to a 4-char string object */
173 PyMac_BuildOSType(OSType t
)
175 uint32_t tmp
= htonl((uint32_t)t
);
176 return PyString_FromStringAndSize((char *)&tmp
, 4);
179 /* Convert an NumVersion value to a 4-element tuple */
181 PyMac_BuildNumVersion(NumVersion t
)
183 return Py_BuildValue("(hhhh)", t
.majorRev
, t
.minorAndBugRev
, t
.stage
, t
.nonRelRev
);
187 /* Convert a Python string object to a Str255 */
189 PyMac_GetStr255(PyObject
*v
, Str255 pbuf
)
192 if (!PyString_Check(v
) || (len
= PyString_Size(v
)) > 255) {
193 PyErr_SetString(PyExc_TypeError
,
194 "Str255 arg must be string of at most 255 chars");
198 memcpy((char *)(pbuf
+1), PyString_AsString(v
), len
);
202 /* Convert a Str255 to a Python string object */
204 PyMac_BuildStr255(Str255 s
)
207 PyErr_SetString(PyExc_SystemError
, "Str255 pointer is NULL");
210 return PyString_FromStringAndSize((char *)&s
[1], (int)s
[0]);
214 PyMac_BuildOptStr255(Str255 s
)
220 return PyString_FromStringAndSize((char *)&s
[1], (int)s
[0]);
225 /* Convert a Python object to a Rect.
226 The object must be a (left, top, right, bottom) tuple.
227 (This differs from the order in the struct but is consistent with
228 the arguments to SetRect(), and also with STDWIN). */
230 PyMac_GetRect(PyObject
*v
, Rect
*r
)
232 return PyArg_Parse(v
, "(hhhh)", &r
->left
, &r
->top
, &r
->right
, &r
->bottom
);
235 /* Convert a Rect to a Python object */
237 PyMac_BuildRect(Rect
*r
)
239 return Py_BuildValue("(hhhh)", r
->left
, r
->top
, r
->right
, r
->bottom
);
243 /* Convert a Python object to a Point.
244 The object must be a (h, v) tuple.
245 (This differs from the order in the struct but is consistent with
246 the arguments to SetPoint(), and also with STDWIN). */
248 PyMac_GetPoint(PyObject
*v
, Point
*p
)
250 return PyArg_Parse(v
, "(hh)", &p
->h
, &p
->v
);
253 /* Convert a Point to a Python object */
255 PyMac_BuildPoint(Point p
)
257 return Py_BuildValue("(hh)", p
.h
, p
.v
);
261 /* Convert a Python object to an EventRecord.
262 The object must be a (what, message, when, (v, h), modifiers) tuple. */
264 PyMac_GetEventRecord(PyObject
*v
, EventRecord
*e
)
266 return PyArg_Parse(v
, "(Hkk(hh)H)",
275 /* Convert a Rect to an EventRecord object */
277 PyMac_BuildEventRecord(EventRecord
*e
)
279 return Py_BuildValue("(hll(hh)h)",
288 /* Convert Python object to Fixed */
290 PyMac_GetFixed(PyObject
*v
, Fixed
*f
)
294 if( !PyArg_Parse(v
, "d", &d
))
296 *f
= (Fixed
)(d
* 0x10000);
300 /* Convert a Fixed to a Python object */
302 PyMac_BuildFixed(Fixed f
)
308 return Py_BuildValue("d", d
);
311 /* Convert wide to/from Python int or (hi, lo) tuple. XXXX Should use Python longs */
313 PyMac_Getwide(PyObject
*v
, wide
*rv
)
315 if (PyInt_Check(v
)) {
317 rv
->lo
= PyInt_AsLong(v
);
318 if( rv
->lo
& 0x80000000 )
322 return PyArg_Parse(v
, "(kk)", &rv
->hi
, &rv
->lo
);
327 PyMac_Buildwide(wide
*w
)
329 if ( (w
->hi
== 0 && (w
->lo
& 0x80000000) == 0) ||
330 (w
->hi
== -1 && (w
->lo
& 0x80000000) ) )
331 return PyInt_FromLong(w
->lo
);
332 return Py_BuildValue("(ll)", w
->hi
, w
->lo
);
335 #ifdef USE_TOOLBOX_OBJECT_GLUE
337 ** Glue together the toolbox objects.
339 ** Because toolbox modules interdepend on each other, they use each others
340 ** object types, on MacOSX/MachO this leads to the situation that they
341 ** cannot be dynamically loaded (or they would all have to be lumped into
342 ** a single .so, but this would be bad for extensibility).
344 ** This file defines wrappers for all the _New and _Convert functions,
345 ** which are the Py_BuildValue and PyArg_ParseTuple helpers. The wrappers
346 ** check an indirection function pointer, and if it isn't filled in yet
347 ** they import the appropriate module, whose init routine should fill in
351 #define GLUE_NEW(object, routinename, module) \
352 PyObject *(*PyMacGluePtr_##routinename)(object); \
354 PyObject *routinename(object cobj) { \
355 if (!PyMacGluePtr_##routinename) { \
356 if (!PyImport_ImportModule(module)) return NULL; \
357 if (!PyMacGluePtr_##routinename) { \
358 PyErr_SetString(PyExc_ImportError, "Module did not provide routine: " module ": " #routinename); \
362 return (*PyMacGluePtr_##routinename)(cobj); \
365 #define GLUE_CONVERT(object, routinename, module) \
366 int (*PyMacGluePtr_##routinename)(PyObject *, object *); \
368 int routinename(PyObject *pyobj, object *cobj) { \
369 if (!PyMacGluePtr_##routinename) { \
370 if (!PyImport_ImportModule(module)) return 0; \
371 if (!PyMacGluePtr_##routinename) { \
372 PyErr_SetString(PyExc_ImportError, "Module did not provide routine: " module ": " #routinename); \
376 return (*PyMacGluePtr_##routinename)(pyobj, cobj); \
379 GLUE_NEW(FSSpec
*, PyMac_BuildFSSpec
, "Carbon.File")
380 GLUE_CONVERT(FSSpec
, PyMac_GetFSSpec
, "Carbon.File")
381 GLUE_NEW(FSRef
*, PyMac_BuildFSRef
, "Carbon.File")
382 GLUE_CONVERT(FSRef
, PyMac_GetFSRef
, "Carbon.File")
384 GLUE_NEW(AppleEvent
*, AEDesc_New
, "Carbon.AE") /* XXXX Why by address? */
385 GLUE_NEW(AppleEvent
*, AEDesc_NewBorrowed
, "Carbon.AE")
386 GLUE_CONVERT(AppleEvent
, AEDesc_Convert
, "Carbon.AE")
388 GLUE_NEW(Component
, CmpObj_New
, "Carbon.Cm")
389 GLUE_CONVERT(Component
, CmpObj_Convert
, "Carbon.Cm")
390 GLUE_NEW(ComponentInstance
, CmpInstObj_New
, "Carbon.Cm")
391 GLUE_CONVERT(ComponentInstance
, CmpInstObj_Convert
, "Carbon.Cm")
393 GLUE_NEW(ControlHandle
, CtlObj_New
, "Carbon.Ctl")
394 GLUE_CONVERT(ControlHandle
, CtlObj_Convert
, "Carbon.Ctl")
396 GLUE_NEW(DialogPtr
, DlgObj_New
, "Carbon.Dlg")
397 GLUE_CONVERT(DialogPtr
, DlgObj_Convert
, "Carbon.Dlg")
398 GLUE_NEW(DialogPtr
, DlgObj_WhichDialog
, "Carbon.Dlg")
400 GLUE_NEW(DragReference
, DragObj_New
, "Carbon.Drag")
401 GLUE_CONVERT(DragReference
, DragObj_Convert
, "Carbon.Drag")
403 GLUE_NEW(ListHandle
, ListObj_New
, "Carbon.List")
404 GLUE_CONVERT(ListHandle
, ListObj_Convert
, "Carbon.List")
406 GLUE_NEW(MenuHandle
, MenuObj_New
, "Carbon.Menu")
407 GLUE_CONVERT(MenuHandle
, MenuObj_Convert
, "Carbon.Menu")
409 GLUE_NEW(GrafPtr
, GrafObj_New
, "Carbon.Qd")
410 GLUE_CONVERT(GrafPtr
, GrafObj_Convert
, "Carbon.Qd")
411 GLUE_NEW(BitMapPtr
, BMObj_New
, "Carbon.Qd")
412 GLUE_CONVERT(BitMapPtr
, BMObj_Convert
, "Carbon.Qd")
413 GLUE_NEW(RGBColor
*, QdRGB_New
, "Carbon.Qd") /* XXXX Why? */
414 GLUE_CONVERT(RGBColor
, QdRGB_Convert
, "Carbon.Qd")
416 GLUE_NEW(GWorldPtr
, GWorldObj_New
, "Carbon.Qdoffs")
417 GLUE_CONVERT(GWorldPtr
, GWorldObj_Convert
, "Carbon.Qdoffs")
419 GLUE_NEW(Track
, TrackObj_New
, "Carbon.Qt")
420 GLUE_CONVERT(Track
, TrackObj_Convert
, "Carbon.Qt")
421 GLUE_NEW(Movie
, MovieObj_New
, "Carbon.Qt")
422 GLUE_CONVERT(Movie
, MovieObj_Convert
, "Carbon.Qt")
423 GLUE_NEW(MovieController
, MovieCtlObj_New
, "Carbon.Qt")
424 GLUE_CONVERT(MovieController
, MovieCtlObj_Convert
, "Carbon.Qt")
425 GLUE_NEW(TimeBase
, TimeBaseObj_New
, "Carbon.Qt")
426 GLUE_CONVERT(TimeBase
, TimeBaseObj_Convert
, "Carbon.Qt")
427 GLUE_NEW(UserData
, UserDataObj_New
, "Carbon.Qt")
428 GLUE_CONVERT(UserData
, UserDataObj_Convert
, "Carbon.Qt")
429 GLUE_NEW(Media
, MediaObj_New
, "Carbon.Qt")
430 GLUE_CONVERT(Media
, MediaObj_Convert
, "Carbon.Qt")
432 GLUE_NEW(Handle
, ResObj_New
, "Carbon.Res")
433 GLUE_CONVERT(Handle
, ResObj_Convert
, "Carbon.Res")
434 GLUE_NEW(Handle
, OptResObj_New
, "Carbon.Res")
435 GLUE_CONVERT(Handle
, OptResObj_Convert
, "Carbon.Res")
437 GLUE_NEW(TEHandle
, TEObj_New
, "Carbon.TE")
438 GLUE_CONVERT(TEHandle
, TEObj_Convert
, "Carbon.TE")
440 GLUE_NEW(WindowPtr
, WinObj_New
, "Carbon.Win")
441 GLUE_CONVERT(WindowPtr
, WinObj_Convert
, "Carbon.Win")
442 GLUE_NEW(WindowPtr
, WinObj_WhichWindow
, "Carbon.Win")
444 GLUE_CONVERT(CFTypeRef
, CFObj_Convert
, "Carbon.CF")
445 GLUE_NEW(CFTypeRef
, CFObj_New
, "Carbon.CF")
447 GLUE_CONVERT(CFTypeRef
, CFTypeRefObj_Convert
, "Carbon.CF")
448 GLUE_NEW(CFTypeRef
, CFTypeRefObj_New
, "Carbon.CF")
450 GLUE_CONVERT(CFStringRef
, CFStringRefObj_Convert
, "Carbon.CF")
451 GLUE_NEW(CFStringRef
, CFStringRefObj_New
, "Carbon.CF")
452 GLUE_CONVERT(CFMutableStringRef
, CFMutableStringRefObj_Convert
, "Carbon.CF")
453 GLUE_NEW(CFMutableStringRef
, CFMutableStringRefObj_New
, "Carbon.CF")
455 GLUE_CONVERT(CFArrayRef
, CFArrayRefObj_Convert
, "Carbon.CF")
456 GLUE_NEW(CFArrayRef
, CFArrayRefObj_New
, "Carbon.CF")
457 GLUE_CONVERT(CFMutableArrayRef
, CFMutableArrayRefObj_Convert
, "Carbon.CF")
458 GLUE_NEW(CFMutableArrayRef
, CFMutableArrayRefObj_New
, "Carbon.CF")
460 GLUE_CONVERT(CFDictionaryRef
, CFDictionaryRefObj_Convert
, "Carbon.CF")
461 GLUE_NEW(CFDictionaryRef
, CFDictionaryRefObj_New
, "Carbon.CF")
462 GLUE_CONVERT(CFMutableDictionaryRef
, CFMutableDictionaryRefObj_Convert
, "Carbon.CF")
463 GLUE_NEW(CFMutableDictionaryRef
, CFMutableDictionaryRefObj_New
, "Carbon.CF")
465 GLUE_CONVERT(CFURLRef
, CFURLRefObj_Convert
, "Carbon.CF")
466 GLUE_CONVERT(CFURLRef
, OptionalCFURLRefObj_Convert
, "Carbon.CF")
467 GLUE_NEW(CFURLRef
, CFURLRefObj_New
, "Carbon.CF")
469 #endif /* USE_TOOLBOX_OBJECT_GLUE */