This commit was manufactured by cvs2svn to create tag 'r22a4-fork'.
[python/dscho.git] / Python / mactoolboxglue.c
blob52ff00b470ad173e7869389dae3f5a9efe8cbfa7
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"
29 #ifdef WITHOUT_FRAMEWORKS
30 #include <Script.h>
31 #include <Resources.h>
32 #endif
35 ** Find out what the current script is.
36 ** Donated by Fredrik Lund.
38 char *PyMac_getscript()
40 int font, script, lang;
41 font = 0;
42 font = GetSysFont();
43 script = FontToScript(font);
44 switch (script) {
45 case smRoman:
46 lang = GetScriptVariable(script, smScriptLang);
47 if (lang == langIcelandic)
48 return "mac-iceland";
49 else if (lang == langTurkish)
50 return "mac-turkish";
51 else if (lang == langGreek)
52 return "mac-greek";
53 else
54 return "mac-roman";
55 break;
56 #if 0
57 /* We don't have a codec for this, so don't return it */
58 case smJapanese:
59 return "mac-japan";
60 #endif
61 case smGreek:
62 return "mac-greek";
63 case smCyrillic:
64 return "mac-cyrillic";
65 default:
66 return "ascii"; /* better than nothing */
70 /* Like strerror() but for Mac OS error numbers */
71 char *PyMac_StrError(int err)
73 static char buf[256];
74 Handle h;
75 char *str;
77 h = GetResource('Estr', err);
78 if ( h ) {
79 HLock(h);
80 str = (char *)*h;
81 memcpy(buf, str+1, (unsigned char)str[0]);
82 buf[(unsigned char)str[0]] = '\0';
83 HUnlock(h);
84 ReleaseResource(h);
85 } else {
86 sprintf(buf, "Mac OS error code %d", err);
88 return buf;
91 /* Exception object shared by all Mac specific modules for Mac OS errors */
92 PyObject *PyMac_OSErrException;
94 /* Initialize and return PyMac_OSErrException */
95 PyObject *
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 */
104 PyObject *
105 PyErr_Mac(PyObject *eobj, int err)
107 char *msg;
108 PyObject *v;
110 if (err == 0 && !PyErr_Occurred()) {
111 Py_INCREF(Py_None);
112 return Py_None;
114 if (err == -1 && PyErr_Occurred())
115 return NULL;
116 msg = PyMac_StrError(err);
117 v = Py_BuildValue("(is)", err, msg);
118 PyErr_SetObject(eobj, v);
119 Py_DECREF(v);
120 return NULL;
123 /* Call PyErr_Mac with PyMac_OSErrException */
124 PyObject *
125 PyMac_Error(OSErr err)
127 return PyErr_Mac(PyMac_GetOSErrException(), err);
131 #if TARGET_API_MAC_OSX
132 OSErr
133 PyMac_GetFullPathname(FSSpec *fss, char *path, int len)
135 FSRef fsr;
136 OSErr err;
138 *path = '\0';
139 err = FSpMakeFSRef(fss, &fsr);
140 if ( err == fnfErr ) {
141 /* FSSpecs can point to non-existing files, fsrefs can't. */
142 FSSpec fss2;
143 int tocopy;
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...
155 strcat(path, "/");
156 tocopy = fss->name[0];
157 if ( strlen(path) + tocopy >= len )
158 tocopy = len - strlen(path) - 1;
159 if ( tocopy > 0 )
160 strncat(path, fss->name+1, tocopy);
161 } else {
162 if ( err ) return err;
163 err = (OSErr)FSRefMakePath(&fsr, path, len);
164 if ( err ) return err;
166 return 0;
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");
177 return 0;
179 memcpy((char *)pr, PyString_AsString(v), 4);
180 return 1;
183 /* Convert an OSType value to a 4-char string object */
184 PyObject *
185 PyMac_BuildOSType(OSType t)
187 return PyString_FromStringAndSize((char *)&t, 4);
190 /* Convert an NumVersion value to a 4-element tuple */
191 PyObject *
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)
202 int len;
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");
206 return 0;
208 pbuf[0] = len;
209 memcpy((char *)(pbuf+1), PyString_AsString(v), len);
210 return 1;
213 /* Convert a Str255 to a Python string object */
214 PyObject *
215 PyMac_BuildStr255(Str255 s)
217 if ( s == NULL ) {
218 PyErr_SetString(PyExc_SystemError, "Str255 pointer is NULL");
219 return NULL;
221 return PyString_FromStringAndSize((char *)&s[1], (int)s[0]);
224 PyObject *
225 PyMac_BuildOptStr255(Str255 s)
227 if ( s == NULL ) {
228 Py_INCREF(Py_None);
229 return Py_None;
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 */
247 PyObject *
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 */
265 PyObject *
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)",
278 &e->what,
279 &e->message,
280 &e->when,
281 &e->where.h,
282 &e->where.v,
283 &e->modifiers);
286 /* Convert a Rect to an EventRecord object */
287 PyObject *
288 PyMac_BuildEventRecord(EventRecord *e)
290 return Py_BuildValue("(hll(hh)h)",
291 e->what,
292 e->message,
293 e->when,
294 e->where.h,
295 e->where.v,
296 e->modifiers);
299 /* Convert Python object to Fixed */
301 PyMac_GetFixed(PyObject *v, Fixed *f)
303 double d;
305 if( !PyArg_Parse(v, "d", &d))
306 return 0;
307 *f = (Fixed)(d * 0x10000);
308 return 1;
311 /* Convert a Fixed to a Python object */
312 PyObject *
313 PyMac_BuildFixed(Fixed f)
315 double d;
317 d = f;
318 d = d / 0x10000;
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)) {
327 rv->hi = 0;
328 rv->lo = PyInt_AsLong(v);
329 if( rv->lo & 0x80000000 )
330 rv->hi = -1;
331 return 1;
333 return PyArg_Parse(v, "(ll)", &rv->hi, &rv->lo);
337 PyObject *
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
359 ** the pointer.
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); \
370 return NULL; \
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); \
384 return NULL; \
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 */