blob: 242cf57e684dc8c3e73cf19104915d3dff593513 [file] [log] [blame]
Guido van Rossum2d167031994-09-16 10:54:21 +00001/***********************************************************
Jack Jansen42218ce1997-01-31 16:15:11 +00002Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
Guido van Rossum99546991995-01-08 14:33:34 +00003The Netherlands.
Guido van Rossum2d167031994-09-16 10:54:21 +00004
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/* Macintosh OS-specific interface */
26
27#include "Python.h"
Jack Jansen97ce3611994-12-14 14:02:24 +000028#include "macglue.h"
Jack Jansenb19c6672000-10-12 21:24:05 +000029#include "pythonresources.h"
Guido van Rossum2d167031994-09-16 10:54:21 +000030
Jack Jansen6143d532001-05-19 12:34:59 +000031#include <Carbon/Carbon.h>
Jack Jansend7c17232003-02-21 16:31:11 +000032#include <ApplicationServices/ApplicationServices.h>
Jack Jansenee23d6e1995-01-27 14:43:25 +000033
Guido van Rossum2d167031994-09-16 10:54:21 +000034static PyObject *MacOS_Error; /* Exception MacOS.Error */
35
Jack Jansen697842f2001-09-10 22:00:39 +000036#ifdef TARGET_API_MAC_OSX
37#define PATHNAMELEN 1024
38#else
39#define PATHNAMELEN 256
40#endif
41
Jack Jansen76a05891996-02-29 16:11:32 +000042/* ----------------------------------------------------- */
43
44/* Declarations for objects of type Resource fork */
45
46typedef struct {
47 PyObject_HEAD
48 short fRefNum;
49 int isclosed;
50} rfobject;
51
Jeremy Hylton938ace62002-07-17 16:30:39 +000052static PyTypeObject Rftype;
Jack Jansen76a05891996-02-29 16:11:32 +000053
54
55
56/* ---------------------------------------------------------------- */
57
58static void
Jack Jansendeefbe52001-08-08 13:46:49 +000059do_close(rfobject *self)
Jack Jansen76a05891996-02-29 16:11:32 +000060{
61 if (self->isclosed ) return;
62 (void)FSClose(self->fRefNum);
63 self->isclosed = 1;
64}
65
66static char rf_read__doc__[] =
67"Read data from resource fork"
68;
69
70static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +000071rf_read(rfobject *self, PyObject *args)
Jack Jansen76a05891996-02-29 16:11:32 +000072{
73 long n;
74 PyObject *v;
75 OSErr err;
76
77 if (self->isclosed) {
78 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
79 return NULL;
80 }
81
82 if (!PyArg_ParseTuple(args, "l", &n))
83 return NULL;
84
85 v = PyString_FromStringAndSize((char *)NULL, n);
86 if (v == NULL)
87 return NULL;
88
89 err = FSRead(self->fRefNum, &n, PyString_AsString(v));
90 if (err && err != eofErr) {
91 PyMac_Error(err);
92 Py_DECREF(v);
93 return NULL;
94 }
95 _PyString_Resize(&v, n);
96 return v;
97}
98
99
100static char rf_write__doc__[] =
101"Write to resource fork"
102;
103
104static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000105rf_write(rfobject *self, PyObject *args)
Jack Jansen76a05891996-02-29 16:11:32 +0000106{
107 char *buffer;
108 long size;
109 OSErr err;
110
111 if (self->isclosed) {
112 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
113 return NULL;
114 }
Jack Janseneeccca91997-05-07 15:46:31 +0000115 if (!PyArg_ParseTuple(args, "s#", &buffer, &size))
Jack Jansen76a05891996-02-29 16:11:32 +0000116 return NULL;
117 err = FSWrite(self->fRefNum, &size, buffer);
118 if (err) {
119 PyMac_Error(err);
120 return NULL;
121 }
122 Py_INCREF(Py_None);
123 return Py_None;
124}
125
126
127static char rf_seek__doc__[] =
128"Set file position"
129;
130
131static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000132rf_seek(rfobject *self, PyObject *args)
Jack Jansen76a05891996-02-29 16:11:32 +0000133{
134 long amount, pos;
135 int whence = SEEK_SET;
136 long eof;
137 OSErr err;
138
139 if (self->isclosed) {
140 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
141 return NULL;
142 }
143 if (!PyArg_ParseTuple(args, "l|i", &amount, &whence))
144 return NULL;
145
Jack Jansendeefbe52001-08-08 13:46:49 +0000146 if ((err = GetEOF(self->fRefNum, &eof)))
Jack Jansen76a05891996-02-29 16:11:32 +0000147 goto ioerr;
148
149 switch (whence) {
150 case SEEK_CUR:
Jack Jansendeefbe52001-08-08 13:46:49 +0000151 if ((err = GetFPos(self->fRefNum, &pos)))
Jack Jansen76a05891996-02-29 16:11:32 +0000152 goto ioerr;
153 break;
154 case SEEK_END:
155 pos = eof;
156 break;
157 case SEEK_SET:
158 pos = 0;
159 break;
160 default:
161 PyErr_BadArgument();
162 return NULL;
163 }
164
165 pos += amount;
166
167 /* Don't bother implementing seek past EOF */
168 if (pos > eof || pos < 0) {
169 PyErr_BadArgument();
170 return NULL;
171 }
172
Jack Jansendeefbe52001-08-08 13:46:49 +0000173 if ((err = SetFPos(self->fRefNum, fsFromStart, pos)) ) {
Jack Jansen76a05891996-02-29 16:11:32 +0000174ioerr:
175 PyMac_Error(err);
176 return NULL;
177 }
178 Py_INCREF(Py_None);
179 return Py_None;
180}
181
182
183static char rf_tell__doc__[] =
184"Get file position"
185;
186
187static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000188rf_tell(rfobject *self, PyObject *args)
Jack Jansen76a05891996-02-29 16:11:32 +0000189{
190 long where;
191 OSErr err;
192
193 if (self->isclosed) {
194 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
195 return NULL;
196 }
197 if (!PyArg_ParseTuple(args, ""))
198 return NULL;
Jack Jansendeefbe52001-08-08 13:46:49 +0000199 if ((err = GetFPos(self->fRefNum, &where)) ) {
Jack Jansen76a05891996-02-29 16:11:32 +0000200 PyMac_Error(err);
201 return NULL;
202 }
203 return PyInt_FromLong(where);
204}
205
206static char rf_close__doc__[] =
207"Close resource fork"
208;
209
210static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000211rf_close(rfobject *self, PyObject *args)
Jack Jansen76a05891996-02-29 16:11:32 +0000212{
Jack Jansen76a05891996-02-29 16:11:32 +0000213 if (!PyArg_ParseTuple(args, ""))
214 return NULL;
215 do_close(self);
216 Py_INCREF(Py_None);
217 return Py_None;
218}
219
220
221static struct PyMethodDef rf_methods[] = {
Jack Jansendeefbe52001-08-08 13:46:49 +0000222 {"read", (PyCFunction)rf_read, 1, rf_read__doc__},
223 {"write", (PyCFunction)rf_write, 1, rf_write__doc__},
224 {"seek", (PyCFunction)rf_seek, 1, rf_seek__doc__},
225 {"tell", (PyCFunction)rf_tell, 1, rf_tell__doc__},
226 {"close", (PyCFunction)rf_close, 1, rf_close__doc__},
Jack Jansen76a05891996-02-29 16:11:32 +0000227
228 {NULL, NULL} /* sentinel */
229};
230
231/* ---------- */
232
233
234static rfobject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000235newrfobject(void)
Jack Jansen76a05891996-02-29 16:11:32 +0000236{
237 rfobject *self;
238
239 self = PyObject_NEW(rfobject, &Rftype);
240 if (self == NULL)
241 return NULL;
242 self->isclosed = 1;
243 return self;
244}
245
246
247static void
Jack Jansendeefbe52001-08-08 13:46:49 +0000248rf_dealloc(rfobject *self)
Jack Jansen76a05891996-02-29 16:11:32 +0000249{
250 do_close(self);
Jack Jansen0e2f7982002-05-22 14:31:48 +0000251 PyObject_DEL(self);
Jack Jansen76a05891996-02-29 16:11:32 +0000252}
253
254static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000255rf_getattr(rfobject *self, char *name)
Jack Jansen76a05891996-02-29 16:11:32 +0000256{
257 return Py_FindMethod(rf_methods, (PyObject *)self, name);
258}
259
260static char Rftype__doc__[] =
261"Resource fork file object"
262;
263
264static PyTypeObject Rftype = {
265 PyObject_HEAD_INIT(&PyType_Type)
266 0, /*ob_size*/
Guido van Rossum14648392001-12-08 18:02:58 +0000267 "MacOS.ResourceFork", /*tp_name*/
Jack Jansen76a05891996-02-29 16:11:32 +0000268 sizeof(rfobject), /*tp_basicsize*/
269 0, /*tp_itemsize*/
270 /* methods */
271 (destructor)rf_dealloc, /*tp_dealloc*/
272 (printfunc)0, /*tp_print*/
273 (getattrfunc)rf_getattr, /*tp_getattr*/
274 (setattrfunc)0, /*tp_setattr*/
275 (cmpfunc)0, /*tp_compare*/
276 (reprfunc)0, /*tp_repr*/
277 0, /*tp_as_number*/
278 0, /*tp_as_sequence*/
279 0, /*tp_as_mapping*/
280 (hashfunc)0, /*tp_hash*/
281 (ternaryfunc)0, /*tp_call*/
282 (reprfunc)0, /*tp_str*/
283
284 /* Space for future expansion */
285 0L,0L,0L,0L,
286 Rftype__doc__ /* Documentation string */
287};
288
289/* End of code for Resource fork objects */
290/* -------------------------------------------------------- */
Guido van Rossum2d167031994-09-16 10:54:21 +0000291
292/*----------------------------------------------------------------------*/
Guido van Rossume791c2e1995-01-09 13:20:04 +0000293/* Miscellaneous File System Operations */
294
Jack Jansenfe94e972003-03-19 22:51:42 +0000295static char getcrtp_doc[] = "Get MacOS 4-char creator and type for a file";
Jack Jansen120a1051997-06-03 15:29:41 +0000296
Guido van Rossume791c2e1995-01-09 13:20:04 +0000297static PyObject *
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000298MacOS_GetCreatorAndType(PyObject *self, PyObject *args)
Guido van Rossume791c2e1995-01-09 13:20:04 +0000299{
Jack Jansene79dc762000-06-02 21:35:07 +0000300 FSSpec fss;
Guido van Rossume791c2e1995-01-09 13:20:04 +0000301 FInfo info;
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000302 PyObject *creator, *type, *res;
Guido van Rossume791c2e1995-01-09 13:20:04 +0000303 OSErr err;
304
Jack Jansene79dc762000-06-02 21:35:07 +0000305 if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSSpec, &fss))
Guido van Rossume791c2e1995-01-09 13:20:04 +0000306 return NULL;
Jack Jansene79dc762000-06-02 21:35:07 +0000307 if ((err = FSpGetFInfo(&fss, &info)) != noErr)
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000308 return PyErr_Mac(MacOS_Error, err);
Guido van Rossume791c2e1995-01-09 13:20:04 +0000309 creator = PyString_FromStringAndSize((char *)&info.fdCreator, 4);
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000310 type = PyString_FromStringAndSize((char *)&info.fdType, 4);
311 res = Py_BuildValue("OO", creator, type);
Guido van Rossumfffb8bb1995-01-12 12:37:24 +0000312 Py_DECREF(creator);
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000313 Py_DECREF(type);
Guido van Rossume791c2e1995-01-09 13:20:04 +0000314 return res;
315}
316
Jack Jansenfe94e972003-03-19 22:51:42 +0000317static char setcrtp_doc[] = "Set MacOS 4-char creator and type for a file";
Jack Jansen120a1051997-06-03 15:29:41 +0000318
Guido van Rossume791c2e1995-01-09 13:20:04 +0000319static PyObject *
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000320MacOS_SetCreatorAndType(PyObject *self, PyObject *args)
Guido van Rossume791c2e1995-01-09 13:20:04 +0000321{
Jack Jansene79dc762000-06-02 21:35:07 +0000322 FSSpec fss;
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000323 ResType creator, type;
Guido van Rossume791c2e1995-01-09 13:20:04 +0000324 FInfo info;
325 OSErr err;
326
327 if (!PyArg_ParseTuple(args, "O&O&O&",
Jack Jansene79dc762000-06-02 21:35:07 +0000328 PyMac_GetFSSpec, &fss, PyMac_GetOSType, &creator, PyMac_GetOSType, &type))
Guido van Rossume791c2e1995-01-09 13:20:04 +0000329 return NULL;
Jack Jansene79dc762000-06-02 21:35:07 +0000330 if ((err = FSpGetFInfo(&fss, &info)) != noErr)
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000331 return PyErr_Mac(MacOS_Error, err);
Guido van Rossume791c2e1995-01-09 13:20:04 +0000332 info.fdCreator = creator;
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000333 info.fdType = type;
Jack Jansene79dc762000-06-02 21:35:07 +0000334 if ((err = FSpSetFInfo(&fss, &info)) != noErr)
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000335 return PyErr_Mac(MacOS_Error, err);
Guido van Rossume791c2e1995-01-09 13:20:04 +0000336 Py_INCREF(Py_None);
337 return Py_None;
338}
339
Jack Jansenf3163302001-05-19 12:50:05 +0000340#if !TARGET_API_MAC_OSX
Jack Jansen120a1051997-06-03 15:29:41 +0000341static char schedparams_doc[] = "Set/return mainloop interrupt check flag, etc";
342
Jack Jansene8e8ae01995-01-26 16:36:45 +0000343/*
Jack Jansen120a1051997-06-03 15:29:41 +0000344** Set scheduler parameters
Jack Jansene8e8ae01995-01-26 16:36:45 +0000345*/
346static PyObject *
Jack Jansen120a1051997-06-03 15:29:41 +0000347MacOS_SchedParams(PyObject *self, PyObject *args)
Jack Jansene8e8ae01995-01-26 16:36:45 +0000348{
Jack Jansen120a1051997-06-03 15:29:41 +0000349 PyMacSchedParams old, new;
Jack Jansene8e8ae01995-01-26 16:36:45 +0000350
Jack Jansen120a1051997-06-03 15:29:41 +0000351 PyMac_GetSchedParams(&old);
352 new = old;
353 if (!PyArg_ParseTuple(args, "|iiidd", &new.check_interrupt, &new.process_events,
354 &new.besocial, &new.check_interval, &new.bg_yield))
Jack Jansene8e8ae01995-01-26 16:36:45 +0000355 return NULL;
Jack Jansen120a1051997-06-03 15:29:41 +0000356 PyMac_SetSchedParams(&new);
357 return Py_BuildValue("iiidd", old.check_interrupt, old.process_events,
358 old.besocial, old.check_interval, old.bg_yield);
Jack Jansene8e8ae01995-01-26 16:36:45 +0000359}
360
Jack Jansen120a1051997-06-03 15:29:41 +0000361static char appswitch_doc[] = "Obsolete, use SchedParams";
362
363/* Obsolete, for backward compatability */
Jack Jansenee23d6e1995-01-27 14:43:25 +0000364static PyObject *
365MacOS_EnableAppswitch(PyObject *self, PyObject *args)
366{
Jack Jansen120a1051997-06-03 15:29:41 +0000367 int new, old;
368 PyMacSchedParams schp;
Jack Jansenee23d6e1995-01-27 14:43:25 +0000369
Guido van Rossume7134aa1995-02-26 10:20:53 +0000370 if (!PyArg_ParseTuple(args, "i", &new))
Jack Jansenee23d6e1995-01-27 14:43:25 +0000371 return NULL;
Jack Jansen120a1051997-06-03 15:29:41 +0000372 PyMac_GetSchedParams(&schp);
373 if ( schp.process_events )
374 old = 1;
375 else if ( schp.check_interrupt )
Jack Jansen120a1051997-06-03 15:29:41 +0000376 old = 0;
Jack Jansen2e871e41997-09-08 13:23:19 +0000377 else
378 old = -1;
Jack Jansen120a1051997-06-03 15:29:41 +0000379 if ( new > 0 ) {
380 schp.process_events = mDownMask|keyDownMask|osMask;
381 schp.check_interrupt = 1;
Jack Jansen2e871e41997-09-08 13:23:19 +0000382 } else if ( new == 0 ) {
Jack Jansen120a1051997-06-03 15:29:41 +0000383 schp.process_events = 0;
384 schp.check_interrupt = 1;
385 } else {
386 schp.process_events = 0;
387 schp.check_interrupt = 0;
388 }
389 PyMac_SetSchedParams(&schp);
Guido van Rossume7134aa1995-02-26 10:20:53 +0000390 return Py_BuildValue("i", old);
Jack Jansenee23d6e1995-01-27 14:43:25 +0000391}
392
Jack Jansen883765e1997-06-20 16:19:38 +0000393static char setevh_doc[] = "Set python event handler to be called in mainloop";
394
395static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000396MacOS_SetEventHandler(PyObject *self, PyObject *args)
Jack Jansen883765e1997-06-20 16:19:38 +0000397{
398 PyObject *evh = NULL;
399
400 if (!PyArg_ParseTuple(args, "|O", &evh))
401 return NULL;
402 if (evh == Py_None)
403 evh = NULL;
404 if ( evh && !PyCallable_Check(evh) ) {
405 PyErr_SetString(PyExc_ValueError, "SetEventHandler argument must be callable");
406 return NULL;
407 }
408 if ( !PyMac_SetEventHandler(evh) )
409 return NULL;
410 Py_INCREF(Py_None);
411 return Py_None;
412}
413
Jack Jansen120a1051997-06-03 15:29:41 +0000414static char handleev_doc[] = "Pass event to other interested parties like sioux";
Jack Jansena76382a1995-02-02 14:25:56 +0000415
416static PyObject *
417MacOS_HandleEvent(PyObject *self, PyObject *args)
418{
419 EventRecord ev;
420
421 if (!PyArg_ParseTuple(args, "O&", PyMac_GetEventRecord, &ev))
422 return NULL;
Jack Jansen883765e1997-06-20 16:19:38 +0000423 PyMac_HandleEventIntern(&ev);
Jack Jansena76382a1995-02-02 14:25:56 +0000424 Py_INCREF(Py_None);
425 return Py_None;
426}
Jack Jansenf3163302001-05-19 12:50:05 +0000427#endif /* !TARGET_API_MAC_OSX */
Jack Jansena76382a1995-02-02 14:25:56 +0000428
Jack Jansen120a1051997-06-03 15:29:41 +0000429static char geterr_doc[] = "Convert OSErr number to string";
430
Jack Jansen829f88c1995-07-17 11:36:01 +0000431static PyObject *
432MacOS_GetErrorString(PyObject *self, PyObject *args)
433{
434 int errn;
435
436 if (!PyArg_ParseTuple(args, "i", &errn))
437 return NULL;
438 return Py_BuildValue("s", PyMac_StrError(errn));
439}
440
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000441static char splash_doc[] = "Open a splash-screen dialog by resource-id (0=close)";
442
443static PyObject *
444MacOS_splash(PyObject *self, PyObject *args)
445{
Jack Jansendf34cf11996-09-15 22:12:00 +0000446 int resid = -1;
Jack Jansen450ae9f1997-05-13 15:41:48 +0000447 static DialogPtr curdialog = NULL;
Jack Jansen2e871e41997-09-08 13:23:19 +0000448 DialogPtr olddialog;
Jack Jansen04df9d51996-09-23 15:49:43 +0000449 WindowRef theWindow;
450 CGrafPtr thePort;
Jack Jansene79dc762000-06-02 21:35:07 +0000451#if 0
Jack Jansen04df9d51996-09-23 15:49:43 +0000452 short xpos, ypos, width, height, swidth, sheight;
Jack Jansene79dc762000-06-02 21:35:07 +0000453#endif
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000454
Jack Jansendf34cf11996-09-15 22:12:00 +0000455 if (!PyArg_ParseTuple(args, "|i", &resid))
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000456 return NULL;
Jack Jansen2e871e41997-09-08 13:23:19 +0000457 olddialog = curdialog;
Jack Jansencbe6a531998-02-20 15:59:59 +0000458 curdialog = NULL;
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000459
Jack Jansendf34cf11996-09-15 22:12:00 +0000460 if ( resid != -1 ) {
461 curdialog = GetNewDialog(resid, NULL, (WindowPtr)-1);
Jack Jansen04df9d51996-09-23 15:49:43 +0000462 if ( curdialog ) {
463 theWindow = GetDialogWindow(curdialog);
464 thePort = GetWindowPort(theWindow);
Jack Jansene79dc762000-06-02 21:35:07 +0000465#if 0
Jack Jansen04df9d51996-09-23 15:49:43 +0000466 width = thePort->portRect.right - thePort->portRect.left;
467 height = thePort->portRect.bottom - thePort->portRect.top;
468 swidth = qd.screenBits.bounds.right - qd.screenBits.bounds.left;
469 sheight = qd.screenBits.bounds.bottom - qd.screenBits.bounds.top - LMGetMBarHeight();
470 xpos = (swidth-width)/2;
471 ypos = (sheight-height)/5 + LMGetMBarHeight();
472 MoveWindow(theWindow, xpos, ypos, 0);
473 ShowWindow(theWindow);
Jack Jansene79dc762000-06-02 21:35:07 +0000474#endif
Jack Jansendf34cf11996-09-15 22:12:00 +0000475 DrawDialog(curdialog);
Jack Jansen04df9d51996-09-23 15:49:43 +0000476 }
Jack Jansendf34cf11996-09-15 22:12:00 +0000477 }
Jack Jansen2e871e41997-09-08 13:23:19 +0000478 if (olddialog)
479 DisposeDialog(olddialog);
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000480 Py_INCREF(Py_None);
481 return Py_None;
482}
483
Jack Janseneb76b841996-09-30 14:43:22 +0000484static char DebugStr_doc[] = "Switch to low-level debugger with a message";
485
486static PyObject *
487MacOS_DebugStr(PyObject *self, PyObject *args)
488{
489 Str255 message;
490 PyObject *object = 0;
491
492 if (!PyArg_ParseTuple(args, "O&|O", PyMac_GetStr255, message, &object))
493 return NULL;
494 DebugStr(message);
495 Py_INCREF(Py_None);
496 return Py_None;
497}
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000498
Jack Jansen2e871e41997-09-08 13:23:19 +0000499static char SysBeep_doc[] = "BEEEEEP!!!";
500
501static PyObject *
502MacOS_SysBeep(PyObject *self, PyObject *args)
503{
504 int duration = 6;
505
506 if (!PyArg_ParseTuple(args, "|i", &duration))
507 return NULL;
508 SysBeep(duration);
509 Py_INCREF(Py_None);
510 return Py_None;
511}
512
Jack Jansend7c17232003-02-21 16:31:11 +0000513static char WMAvailable_doc[] =
514 "True if this process can interact with the display."
515 "Will foreground the application on the first call as a side-effect."
516 ;
517
518static PyObject *
519MacOS_WMAvailable(PyObject *self, PyObject *args)
520{
521 static PyObject *rv = NULL;
522
523 if (!PyArg_ParseTuple(args, ""))
524 return NULL;
525 if (!rv) {
526#if TARGET_API_MAC_OSX
527 ProcessSerialNumber psn;
528
529 /*
530 ** This is a fairly innocuous call to make if we don't have a window
531 ** manager, or if we have no permission to talk to it. It will print
532 ** a message on stderr, but at least it won't abort the process.
533 ** It appears the function caches the result itself, and it's cheap, so
534 ** no need for us to cache.
535 */
536 if (CGMainDisplayID() == 0) {
537 rv = Py_False;
538 } else {
539 if (GetCurrentProcess(&psn) < 0 ||
540 SetFrontProcess(&psn) < 0) {
541 rv = Py_False;
542 } else {
543 rv = Py_True;
544 }
545 }
546#else
547 rv = Py_True;
548#endif
549 }
550 Py_INCREF(rv);
551 return rv;
552}
553
Jack Jansen898ac1b1997-09-01 15:38:12 +0000554static char GetTicks_doc[] = "Return number of ticks since bootup";
555
556static PyObject *
557MacOS_GetTicks(PyObject *self, PyObject *args)
558{
Jack Jansene79dc762000-06-02 21:35:07 +0000559 return Py_BuildValue("i", (int)TickCount());
Jack Jansen898ac1b1997-09-01 15:38:12 +0000560}
561
Jack Jansen76a05891996-02-29 16:11:32 +0000562static char openrf_doc[] = "Open resource fork of a file";
563
564static PyObject *
565MacOS_openrf(PyObject *self, PyObject *args)
566{
567 OSErr err;
568 char *mode = "r";
569 FSSpec fss;
570 SignedByte permission = 1;
571 rfobject *fp;
572
573 if (!PyArg_ParseTuple(args, "O&|s", PyMac_GetFSSpec, &fss, &mode))
574 return NULL;
575 while (*mode) {
576 switch (*mode++) {
577 case '*': break;
578 case 'r': permission = 1; break;
579 case 'w': permission = 2; break;
580 case 'b': break;
581 default:
582 PyErr_BadArgument();
583 return NULL;
584 }
585 }
586
587 if ( (fp = newrfobject()) == NULL )
588 return NULL;
589
590 err = HOpenRF(fss.vRefNum, fss.parID, fss.name, permission, &fp->fRefNum);
591
592 if ( err == fnfErr ) {
593 /* In stead of doing complicated things here to get creator/type
594 ** correct we let the standard i/o library handle it
595 */
596 FILE *tfp;
Jack Jansen697842f2001-09-10 22:00:39 +0000597 char pathname[PATHNAMELEN];
Jack Jansen76a05891996-02-29 16:11:32 +0000598
Jack Jansenb7348692002-12-23 23:16:25 +0000599 if ( (err=PyMac_GetFullPathname(&fss, pathname, PATHNAMELEN)) ) {
Jack Jansen76a05891996-02-29 16:11:32 +0000600 PyMac_Error(err);
601 Py_DECREF(fp);
602 return NULL;
603 }
604
605 if ( (tfp = fopen(pathname, "w")) == NULL ) {
606 PyMac_Error(fnfErr); /* What else... */
607 Py_DECREF(fp);
608 return NULL;
609 }
610 fclose(tfp);
611 err = HOpenRF(fss.vRefNum, fss.parID, fss.name, permission, &fp->fRefNum);
612 }
613 if ( err ) {
614 Py_DECREF(fp);
615 PyMac_Error(err);
616 return NULL;
617 }
618 fp->isclosed = 0;
619 return (PyObject *)fp;
620}
621
Jack Jansenf3163302001-05-19 12:50:05 +0000622#if !TARGET_API_MAC_OSX
Jack Jansen957d07a2000-02-21 11:07:37 +0000623static char FreeMem_doc[] = "Return the total amount of free space in the heap";
624
625static PyObject *
626MacOS_FreeMem(PyObject *self, PyObject *args)
627{
628 long rv;
629
630 if (!PyArg_ParseTuple(args, ""))
631 return NULL;
632 rv = FreeMem();
633 return Py_BuildValue("l", rv);
634}
635
636static char MaxBlock_doc[] = "Return the largest contiguous block of free space in the heap";
637
638static PyObject *
639MacOS_MaxBlock(PyObject *self, PyObject *args)
640{
641 long rv;
642
643 if (!PyArg_ParseTuple(args, ""))
644 return NULL;
645 rv = MaxBlock();
646 return Py_BuildValue("l", rv);
647}
648
649static char CompactMem_doc[] = "(wanted size)->actual largest block after compacting";
650
651static PyObject *
652MacOS_CompactMem(PyObject *self, PyObject *args)
653{
654 long value;
655 long rv;
656
657 if (!PyArg_ParseTuple(args, "l", &value))
658 return NULL;
659 rv = CompactMem(value);
660 return Py_BuildValue("l", rv);
661}
662
Jack Jansenb19c6672000-10-12 21:24:05 +0000663static char KeepConsole_doc[] = "(flag) Keep console open 0:never, 1:on output 2:on error, 3:always";
664
665static PyObject *
666MacOS_KeepConsole(PyObject *self, PyObject *args)
667{
668 int value;
669
670 if (!PyArg_ParseTuple(args, "i", &value))
671 return NULL;
672 PyMac_options.keep_console = value;
673 Py_INCREF(Py_None);
674 return Py_None;
675}
676
Jack Jansen8413b472000-10-19 22:02:16 +0000677static char OutputSeen_doc[] = "Call to reset the 'unseen output' flag for the keep-console-open option";
678
679static PyObject *
680MacOS_OutputSeen(PyObject *self, PyObject *args)
681{
682 if (!PyArg_ParseTuple(args, ""))
683 return NULL;
684 PyMac_OutputSeen();
685 Py_INCREF(Py_None);
686 return Py_None;
687}
Jack Jansenf3163302001-05-19 12:50:05 +0000688#endif /* !TARGET_API_MAC_OSX */
Jack Jansen8413b472000-10-19 22:02:16 +0000689
Guido van Rossum2d167031994-09-16 10:54:21 +0000690static PyMethodDef MacOS_Methods[] = {
Jack Jansen120a1051997-06-03 15:29:41 +0000691 {"GetCreatorAndType", MacOS_GetCreatorAndType, 1, getcrtp_doc},
692 {"SetCreatorAndType", MacOS_SetCreatorAndType, 1, setcrtp_doc},
Jack Jansenf3163302001-05-19 12:50:05 +0000693#if !TARGET_API_MAC_OSX
Jack Jansen120a1051997-06-03 15:29:41 +0000694 {"SchedParams", MacOS_SchedParams, 1, schedparams_doc},
695 {"EnableAppswitch", MacOS_EnableAppswitch, 1, appswitch_doc},
Jack Jansen883765e1997-06-20 16:19:38 +0000696 {"SetEventHandler", MacOS_SetEventHandler, 1, setevh_doc},
Jack Jansen120a1051997-06-03 15:29:41 +0000697 {"HandleEvent", MacOS_HandleEvent, 1, handleev_doc},
Jack Jansenf3163302001-05-19 12:50:05 +0000698#endif
Jack Jansen120a1051997-06-03 15:29:41 +0000699 {"GetErrorString", MacOS_GetErrorString, 1, geterr_doc},
700 {"openrf", MacOS_openrf, 1, openrf_doc},
701 {"splash", MacOS_splash, 1, splash_doc},
702 {"DebugStr", MacOS_DebugStr, 1, DebugStr_doc},
Jack Jansen898ac1b1997-09-01 15:38:12 +0000703 {"GetTicks", MacOS_GetTicks, 1, GetTicks_doc},
Jack Jansen2e871e41997-09-08 13:23:19 +0000704 {"SysBeep", MacOS_SysBeep, 1, SysBeep_doc},
Jack Jansend7c17232003-02-21 16:31:11 +0000705 {"WMAvailable", MacOS_WMAvailable, 1, WMAvailable_doc},
Jack Jansenf3163302001-05-19 12:50:05 +0000706#if !TARGET_API_MAC_OSX
Jack Jansen957d07a2000-02-21 11:07:37 +0000707 {"FreeMem", MacOS_FreeMem, 1, FreeMem_doc},
708 {"MaxBlock", MacOS_MaxBlock, 1, MaxBlock_doc},
709 {"CompactMem", MacOS_CompactMem, 1, CompactMem_doc},
Jack Jansenb19c6672000-10-12 21:24:05 +0000710 {"KeepConsole", MacOS_KeepConsole, 1, KeepConsole_doc},
Jack Jansen8413b472000-10-19 22:02:16 +0000711 {"OutputSeen", MacOS_OutputSeen, 1, OutputSeen_doc},
Jack Jansenf3163302001-05-19 12:50:05 +0000712#endif
Guido van Rossumf74d4e21995-01-18 23:58:07 +0000713 {NULL, NULL} /* Sentinel */
Guido van Rossum2d167031994-09-16 10:54:21 +0000714};
715
716
717void
Jack Jansendeefbe52001-08-08 13:46:49 +0000718initMacOS(void)
Guido van Rossum2d167031994-09-16 10:54:21 +0000719{
720 PyObject *m, *d;
721
722 m = Py_InitModule("MacOS", MacOS_Methods);
723 d = PyModule_GetDict(m);
724
725 /* Initialize MacOS.Error exception */
Guido van Rossumbf068b11995-01-25 23:09:20 +0000726 MacOS_Error = PyMac_GetOSErrException();
Guido van Rossume433c971994-09-29 10:02:56 +0000727 if (MacOS_Error == NULL || PyDict_SetItemString(d, "Error", MacOS_Error) != 0)
Jack Jansenfa1e27d2000-09-08 10:21:44 +0000728 return;
Jack Jansena755e681997-09-20 17:40:22 +0000729 Rftype.ob_type = &PyType_Type;
730 Py_INCREF(&Rftype);
731 if (PyDict_SetItemString(d, "ResourceForkType", (PyObject *)&Rftype) != 0)
Jack Jansenfa1e27d2000-09-08 10:21:44 +0000732 return;
Jack Jansenf73bab71997-04-03 14:51:03 +0000733 /*
734 ** This is a hack: the following constant added to the id() of a string
735 ** object gives you the address of the data. Unfortunately, it is needed for
736 ** some of the image and sound processing interfaces on the mac:-(
737 */
738 {
739 PyStringObject *p = 0;
740 long off = (long)&(p->ob_sval[0]);
741
742 if( PyDict_SetItemString(d, "string_id_to_buffer", Py_BuildValue("i", off)) != 0)
Jack Jansenfa1e27d2000-09-08 10:21:44 +0000743 return;
Jack Jansenf73bab71997-04-03 14:51:03 +0000744 }
Jack Jansenf3163302001-05-19 12:50:05 +0000745#if TARGET_API_MAC_OSX
746#define PY_RUNTIMEMODEL "macho"
Jack Jansenf3163302001-05-19 12:50:05 +0000747#elif TARGET_API_MAC_CARBON
748#define PY_RUNTIMEMODEL "carbon"
Jack Jansen6e68a7e2001-05-12 21:31:34 +0000749#else
750#error "None of the TARGET_API_MAC_XXX I know about is set"
Jack Jansen193509b2001-01-23 22:38:23 +0000751#endif
752 if (PyDict_SetItemString(d, "runtimemodel",
753 Py_BuildValue("s", PY_RUNTIMEMODEL)) != 0)
754 return;
Jack Jansen8cd9a4f2003-02-23 23:23:47 +0000755#if !TARGET_API_MAC_OSX
756#define PY_LINKMODEL "cfm"
757#elif defined(WITH_NEXT_FRAMEWORK)
758#define PY_LINKMODEL "framework"
759#elif defined(Py_ENABLE_SHARED)
760#define PY_LINKMODEL "shared"
761#else
762#define PY_LINKMODEL "static"
763#endif
764 if (PyDict_SetItemString(d, "linkmodel",
765 Py_BuildValue("s", PY_LINKMODEL)) != 0)
766 return;
767
Guido van Rossum2d167031994-09-16 10:54:21 +0000768}