Adding basic imputil documentation.
[python.git] / Python / mactoolboxglue.c
blob26a13083f367913358df95273d975bbf6fd452d3
1 /***********************************************************
2 Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
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 ******************************************************************/
26 #include "Python.h"
27 #include "pymactoolbox.h"
28 #include <arpa/inet.h> /* for ntohl, htonl */
31 /* Like strerror() but for Mac OS error numbers */
32 char *
33 PyMac_StrError(int err)
35 static char buf[256];
36 PyObject *m;
37 PyObject *rv;
39 m = PyImport_ImportModule("MacOS");
40 if (!m) {
41 if (Py_VerboseFlag)
42 PyErr_Print();
43 PyErr_Clear();
44 rv = NULL;
46 else {
47 rv = PyObject_CallMethod(m, "GetErrorString", "i", err);
48 if (!rv)
49 PyErr_Clear();
51 if (!rv) {
52 buf[0] = '\0';
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';
63 Py_DECREF(rv);
65 Py_XDECREF(m);
66 return buf;
69 /* Exception object shared by all Mac specific modules for Mac OS errors */
70 PyObject *PyMac_OSErrException;
72 /* Initialize and return PyMac_OSErrException */
73 PyObject *
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 */
82 PyObject *
83 PyErr_Mac(PyObject *eobj, int err)
85 char *msg;
86 PyObject *v;
88 if (err == 0 && !PyErr_Occurred()) {
89 Py_INCREF(Py_None);
90 return Py_None;
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;
101 /* Call PyErr_Mac with PyMac_OSErrException */
102 PyObject *
103 PyMac_Error(OSErr err)
105 return PyErr_Mac(PyMac_GetOSErrException(), err);
109 OSErr
110 PyMac_GetFullPathname(FSSpec *fss, char *path, int len)
112 PyObject *fs, *exc;
113 PyObject *rv = NULL;
114 char *input;
115 OSErr err = noErr;
117 *path = '\0';
119 fs = PyMac_BuildFSSpec(fss);
120 if (!fs)
121 goto error;
123 rv = PyObject_CallMethod(fs, "as_pathname", "");
124 if (!rv)
125 goto error;
127 input = PyString_AsString(rv);
128 if (!input)
129 goto error;
131 strncpy(path, input, len - 1);
132 path[len - 1] = '\0';
134 Py_XDECREF(rv);
135 Py_XDECREF(fs);
136 return err;
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);
149 if (err == noErr)
150 err = -1;
151 PyErr_Clear();
152 Py_XDECREF(rv);
153 Py_XDECREF(fs);
154 return err;
157 /* Convert a 4-char string object argument to an OSType value */
159 PyMac_GetOSType(PyObject *v, OSType *pr)
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;
167 memcpy((char *)&tmp, PyString_AsString(v), 4);
168 *pr = (OSType)ntohl(tmp);
169 return 1;
172 /* Convert an OSType value to a 4-char string object */
173 PyObject *
174 PyMac_BuildOSType(OSType t)
176 uint32_t tmp = htonl((uint32_t)t);
177 return PyString_FromStringAndSize((char *)&tmp, 4);
180 /* Convert an NumVersion value to a 4-element tuple */
181 PyObject *
182 PyMac_BuildNumVersion(NumVersion t)
184 return Py_BuildValue("(hhhh)", t.majorRev, t.minorAndBugRev, t.stage, t.nonRelRev);
188 /* Convert a Python string object to a Str255 */
190 PyMac_GetStr255(PyObject *v, Str255 pbuf)
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;
198 pbuf[0] = len;
199 memcpy((char *)(pbuf+1), PyString_AsString(v), len);
200 return 1;
203 /* Convert a Str255 to a Python string object */
204 PyObject *
205 PyMac_BuildStr255(Str255 s)
207 if ( s == NULL ) {
208 PyErr_SetString(PyExc_SystemError, "Str255 pointer is NULL");
209 return NULL;
211 return PyString_FromStringAndSize((char *)&s[1], (int)s[0]);
214 PyObject *
215 PyMac_BuildOptStr255(Str255 s)
217 if ( s == NULL ) {
218 Py_INCREF(Py_None);
219 return Py_None;
221 return PyString_FromStringAndSize((char *)&s[1], (int)s[0]);
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). */
231 PyMac_GetRect(PyObject *v, Rect *r)
233 return PyArg_Parse(v, "(hhhh)", &r->left, &r->top, &r->right, &r->bottom);
236 /* Convert a Rect to a Python object */
237 PyObject *
238 PyMac_BuildRect(Rect *r)
240 return Py_BuildValue("(hhhh)", r->left, r->top, r->right, r->bottom);
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). */
249 PyMac_GetPoint(PyObject *v, Point *p)
251 return PyArg_Parse(v, "(hh)", &p->h, &p->v);
254 /* Convert a Point to a Python object */
255 PyObject *
256 PyMac_BuildPoint(Point p)
258 return Py_BuildValue("(hh)", p.h, p.v);
262 /* Convert a Python object to an EventRecord.
263 The object must be a (what, message, when, (v, h), modifiers) tuple. */
265 PyMac_GetEventRecord(PyObject *v, EventRecord *e)
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);
276 /* Convert a Rect to an EventRecord object */
277 PyObject *
278 PyMac_BuildEventRecord(EventRecord *e)
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);
289 /* Convert Python object to Fixed */
291 PyMac_GetFixed(PyObject *v, Fixed *f)
293 double d;
295 if( !PyArg_Parse(v, "d", &d))
296 return 0;
297 *f = (Fixed)(d * 0x10000);
298 return 1;
301 /* Convert a Fixed to a Python object */
302 PyObject *
303 PyMac_BuildFixed(Fixed f)
305 double d;
307 d = f;
308 d = d / 0x10000;
309 return Py_BuildValue("d", d);
312 /* Convert wide to/from Python int or (hi, lo) tuple. XXXX Should use Python longs */
314 PyMac_Getwide(PyObject *v, wide *rv)
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;
323 return PyArg_Parse(v, "(kk)", &rv->hi, &rv->lo);
327 PyObject *
328 PyMac_Buildwide(wide *w)
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);
336 #ifdef USE_TOOLBOX_OBJECT_GLUE
338 ** Glue together the toolbox objects.
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).
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.
352 #define GLUE_NEW(object, routinename, module) \
353 PyObject *(*PyMacGluePtr_##routinename)(object); \
355 PyObject *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; \
363 return (*PyMacGluePtr_##routinename)(cobj); \
366 #define GLUE_CONVERT(object, routinename, module) \
367 int (*PyMacGluePtr_##routinename)(PyObject *, object *); \
369 int 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; \
377 return (*PyMacGluePtr_##routinename)(pyobj, cobj); \
380 GLUE_NEW(FSSpec *, PyMac_BuildFSSpec, "Carbon.File")
381 GLUE_CONVERT(FSSpec, PyMac_GetFSSpec, "Carbon.File")
382 GLUE_NEW(FSRef *, PyMac_BuildFSRef, "Carbon.File")
383 GLUE_CONVERT(FSRef, PyMac_GetFSRef, "Carbon.File")
385 GLUE_NEW(AppleEvent *, AEDesc_New, "Carbon.AE") /* XXXX Why by address? */
386 GLUE_NEW(AppleEvent *, AEDesc_NewBorrowed, "Carbon.AE")
387 GLUE_CONVERT(AppleEvent, AEDesc_Convert, "Carbon.AE")
389 GLUE_NEW(Component, CmpObj_New, "Carbon.Cm")
390 GLUE_CONVERT(Component, CmpObj_Convert, "Carbon.Cm")
391 GLUE_NEW(ComponentInstance, CmpInstObj_New, "Carbon.Cm")
392 GLUE_CONVERT(ComponentInstance, CmpInstObj_Convert, "Carbon.Cm")
394 GLUE_NEW(ControlHandle, CtlObj_New, "Carbon.Ctl")
395 GLUE_CONVERT(ControlHandle, CtlObj_Convert, "Carbon.Ctl")
397 GLUE_NEW(DialogPtr, DlgObj_New, "Carbon.Dlg")
398 GLUE_CONVERT(DialogPtr, DlgObj_Convert, "Carbon.Dlg")
399 GLUE_NEW(DialogPtr, DlgObj_WhichDialog, "Carbon.Dlg")
401 GLUE_NEW(DragReference, DragObj_New, "Carbon.Drag")
402 GLUE_CONVERT(DragReference, DragObj_Convert, "Carbon.Drag")
404 GLUE_NEW(ListHandle, ListObj_New, "Carbon.List")
405 GLUE_CONVERT(ListHandle, ListObj_Convert, "Carbon.List")
407 GLUE_NEW(MenuHandle, MenuObj_New, "Carbon.Menu")
408 GLUE_CONVERT(MenuHandle, MenuObj_Convert, "Carbon.Menu")
410 GLUE_NEW(GrafPtr, GrafObj_New, "Carbon.Qd")
411 GLUE_CONVERT(GrafPtr, GrafObj_Convert, "Carbon.Qd")
412 GLUE_NEW(BitMapPtr, BMObj_New, "Carbon.Qd")
413 GLUE_CONVERT(BitMapPtr, BMObj_Convert, "Carbon.Qd")
414 GLUE_NEW(RGBColor *, QdRGB_New, "Carbon.Qd") /* XXXX Why? */
415 GLUE_CONVERT(RGBColor, QdRGB_Convert, "Carbon.Qd")
417 GLUE_NEW(GWorldPtr, GWorldObj_New, "Carbon.Qdoffs")
418 GLUE_CONVERT(GWorldPtr, GWorldObj_Convert, "Carbon.Qdoffs")
420 GLUE_NEW(Track, TrackObj_New, "Carbon.Qt")
421 GLUE_CONVERT(Track, TrackObj_Convert, "Carbon.Qt")
422 GLUE_NEW(Movie, MovieObj_New, "Carbon.Qt")
423 GLUE_CONVERT(Movie, MovieObj_Convert, "Carbon.Qt")
424 GLUE_NEW(MovieController, MovieCtlObj_New, "Carbon.Qt")
425 GLUE_CONVERT(MovieController, MovieCtlObj_Convert, "Carbon.Qt")
426 GLUE_NEW(TimeBase, TimeBaseObj_New, "Carbon.Qt")
427 GLUE_CONVERT(TimeBase, TimeBaseObj_Convert, "Carbon.Qt")
428 GLUE_NEW(UserData, UserDataObj_New, "Carbon.Qt")
429 GLUE_CONVERT(UserData, UserDataObj_Convert, "Carbon.Qt")
430 GLUE_NEW(Media, MediaObj_New, "Carbon.Qt")
431 GLUE_CONVERT(Media, MediaObj_Convert, "Carbon.Qt")
433 GLUE_NEW(Handle, ResObj_New, "Carbon.Res")
434 GLUE_CONVERT(Handle, ResObj_Convert, "Carbon.Res")
435 GLUE_NEW(Handle, OptResObj_New, "Carbon.Res")
436 GLUE_CONVERT(Handle, OptResObj_Convert, "Carbon.Res")
438 GLUE_NEW(TEHandle, TEObj_New, "Carbon.TE")
439 GLUE_CONVERT(TEHandle, TEObj_Convert, "Carbon.TE")
441 GLUE_NEW(WindowPtr, WinObj_New, "Carbon.Win")
442 GLUE_CONVERT(WindowPtr, WinObj_Convert, "Carbon.Win")
443 GLUE_NEW(WindowPtr, WinObj_WhichWindow, "Carbon.Win")
445 GLUE_CONVERT(CFTypeRef, CFObj_Convert, "Carbon.CF")
446 GLUE_NEW(CFTypeRef, CFObj_New, "Carbon.CF")
448 GLUE_CONVERT(CFTypeRef, CFTypeRefObj_Convert, "Carbon.CF")
449 GLUE_NEW(CFTypeRef, CFTypeRefObj_New, "Carbon.CF")
451 GLUE_CONVERT(CFStringRef, CFStringRefObj_Convert, "Carbon.CF")
452 GLUE_NEW(CFStringRef, CFStringRefObj_New, "Carbon.CF")
453 GLUE_CONVERT(CFMutableStringRef, CFMutableStringRefObj_Convert, "Carbon.CF")
454 GLUE_NEW(CFMutableStringRef, CFMutableStringRefObj_New, "Carbon.CF")
456 GLUE_CONVERT(CFArrayRef, CFArrayRefObj_Convert, "Carbon.CF")
457 GLUE_NEW(CFArrayRef, CFArrayRefObj_New, "Carbon.CF")
458 GLUE_CONVERT(CFMutableArrayRef, CFMutableArrayRefObj_Convert, "Carbon.CF")
459 GLUE_NEW(CFMutableArrayRef, CFMutableArrayRefObj_New, "Carbon.CF")
461 GLUE_CONVERT(CFDictionaryRef, CFDictionaryRefObj_Convert, "Carbon.CF")
462 GLUE_NEW(CFDictionaryRef, CFDictionaryRefObj_New, "Carbon.CF")
463 GLUE_CONVERT(CFMutableDictionaryRef, CFMutableDictionaryRefObj_Convert, "Carbon.CF")
464 GLUE_NEW(CFMutableDictionaryRef, CFMutableDictionaryRefObj_New, "Carbon.CF")
466 GLUE_CONVERT(CFURLRef, CFURLRefObj_Convert, "Carbon.CF")
467 GLUE_CONVERT(CFURLRef, OptionalCFURLRefObj_Convert, "Carbon.CF")
468 GLUE_NEW(CFURLRef, CFURLRefObj_New, "Carbon.CF")
470 #endif /* USE_TOOLBOX_OBJECT_GLUE */