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"
30 /* Like strerror() but for Mac OS error numbers */
32 PyMac_StrError(int err
)
38 m
= PyImport_ImportModule("MacOS");
46 rv
= PyObject_CallMethod(m
, "GetErrorString", "i", err
);
54 char *input
= PyString_AsString(rv
);
59 strncpy(buf
, input
, sizeof(buf
) - 1);
60 buf
[sizeof(buf
) - 1] = '\0';
67 /* Exception object shared by all Mac specific modules for Mac OS errors */
68 PyObject
*PyMac_OSErrException
;
70 /* Initialize and return PyMac_OSErrException */
72 PyMac_GetOSErrException(void)
74 if (PyMac_OSErrException
== NULL
)
75 PyMac_OSErrException
= PyErr_NewException("MacOS.Error", NULL
, NULL
);
76 return PyMac_OSErrException
;
79 /* Set a MAC-specific error from errno, and return NULL; return None if no error */
81 PyErr_Mac(PyObject
*eobj
, int err
)
86 if (err
== 0 && !PyErr_Occurred()) {
90 if (err
== -1 && PyErr_Occurred())
92 msg
= PyMac_StrError(err
);
93 v
= Py_BuildValue("(is)", err
, msg
);
94 PyErr_SetObject(eobj
, v
);
99 /* Call PyErr_Mac with PyMac_OSErrException */
101 PyMac_Error(OSErr err
)
103 return PyErr_Mac(PyMac_GetOSErrException(), err
);
108 PyMac_GetFullPathname(FSSpec
*fss
, char *path
, int len
)
117 fs
= PyMac_BuildFSSpec(fss
);
121 rv
= PyObject_CallMethod(fs
, "as_pathname", "");
125 input
= PyString_AsString(rv
);
129 strncpy(path
, input
, len
- 1);
130 path
[len
- 1] = '\0';
137 exc
= PyErr_Occurred();
138 if (exc
&& PyErr_GivenExceptionMatches(exc
,
139 PyMac_GetOSErrException())) {
140 PyObject
*args
= PyObject_GetAttrString(exc
, "args");
143 PyArg_ParseTuple(args
, "is", &err
, &ignore
);
155 /* Convert a 4-char string object argument to an OSType value */
157 PyMac_GetOSType(PyObject
*v
, OSType
*pr
)
159 if (!PyString_Check(v
) || PyString_Size(v
) != 4) {
160 PyErr_SetString(PyExc_TypeError
,
161 "OSType arg must be string of 4 chars");
164 memcpy((char *)pr
, PyString_AsString(v
), 4);
168 /* Convert an OSType value to a 4-char string object */
170 PyMac_BuildOSType(OSType t
)
172 return PyString_FromStringAndSize((char *)&t
, 4);
175 /* Convert an NumVersion value to a 4-element tuple */
177 PyMac_BuildNumVersion(NumVersion t
)
179 return Py_BuildValue("(hhhh)", t
.majorRev
, t
.minorAndBugRev
, t
.stage
, t
.nonRelRev
);
183 /* Convert a Python string object to a Str255 */
185 PyMac_GetStr255(PyObject
*v
, Str255 pbuf
)
188 if (!PyString_Check(v
) || (len
= PyString_Size(v
)) > 255) {
189 PyErr_SetString(PyExc_TypeError
,
190 "Str255 arg must be string of at most 255 chars");
194 memcpy((char *)(pbuf
+1), PyString_AsString(v
), len
);
198 /* Convert a Str255 to a Python string object */
200 PyMac_BuildStr255(Str255 s
)
203 PyErr_SetString(PyExc_SystemError
, "Str255 pointer is NULL");
206 return PyString_FromStringAndSize((char *)&s
[1], (int)s
[0]);
210 PyMac_BuildOptStr255(Str255 s
)
216 return PyString_FromStringAndSize((char *)&s
[1], (int)s
[0]);
221 /* Convert a Python object to a Rect.
222 The object must be a (left, top, right, bottom) tuple.
223 (This differs from the order in the struct but is consistent with
224 the arguments to SetRect(), and also with STDWIN). */
226 PyMac_GetRect(PyObject
*v
, Rect
*r
)
228 return PyArg_Parse(v
, "(hhhh)", &r
->left
, &r
->top
, &r
->right
, &r
->bottom
);
231 /* Convert a Rect to a Python object */
233 PyMac_BuildRect(Rect
*r
)
235 return Py_BuildValue("(hhhh)", r
->left
, r
->top
, r
->right
, r
->bottom
);
239 /* Convert a Python object to a Point.
240 The object must be a (h, v) tuple.
241 (This differs from the order in the struct but is consistent with
242 the arguments to SetPoint(), and also with STDWIN). */
244 PyMac_GetPoint(PyObject
*v
, Point
*p
)
246 return PyArg_Parse(v
, "(hh)", &p
->h
, &p
->v
);
249 /* Convert a Point to a Python object */
251 PyMac_BuildPoint(Point p
)
253 return Py_BuildValue("(hh)", p
.h
, p
.v
);
257 /* Convert a Python object to an EventRecord.
258 The object must be a (what, message, when, (v, h), modifiers) tuple. */
260 PyMac_GetEventRecord(PyObject
*v
, EventRecord
*e
)
262 return PyArg_Parse(v
, "(Hkk(hh)H)",
271 /* Convert a Rect to an EventRecord object */
273 PyMac_BuildEventRecord(EventRecord
*e
)
275 return Py_BuildValue("(hll(hh)h)",
284 /* Convert Python object to Fixed */
286 PyMac_GetFixed(PyObject
*v
, Fixed
*f
)
290 if( !PyArg_Parse(v
, "d", &d
))
292 *f
= (Fixed
)(d
* 0x10000);
296 /* Convert a Fixed to a Python object */
298 PyMac_BuildFixed(Fixed f
)
304 return Py_BuildValue("d", d
);
307 /* Convert wide to/from Python int or (hi, lo) tuple. XXXX Should use Python longs */
309 PyMac_Getwide(PyObject
*v
, wide
*rv
)
311 if (PyInt_Check(v
)) {
313 rv
->lo
= PyInt_AsLong(v
);
314 if( rv
->lo
& 0x80000000 )
318 return PyArg_Parse(v
, "(kk)", &rv
->hi
, &rv
->lo
);
323 PyMac_Buildwide(wide
*w
)
325 if ( (w
->hi
== 0 && (w
->lo
& 0x80000000) == 0) ||
326 (w
->hi
== -1 && (w
->lo
& 0x80000000) ) )
327 return PyInt_FromLong(w
->lo
);
328 return Py_BuildValue("(ll)", w
->hi
, w
->lo
);
331 #ifdef USE_TOOLBOX_OBJECT_GLUE
333 ** Glue together the toolbox objects.
335 ** Because toolbox modules interdepend on each other, they use each others
336 ** object types, on MacOSX/MachO this leads to the situation that they
337 ** cannot be dynamically loaded (or they would all have to be lumped into
338 ** a single .so, but this would be bad for extensibility).
340 ** This file defines wrappers for all the _New and _Convert functions,
341 ** which are the Py_BuildValue and PyArg_ParseTuple helpers. The wrappers
342 ** check an indirection function pointer, and if it isn't filled in yet
343 ** they import the appropriate module, whose init routine should fill in
347 #define GLUE_NEW(object, routinename, module) \
348 PyObject *(*PyMacGluePtr_##routinename)(object); \
350 PyObject *routinename(object cobj) { \
351 if (!PyMacGluePtr_##routinename) { \
352 if (!PyImport_ImportModule(module)) return NULL; \
353 if (!PyMacGluePtr_##routinename) { \
354 PyErr_SetString(PyExc_ImportError, "Module did not provide routine: " module ": " #routinename); \
358 return (*PyMacGluePtr_##routinename)(cobj); \
361 #define GLUE_CONVERT(object, routinename, module) \
362 int (*PyMacGluePtr_##routinename)(PyObject *, object *); \
364 int routinename(PyObject *pyobj, object *cobj) { \
365 if (!PyMacGluePtr_##routinename) { \
366 if (!PyImport_ImportModule(module)) return NULL; \
367 if (!PyMacGluePtr_##routinename) { \
368 PyErr_SetString(PyExc_ImportError, "Module did not provide routine: " module ": " #routinename); \
372 return (*PyMacGluePtr_##routinename)(pyobj, cobj); \
375 GLUE_NEW(FSSpec
*, PyMac_BuildFSSpec
, "Carbon.File")
376 GLUE_CONVERT(FSSpec
, PyMac_GetFSSpec
, "Carbon.File")
377 GLUE_NEW(FSRef
*, PyMac_BuildFSRef
, "Carbon.File")
378 GLUE_CONVERT(FSRef
, PyMac_GetFSRef
, "Carbon.File")
380 GLUE_NEW(AppleEvent
*, AEDesc_New
, "Carbon.AE") /* XXXX Why by address? */
381 GLUE_NEW(AppleEvent
*, AEDesc_NewBorrowed
, "Carbon.AE")
382 GLUE_CONVERT(AppleEvent
, AEDesc_Convert
, "Carbon.AE")
384 GLUE_NEW(Component
, CmpObj_New
, "Carbon.Cm")
385 GLUE_CONVERT(Component
, CmpObj_Convert
, "Carbon.Cm")
386 GLUE_NEW(ComponentInstance
, CmpInstObj_New
, "Carbon.Cm")
387 GLUE_CONVERT(ComponentInstance
, CmpInstObj_Convert
, "Carbon.Cm")
389 GLUE_NEW(ControlHandle
, CtlObj_New
, "Carbon.Ctl")
390 GLUE_CONVERT(ControlHandle
, CtlObj_Convert
, "Carbon.Ctl")
392 GLUE_NEW(DialogPtr
, DlgObj_New
, "Carbon.Dlg")
393 GLUE_CONVERT(DialogPtr
, DlgObj_Convert
, "Carbon.Dlg")
394 GLUE_NEW(DialogPtr
, DlgObj_WhichDialog
, "Carbon.Dlg")
396 GLUE_NEW(DragReference
, DragObj_New
, "Carbon.Drag")
397 GLUE_CONVERT(DragReference
, DragObj_Convert
, "Carbon.Drag")
399 GLUE_NEW(ListHandle
, ListObj_New
, "Carbon.List")
400 GLUE_CONVERT(ListHandle
, ListObj_Convert
, "Carbon.List")
402 GLUE_NEW(MenuHandle
, MenuObj_New
, "Carbon.Menu")
403 GLUE_CONVERT(MenuHandle
, MenuObj_Convert
, "Carbon.Menu")
405 GLUE_NEW(GrafPtr
, GrafObj_New
, "Carbon.Qd")
406 GLUE_CONVERT(GrafPtr
, GrafObj_Convert
, "Carbon.Qd")
407 GLUE_NEW(BitMapPtr
, BMObj_New
, "Carbon.Qd")
408 GLUE_CONVERT(BitMapPtr
, BMObj_Convert
, "Carbon.Qd")
409 GLUE_NEW(RGBColor
*, QdRGB_New
, "Carbon.Qd") /* XXXX Why? */
410 GLUE_CONVERT(RGBColor
, QdRGB_Convert
, "Carbon.Qd")
412 GLUE_NEW(GWorldPtr
, GWorldObj_New
, "Carbon.Qdoffs")
413 GLUE_CONVERT(GWorldPtr
, GWorldObj_Convert
, "Carbon.Qdoffs")
415 GLUE_NEW(Track
, TrackObj_New
, "Carbon.Qt")
416 GLUE_CONVERT(Track
, TrackObj_Convert
, "Carbon.Qt")
417 GLUE_NEW(Movie
, MovieObj_New
, "Carbon.Qt")
418 GLUE_CONVERT(Movie
, MovieObj_Convert
, "Carbon.Qt")
419 GLUE_NEW(MovieController
, MovieCtlObj_New
, "Carbon.Qt")
420 GLUE_CONVERT(MovieController
, MovieCtlObj_Convert
, "Carbon.Qt")
421 GLUE_NEW(TimeBase
, TimeBaseObj_New
, "Carbon.Qt")
422 GLUE_CONVERT(TimeBase
, TimeBaseObj_Convert
, "Carbon.Qt")
423 GLUE_NEW(UserData
, UserDataObj_New
, "Carbon.Qt")
424 GLUE_CONVERT(UserData
, UserDataObj_Convert
, "Carbon.Qt")
425 GLUE_NEW(Media
, MediaObj_New
, "Carbon.Qt")
426 GLUE_CONVERT(Media
, MediaObj_Convert
, "Carbon.Qt")
428 GLUE_NEW(Handle
, ResObj_New
, "Carbon.Res")
429 GLUE_CONVERT(Handle
, ResObj_Convert
, "Carbon.Res")
430 GLUE_NEW(Handle
, OptResObj_New
, "Carbon.Res")
431 GLUE_CONVERT(Handle
, OptResObj_Convert
, "Carbon.Res")
433 GLUE_NEW(TEHandle
, TEObj_New
, "Carbon.TE")
434 GLUE_CONVERT(TEHandle
, TEObj_Convert
, "Carbon.TE")
436 GLUE_NEW(WindowPtr
, WinObj_New
, "Carbon.Win")
437 GLUE_CONVERT(WindowPtr
, WinObj_Convert
, "Carbon.Win")
438 GLUE_NEW(WindowPtr
, WinObj_WhichWindow
, "Carbon.Win")
440 GLUE_CONVERT(CFTypeRef
, CFObj_Convert
, "Carbon.CF")
441 GLUE_NEW(CFTypeRef
, CFObj_New
, "Carbon.CF")
443 GLUE_CONVERT(CFTypeRef
, CFTypeRefObj_Convert
, "Carbon.CF")
444 GLUE_NEW(CFTypeRef
, CFTypeRefObj_New
, "Carbon.CF")
446 GLUE_CONVERT(CFStringRef
, CFStringRefObj_Convert
, "Carbon.CF")
447 GLUE_NEW(CFStringRef
, CFStringRefObj_New
, "Carbon.CF")
448 GLUE_CONVERT(CFMutableStringRef
, CFMutableStringRefObj_Convert
, "Carbon.CF")
449 GLUE_NEW(CFMutableStringRef
, CFMutableStringRefObj_New
, "Carbon.CF")
451 GLUE_CONVERT(CFArrayRef
, CFArrayRefObj_Convert
, "Carbon.CF")
452 GLUE_NEW(CFArrayRef
, CFArrayRefObj_New
, "Carbon.CF")
453 GLUE_CONVERT(CFMutableArrayRef
, CFMutableArrayRefObj_Convert
, "Carbon.CF")
454 GLUE_NEW(CFMutableArrayRef
, CFMutableArrayRefObj_New
, "Carbon.CF")
456 GLUE_CONVERT(CFDictionaryRef
, CFDictionaryRefObj_Convert
, "Carbon.CF")
457 GLUE_NEW(CFDictionaryRef
, CFDictionaryRefObj_New
, "Carbon.CF")
458 GLUE_CONVERT(CFMutableDictionaryRef
, CFMutableDictionaryRefObj_Convert
, "Carbon.CF")
459 GLUE_NEW(CFMutableDictionaryRef
, CFMutableDictionaryRefObj_New
, "Carbon.CF")
461 GLUE_CONVERT(CFURLRef
, CFURLRefObj_Convert
, "Carbon.CF")
462 GLUE_CONVERT(CFURLRef
, OptionalCFURLRefObj_Convert
, "Carbon.CF")
463 GLUE_NEW(CFURLRef
, CFURLRefObj_New
, "Carbon.CF")
465 #endif /* USE_TOOLBOX_OBJECT_GLUE */