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"
29 #ifdef WITHOUT_FRAMEWORKS
31 #include <Resources.h>
35 ** Find out what the current script is.
36 ** Donated by Fredrik Lund.
38 char *PyMac_getscript()
40 int font
, script
, lang
;
43 script
= FontToScript(font
);
46 lang
= GetScriptVariable(script
, smScriptLang
);
47 if (lang
== langIcelandic
)
49 else if (lang
== langTurkish
)
51 else if (lang
== langGreek
)
57 /* We don't have a codec for this, so don't return it */
64 return "mac-cyrillic";
66 return "ascii"; /* better than nothing */
70 /* Like strerror() but for Mac OS error numbers */
71 char *PyMac_StrError(int err
)
77 h
= GetResource('Estr', err
);
81 memcpy(buf
, str
+1, (unsigned char)str
[0]);
82 buf
[(unsigned char)str
[0]] = '\0';
86 sprintf(buf
, "Mac OS error code %d", err
);
91 /* Exception object shared by all Mac specific modules for Mac OS errors */
92 PyObject
*PyMac_OSErrException
;
94 /* Initialize and return PyMac_OSErrException */
96 PyMac_GetOSErrException(void)
98 if (PyMac_OSErrException
== NULL
)
99 PyMac_OSErrException
= PyString_FromString("MacOS.Error");
100 return PyMac_OSErrException
;
103 /* Set a MAC-specific error from errno, and return NULL; return None if no error */
105 PyErr_Mac(PyObject
*eobj
, int err
)
110 if (err
== 0 && !PyErr_Occurred()) {
114 if (err
== -1 && PyErr_Occurred())
116 msg
= PyMac_StrError(err
);
117 v
= Py_BuildValue("(is)", err
, msg
);
118 PyErr_SetObject(eobj
, v
);
123 /* Call PyErr_Mac with PyMac_OSErrException */
125 PyMac_Error(OSErr err
)
127 return PyErr_Mac(PyMac_GetOSErrException(), err
);
131 #if TARGET_API_MAC_OSX
133 PyMac_GetFullPathname(FSSpec
*fss
, char *path
, int len
)
139 err
= FSpMakeFSRef(fss
, &fsr
);
140 if ( err
== fnfErr
) {
141 /* FSSpecs can point to non-existing files, fsrefs can't. */
145 err
= FSMakeFSSpec(fss
->vRefNum
, fss
->parID
, "", &fss2
);
146 if ( err
) return err
;
147 err
= FSpMakeFSRef(&fss2
, &fsr
);
148 if ( err
) return err
;
149 err
= (OSErr
)FSRefMakePath(&fsr
, path
, len
-1);
150 if ( err
) return err
;
151 /* This part is not 100% safe: we append the filename part, but
152 ** I'm not sure that we don't run afoul of the various 8bit
153 ** encodings here. Will have to look this up at some point...
156 tocopy
= fss
->name
[0];
157 if ( strlen(path
) + tocopy
>= len
)
158 tocopy
= len
- strlen(path
) - 1;
160 strncat(path
, fss
->name
+1, tocopy
);
162 if ( err
) return err
;
163 err
= (OSErr
)FSRefMakePath(&fsr
, path
, len
);
164 if ( err
) return err
;
169 #endif /* TARGET_API_MAC_OSX */
170 /* Convert a 4-char string object argument to an OSType value */
172 PyMac_GetOSType(PyObject
*v
, OSType
*pr
)
174 if (!PyString_Check(v
) || PyString_Size(v
) != 4) {
175 PyErr_SetString(PyExc_TypeError
,
176 "OSType arg must be string of 4 chars");
179 memcpy((char *)pr
, PyString_AsString(v
), 4);
183 /* Convert an OSType value to a 4-char string object */
185 PyMac_BuildOSType(OSType t
)
187 return PyString_FromStringAndSize((char *)&t
, 4);
190 /* Convert an NumVersion value to a 4-element tuple */
192 PyMac_BuildNumVersion(NumVersion t
)
194 return Py_BuildValue("(hhhh)", t
.majorRev
, t
.minorAndBugRev
, t
.stage
, t
.nonRelRev
);
198 /* Convert a Python string object to a Str255 */
200 PyMac_GetStr255(PyObject
*v
, Str255 pbuf
)
203 if (!PyString_Check(v
) || (len
= PyString_Size(v
)) > 255) {
204 PyErr_SetString(PyExc_TypeError
,
205 "Str255 arg must be string of at most 255 chars");
209 memcpy((char *)(pbuf
+1), PyString_AsString(v
), len
);
213 /* Convert a Str255 to a Python string object */
215 PyMac_BuildStr255(Str255 s
)
218 PyErr_SetString(PyExc_SystemError
, "Str255 pointer is NULL");
221 return PyString_FromStringAndSize((char *)&s
[1], (int)s
[0]);
225 PyMac_BuildOptStr255(Str255 s
)
231 return PyString_FromStringAndSize((char *)&s
[1], (int)s
[0]);
236 /* Convert a Python object to a Rect.
237 The object must be a (left, top, right, bottom) tuple.
238 (This differs from the order in the struct but is consistent with
239 the arguments to SetRect(), and also with STDWIN). */
241 PyMac_GetRect(PyObject
*v
, Rect
*r
)
243 return PyArg_Parse(v
, "(hhhh)", &r
->left
, &r
->top
, &r
->right
, &r
->bottom
);
246 /* Convert a Rect to a Python object */
248 PyMac_BuildRect(Rect
*r
)
250 return Py_BuildValue("(hhhh)", r
->left
, r
->top
, r
->right
, r
->bottom
);
254 /* Convert a Python object to a Point.
255 The object must be a (h, v) tuple.
256 (This differs from the order in the struct but is consistent with
257 the arguments to SetPoint(), and also with STDWIN). */
259 PyMac_GetPoint(PyObject
*v
, Point
*p
)
261 return PyArg_Parse(v
, "(hh)", &p
->h
, &p
->v
);
264 /* Convert a Point to a Python object */
266 PyMac_BuildPoint(Point p
)
268 return Py_BuildValue("(hh)", p
.h
, p
.v
);
272 /* Convert a Python object to an EventRecord.
273 The object must be a (what, message, when, (v, h), modifiers) tuple. */
275 PyMac_GetEventRecord(PyObject
*v
, EventRecord
*e
)
277 return PyArg_Parse(v
, "(Hll(hh)H)",
286 /* Convert a Rect to an EventRecord object */
288 PyMac_BuildEventRecord(EventRecord
*e
)
290 return Py_BuildValue("(hll(hh)h)",
299 /* Convert Python object to Fixed */
301 PyMac_GetFixed(PyObject
*v
, Fixed
*f
)
305 if( !PyArg_Parse(v
, "d", &d
))
307 *f
= (Fixed
)(d
* 0x10000);
311 /* Convert a Fixed to a Python object */
313 PyMac_BuildFixed(Fixed f
)
319 return Py_BuildValue("d", d
);
322 /* Convert wide to/from Python int or (hi, lo) tuple. XXXX Should use Python longs */
324 PyMac_Getwide(PyObject
*v
, wide
*rv
)
326 if (PyInt_Check(v
)) {
328 rv
->lo
= PyInt_AsLong(v
);
329 if( rv
->lo
& 0x80000000 )
333 return PyArg_Parse(v
, "(ll)", &rv
->hi
, &rv
->lo
);
338 PyMac_Buildwide(wide
*w
)
340 if ( (w
->hi
== 0 && (w
->lo
& 0x80000000) == 0) ||
341 (w
->hi
== -1 && (w
->lo
& 0x80000000) ) )
342 return PyInt_FromLong(w
->lo
);
343 return Py_BuildValue("(ll)", w
->hi
, w
->lo
);
346 #ifdef USE_TOOLBOX_OBJECT_GLUE
348 ** Glue together the toolbox objects.
350 ** Because toolbox modules interdepend on each other, they use each others
351 ** object types, on MacOSX/MachO this leads to the situation that they
352 ** cannot be dynamically loaded (or they would all have to be lumped into
353 ** a single .so, but this would be bad for extensibility).
355 ** This file defines wrappers for all the _New and _Convert functions,
356 ** which are the Py_BuildValue and PyArg_ParseTuple helpers. The wrappers
357 ** check an indirection function pointer, and if it isn't filled in yet
358 ** they import the appropriate module, whose init routine should fill in
362 #define GLUE_NEW(object, routinename, module) \
363 PyObject *(*PyMacGluePtr_##routinename)(object); \
365 PyObject *routinename(object cobj) { \
366 if (!PyMacGluePtr_##routinename) { \
367 if (!PyImport_ImportModule(module)) return NULL; \
368 if (!PyMacGluePtr_##routinename) { \
369 PyErr_SetString(PyExc_ImportError, "Module did not provide routine: " module ": " #routinename); \
373 return (*PyMacGluePtr_##routinename)(cobj); \
376 #define GLUE_CONVERT(object, routinename, module) \
377 int (*PyMacGluePtr_##routinename)(PyObject *, object *); \
379 int routinename(PyObject *pyobj, object *cobj) { \
380 if (!PyMacGluePtr_##routinename) { \
381 if (!PyImport_ImportModule(module)) return NULL; \
382 if (!PyMacGluePtr_##routinename) { \
383 PyErr_SetString(PyExc_ImportError, "Module did not provide routine: " module ": " #routinename); \
387 return (*PyMacGluePtr_##routinename)(pyobj, cobj); \
390 GLUE_NEW(FSSpec
*, PyMac_BuildFSSpec
, "macfs")
391 GLUE_CONVERT(FSSpec
, PyMac_GetFSSpec
, "macfs")
392 GLUE_NEW(FSRef
*, PyMac_BuildFSRef
, "macfs")
393 GLUE_CONVERT(FSRef
, PyMac_GetFSRef
, "macfs")
395 GLUE_NEW(AppleEvent
*, AEDesc_New
, "Carbon.AE") /* XXXX Why by address? */
396 GLUE_CONVERT(AppleEvent
, AEDesc_Convert
, "Carbon.AE")
398 GLUE_NEW(Component
, CmpObj_New
, "Carbon.Cm")
399 GLUE_CONVERT(Component
, CmpObj_Convert
, "Carbon.Cm")
400 GLUE_NEW(ComponentInstance
, CmpInstObj_New
, "Carbon.Cm")
401 GLUE_CONVERT(ComponentInstance
, CmpInstObj_Convert
, "Carbon.Cm")
403 GLUE_NEW(ControlHandle
, CtlObj_New
, "Carbon.Ctl")
404 GLUE_CONVERT(ControlHandle
, CtlObj_Convert
, "Carbon.Ctl")
406 GLUE_NEW(DialogPtr
, DlgObj_New
, "Carbon.Dlg")
407 GLUE_CONVERT(DialogPtr
, DlgObj_Convert
, "Carbon.Dlg")
408 GLUE_NEW(DialogPtr
, DlgObj_WhichDialog
, "Carbon.Dlg")
410 GLUE_NEW(DragReference
, DragObj_New
, "Carbon.Drag")
411 GLUE_CONVERT(DragReference
, DragObj_Convert
, "Carbon.Drag")
413 GLUE_NEW(ListHandle
, ListObj_New
, "Carbon.List")
414 GLUE_CONVERT(ListHandle
, ListObj_Convert
, "Carbon.List")
416 GLUE_NEW(MenuHandle
, MenuObj_New
, "Carbon.Menu")
417 GLUE_CONVERT(MenuHandle
, MenuObj_Convert
, "Carbon.Menu")
419 GLUE_NEW(GrafPtr
, GrafObj_New
, "Carbon.Qd")
420 GLUE_CONVERT(GrafPtr
, GrafObj_Convert
, "Carbon.Qd")
421 GLUE_NEW(BitMapPtr
, BMObj_New
, "Carbon.Qd")
422 GLUE_CONVERT(BitMapPtr
, BMObj_Convert
, "Carbon.Qd")
423 GLUE_NEW(RGBColor
*, QdRGB_New
, "Carbon.Qd") /* XXXX Why? */
424 GLUE_CONVERT(RGBColor
, QdRGB_Convert
, "Carbon.Qd")
426 GLUE_NEW(GWorldPtr
, GWorldObj_New
, "Carbon.Qdoffs")
427 GLUE_CONVERT(GWorldPtr
, GWorldObj_Convert
, "Carbon.Qdoffs")
429 GLUE_NEW(Track
, TrackObj_New
, "Carbon.Qt")
430 GLUE_CONVERT(Track
, TrackObj_Convert
, "Carbon.Qt")
431 GLUE_NEW(Movie
, MovieObj_New
, "Carbon.Qt")
432 GLUE_CONVERT(Movie
, MovieObj_Convert
, "Carbon.Qt")
433 GLUE_NEW(MovieController
, MovieCtlObj_New
, "Carbon.Qt")
434 GLUE_CONVERT(MovieController
, MovieCtlObj_Convert
, "Carbon.Qt")
435 GLUE_NEW(TimeBase
, TimeBaseObj_New
, "Carbon.Qt")
436 GLUE_CONVERT(TimeBase
, TimeBaseObj_Convert
, "Carbon.Qt")
437 GLUE_NEW(UserData
, UserDataObj_New
, "Carbon.Qt")
438 GLUE_CONVERT(UserData
, UserDataObj_Convert
, "Carbon.Qt")
439 GLUE_NEW(Media
, MediaObj_New
, "Carbon.Qt")
440 GLUE_CONVERT(Media
, MediaObj_Convert
, "Carbon.Qt")
442 GLUE_NEW(Handle
, ResObj_New
, "Carbon.Res")
443 GLUE_CONVERT(Handle
, ResObj_Convert
, "Carbon.Res")
444 GLUE_NEW(Handle
, OptResObj_New
, "Carbon.Res")
445 GLUE_CONVERT(Handle
, OptResObj_Convert
, "Carbon.Res")
447 GLUE_NEW(TEHandle
, TEObj_New
, "Carbon.TE")
448 GLUE_CONVERT(TEHandle
, TEObj_Convert
, "Carbon.TE")
450 GLUE_NEW(WindowPtr
, WinObj_New
, "Carbon.Win")
451 GLUE_CONVERT(WindowPtr
, WinObj_Convert
, "Carbon.Win")
452 GLUE_NEW(WindowPtr
, WinObj_WhichWindow
, "Carbon.Win")
454 #endif /* USE_TOOLBOX_OBJECT_GLUE */