blob: 2d7c461b87df95e4fbdab5012810529416d20053 [file] [log] [blame]
Jack Jansen94bebc02001-08-08 13:17:31 +00001/***********************************************************
2Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
25
26#include "Python.h"
27
28//#include "macglue.h"
29//#include "marshal.h"
30//#include "import.h"
31//#include "importdl.h"
32#include "pymactoolbox.h"
33
34//#include "pythonresources.h"
35
36#ifdef WITHOUT_FRAMEWORKS
37//#include <OSUtils.h> /* for Set(Current)A5 */
38//#include <Files.h>
39//#include <StandardFile.h>
40//#include <Resources.h>
41//#include <Memory.h>
42//#include <Windows.h>
43//#include <Traps.h>
44//#include <Processes.h>
45//#include <Fonts.h>
46//#include <Menus.h>
47//#include <TextUtils.h>
48//#include <LowMem.h>
49//#include <Events.h>
50#else
51//#include <Carbon/Carbon.h>
52#endif
53
54/*
55** Find out what the current script is.
56** Donated by Fredrik Lund.
57*/
58char *PyMac_getscript()
59{
60 int font, script, lang;
61 font = 0;
62 font = GetSysFont();
63 script = FontToScript(font);
64 switch (script) {
65 case smRoman:
66 lang = GetScriptVariable(script, smScriptLang);
67 if (lang == langIcelandic)
68 return "mac-iceland";
69 else if (lang == langTurkish)
70 return "mac-turkish";
71 else if (lang == langGreek)
72 return "mac-greek";
73 else
74 return "mac-roman";
75 break;
76#if 0
77 /* We don't have a codec for this, so don't return it */
78 case smJapanese:
79 return "mac-japan";
80#endif
81 case smGreek:
82 return "mac-greek";
83 case smCyrillic:
84 return "mac-cyrillic";
85 default:
86 return "ascii"; /* better than nothing */
87 }
88}
89
90/* Like strerror() but for Mac OS error numbers */
91char *PyMac_StrError(int err)
92{
93 static char buf[256];
94 Handle h;
95 char *str;
96
97 h = GetResource('Estr', err);
98 if ( h ) {
99 HLock(h);
100 str = (char *)*h;
101 memcpy(buf, str+1, (unsigned char)str[0]);
102 buf[(unsigned char)str[0]] = '\0';
103 HUnlock(h);
104 ReleaseResource(h);
105 } else {
106 sprintf(buf, "Mac OS error code %d", err);
107 }
108 return buf;
109}
110
111/* Exception object shared by all Mac specific modules for Mac OS errors */
112PyObject *PyMac_OSErrException;
113
114/* Initialize and return PyMac_OSErrException */
115PyObject *
116PyMac_GetOSErrException()
117{
118 if (PyMac_OSErrException == NULL)
119 PyMac_OSErrException = PyString_FromString("MacOS.Error");
120 return PyMac_OSErrException;
121}
122
123/* Set a MAC-specific error from errno, and return NULL; return None if no error */
124PyObject *
125PyErr_Mac(PyObject *eobj, int err)
126{
127 char *msg;
128 PyObject *v;
129
130 if (err == 0 && !PyErr_Occurred()) {
131 Py_INCREF(Py_None);
132 return Py_None;
133 }
134 if (err == -1 && PyErr_Occurred())
135 return NULL;
136 msg = PyMac_StrError(err);
137 v = Py_BuildValue("(is)", err, msg);
138 PyErr_SetObject(eobj, v);
139 Py_DECREF(v);
140 return NULL;
141}
142
143/* Call PyErr_Mac with PyMac_OSErrException */
144PyObject *
145PyMac_Error(OSErr err)
146{
147 return PyErr_Mac(PyMac_GetOSErrException(), err);
148}
149
150/* Convert a 4-char string object argument to an OSType value */
151int
152PyMac_GetOSType(PyObject *v, OSType *pr)
153{
154 if (!PyString_Check(v) || PyString_Size(v) != 4) {
155 PyErr_SetString(PyExc_TypeError,
156 "OSType arg must be string of 4 chars");
157 return 0;
158 }
159 memcpy((char *)pr, PyString_AsString(v), 4);
160 return 1;
161}
162
163/* Convert an OSType value to a 4-char string object */
164PyObject *
165PyMac_BuildOSType(OSType t)
166{
167 return PyString_FromStringAndSize((char *)&t, 4);
168}
169
170/* Convert an NumVersion value to a 4-element tuple */
171PyObject *
172PyMac_BuildNumVersion(NumVersion t)
173{
174 return Py_BuildValue("(hhhh)", t.majorRev, t.minorAndBugRev, t.stage, t.nonRelRev);
175}
176
177
178/* Convert a Python string object to a Str255 */
179int
180PyMac_GetStr255(PyObject *v, Str255 pbuf)
181{
182 int len;
183 if (!PyString_Check(v) || (len = PyString_Size(v)) > 255) {
184 PyErr_SetString(PyExc_TypeError,
185 "Str255 arg must be string of at most 255 chars");
186 return 0;
187 }
188 pbuf[0] = len;
189 memcpy((char *)(pbuf+1), PyString_AsString(v), len);
190 return 1;
191}
192
193/* Convert a Str255 to a Python string object */
194PyObject *
195PyMac_BuildStr255(Str255 s)
196{
197 if ( s == NULL ) {
198 PyErr_SetString(PyExc_SystemError, "Str255 pointer is NULL");
199 return NULL;
200 }
201 return PyString_FromStringAndSize((char *)&s[1], (int)s[0]);
202}
203
204PyObject *
205PyMac_BuildOptStr255(Str255 s)
206{
207 if ( s == NULL ) {
208 Py_INCREF(Py_None);
209 return Py_None;
210 }
211 return PyString_FromStringAndSize((char *)&s[1], (int)s[0]);
212}
213
214
215
216/* Convert a Python object to a Rect.
217 The object must be a (left, top, right, bottom) tuple.
218 (This differs from the order in the struct but is consistent with
219 the arguments to SetRect(), and also with STDWIN). */
220int
221PyMac_GetRect(PyObject *v, Rect *r)
222{
223 return PyArg_Parse(v, "(hhhh)", &r->left, &r->top, &r->right, &r->bottom);
224}
225
226/* Convert a Rect to a Python object */
227PyObject *
228PyMac_BuildRect(Rect *r)
229{
230 return Py_BuildValue("(hhhh)", r->left, r->top, r->right, r->bottom);
231}
232
233
234/* Convert a Python object to a Point.
235 The object must be a (h, v) tuple.
236 (This differs from the order in the struct but is consistent with
237 the arguments to SetPoint(), and also with STDWIN). */
238int
239PyMac_GetPoint(PyObject *v, Point *p)
240{
241 return PyArg_Parse(v, "(hh)", &p->h, &p->v);
242}
243
244/* Convert a Point to a Python object */
245PyObject *
246PyMac_BuildPoint(Point p)
247{
248 return Py_BuildValue("(hh)", p.h, p.v);
249}
250
251
252/* Convert a Python object to an EventRecord.
253 The object must be a (what, message, when, (v, h), modifiers) tuple. */
254int
255PyMac_GetEventRecord(PyObject *v, EventRecord *e)
256{
257 return PyArg_Parse(v, "(Hll(hh)H)",
258 &e->what,
259 &e->message,
260 &e->when,
261 &e->where.h,
262 &e->where.v,
263 &e->modifiers);
264}
265
266/* Convert a Rect to an EventRecord object */
267PyObject *
268PyMac_BuildEventRecord(EventRecord *e)
269{
270 return Py_BuildValue("(hll(hh)h)",
271 e->what,
272 e->message,
273 e->when,
274 e->where.h,
275 e->where.v,
276 e->modifiers);
277}
278
279/* Convert Python object to Fixed */
280int
281PyMac_GetFixed(PyObject *v, Fixed *f)
282{
283 double d;
284
285 if( !PyArg_Parse(v, "d", &d))
286 return 0;
287 *f = (Fixed)(d * 0x10000);
288 return 1;
289}
290
291/* Convert a Point to a Python object */
292PyObject *
293PyMac_BuildFixed(Fixed f)
294{
295 double d;
296
297 d = f;
298 d = d / 0x10000;
299 return Py_BuildValue("d", d);
300}
301
302/* Convert wide to/from Python int or (hi, lo) tuple. XXXX Should use Python longs */
303int
304PyMac_Getwide(PyObject *v, wide *rv)
305{
306 if (PyInt_Check(v)) {
307 rv->hi = 0;
308 rv->lo = PyInt_AsLong(v);
309 if( rv->lo & 0x80000000 )
310 rv->hi = -1;
311 return 1;
312 }
313 return PyArg_Parse(v, "(ll)", &rv->hi, &rv->lo);
314}
315
316
317PyObject *
318PyMac_Buildwide(wide *w)
319{
320 if ( (w->hi == 0 && (w->lo & 0x80000000) == 0) ||
321 (w->hi == -1 && (w->lo & 0x80000000) ) )
322 return PyInt_FromLong(w->lo);
323 return Py_BuildValue("(ll)", w->hi, w->lo);
324}
325
326#ifdef USE_TOOLBOX_OBJECT_GLUE
327/*
328** Glue together the toolbox objects.
329**
330** Because toolbox modules interdepend on each other, they use each others
331** object types, on MacOSX/MachO this leads to the situation that they
332** cannot be dynamically loaded (or they would all have to be lumped into
333** a single .so, but this would be bad for extensibility).
334**
335** This file defines wrappers for all the _New and _Convert functions,
336** which are the Py_BuildValue and PyArg_ParseTuple helpers. The wrappers
337** check an indirection function pointer, and if it isn't filled in yet
338** they import the appropriate module, whose init routine should fill in
339** the pointer.
340*/
341
342#define GLUE_NEW(object, routinename, module) \
343PyObject *(*PyMacGluePtr_##routinename)(object); \
344\
345PyObject *routinename(object cobj) { \
346 if (!PyMacGluePtr_##routinename) { \
347 if (!PyImport_ImportModule(module)) return NULL; \
348 if (!PyMacGluePtr_##routinename) { \
349 PyErr_SetString(PyExc_ImportError, "Module did not provide routine: " module ": " #routinename); \
350 return NULL; \
351 } \
352 } \
353 return (*PyMacGluePtr_##routinename)(cobj); \
354}
355
356#define GLUE_CONVERT(object, routinename, module) \
357int (*PyMacGluePtr_##routinename)(PyObject *, object *); \
358\
359int routinename(PyObject *pyobj, object *cobj) { \
360 if (!PyMacGluePtr_##routinename) { \
361 if (!PyImport_ImportModule(module)) return NULL; \
362 if (!PyMacGluePtr_##routinename) { \
363 PyErr_SetString(PyExc_ImportError, "Module did not provide routine: " module ": " #routinename); \
364 return NULL; \
365 } \
366 } \
367 return (*PyMacGluePtr_##routinename)(pyobj, cobj); \
368}
369GLUE_CONVERT(FSSpec, PyMac_GetFSSpec, "macfs")
370
371GLUE_NEW(AppleEvent *, AEDesc_New, "AE") /* XXXX Why by address? */
372GLUE_CONVERT(AppleEvent, AEDesc_Convert, "AE")
373
374GLUE_NEW(Component, CmpObj_New, "Cm")
375GLUE_CONVERT(Component, CmpObj_Convert, "Cm")
376GLUE_NEW(ComponentInstance, CmpInstObj_New, "Cm")
377GLUE_CONVERT(ComponentInstance, CmpInstObj_Convert, "Cm")
378
379GLUE_NEW(ControlHandle, CtlObj_New, "Ctl")
380GLUE_CONVERT(ControlHandle, CtlObj_Convert, "Ctl")
381
382GLUE_NEW(DialogPtr, DlgObj_New, "Dlg")
383GLUE_CONVERT(DialogPtr, DlgObj_Convert, "Dlg")
384GLUE_NEW(DialogPtr, DlgObj_WhichDialog, "Dlg")
385
386GLUE_NEW(DragReference, DragObj_New, "Drag")
387GLUE_CONVERT(DragReference, DragObj_Convert, "Drag")
388
389GLUE_NEW(ListHandle, ListObj_New, "List")
390GLUE_CONVERT(ListHandle, ListObj_Convert, "List")
391
392GLUE_NEW(MenuHandle, MenuObj_New, "Menu")
393GLUE_CONVERT(MenuHandle, MenuObj_Convert, "Menu")
394
395GLUE_NEW(GrafPtr, GrafObj_New, "Qd")
396GLUE_CONVERT(GrafPtr, GrafObj_Convert, "Qd")
397GLUE_NEW(BitMapPtr, BMObj_New, "Qd")
398GLUE_CONVERT(BitMapPtr, BMObj_Convert, "Qd")
399GLUE_NEW(RGBColor *, QdRGB_New, "Qd") /* XXXX Why? */
400GLUE_CONVERT(RGBColor, QdRGB_Convert, "Qd")
401
402GLUE_NEW(GWorldPtr, GWorldObj_New, "Qdoffs")
403GLUE_CONVERT(GWorldPtr, GWorldObj_Convert, "Qdoffs")
404
405GLUE_NEW(Track, TrackObj_New, "Qt")
406GLUE_CONVERT(Track, TrackObj_Convert, "Qt")
407GLUE_NEW(Movie, MovieObj_New, "Qt")
408GLUE_CONVERT(Movie, MovieObj_Convert, "Qt")
409GLUE_NEW(MovieController, MovieCtlObj_New, "Qt")
410GLUE_CONVERT(MovieController, MovieCtlObj_Convert, "Qt")
411GLUE_NEW(TimeBase, TimeBaseObj_New, "Qt")
412GLUE_CONVERT(TimeBase, TimeBaseObj_Convert, "Qt")
413GLUE_NEW(UserData, UserDataObj_New, "Qt")
414GLUE_CONVERT(UserData, UserDataObj_Convert, "Qt")
415GLUE_NEW(Media, MediaObj_New, "Qt")
416GLUE_CONVERT(Media, MediaObj_Convert, "Qt")
417
418GLUE_NEW(Handle, ResObj_New, "Res")
419GLUE_CONVERT(Handle, ResObj_Convert, "Res")
420GLUE_NEW(Handle, OptResObj_New, "Res")
421GLUE_CONVERT(Handle, OptResObj_Convert, "Res")
422
423GLUE_NEW(TEHandle, TEObj_New, "TE")
424GLUE_CONVERT(TEHandle, TEObj_Convert, "TE")
425
426GLUE_NEW(WindowPtr, WinObj_New, "Win")
427GLUE_CONVERT(WindowPtr, WinObj_Convert, "Win")
428GLUE_NEW(WindowPtr, WinObj_WhichWindow, "Win")
429
430#endif /* USE_TOOLBOX_OBJECT_GLUE */