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 ******************************************************************/
25 /* Macintosh OS-specific interface */
36 static PyObject
*MacOS_Error
; /* Exception MacOS.Error */
39 #define bufferIsSmall -607 /*error returns from Post and Accept */
42 static PyObject
*ErrorObject
;
44 /* ----------------------------------------------------- */
46 /* Declarations for objects of type Resource fork */
54 staticforward PyTypeObject Rftype
;
58 /* ---------------------------------------------------------------- */
64 if (self
->isclosed
) return;
65 (void)FSClose(self
->fRefNum
);
69 static char rf_read__doc__
[] =
70 "Read data from resource fork"
83 PyErr_SetString(PyExc_ValueError
, "Operation on closed file");
87 if (!PyArg_ParseTuple(args
, "l", &n
))
90 v
= PyString_FromStringAndSize((char *)NULL
, n
);
94 err
= FSRead(self
->fRefNum
, &n
, PyString_AsString(v
));
95 if (err
&& err
!= eofErr
) {
100 _PyString_Resize(&v
, n
);
105 static char rf_write__doc__
[] =
106 "Write to resource fork"
118 if (self
->isclosed
) {
119 PyErr_SetString(PyExc_ValueError
, "Operation on closed file");
122 if (!PyArg_ParseTuple(args
, "s#", &buffer
, &size
))
124 err
= FSWrite(self
->fRefNum
, &size
, buffer
);
134 static char rf_seek__doc__
[] =
144 int whence
= SEEK_SET
;
148 if (self
->isclosed
) {
149 PyErr_SetString(PyExc_ValueError
, "Operation on closed file");
152 if (!PyArg_ParseTuple(args
, "l|i", &amount
, &whence
))
155 if ( err
= GetEOF(self
->fRefNum
, &eof
))
160 if (err
= GetFPos(self
->fRefNum
, &pos
))
176 /* Don't bother implementing seek past EOF */
177 if (pos
> eof
|| pos
< 0) {
182 if ( err
= SetFPos(self
->fRefNum
, fsFromStart
, pos
) ) {
192 static char rf_tell__doc__
[] =
204 if (self
->isclosed
) {
205 PyErr_SetString(PyExc_ValueError
, "Operation on closed file");
208 if (!PyArg_ParseTuple(args
, ""))
210 if ( err
= GetFPos(self
->fRefNum
, &where
) ) {
214 return PyInt_FromLong(where
);
217 static char rf_close__doc__
[] =
218 "Close resource fork"
226 if (!PyArg_ParseTuple(args
, ""))
234 static struct PyMethodDef rf_methods
[] = {
235 {"read", rf_read
, 1, rf_read__doc__
},
236 {"write", rf_write
, 1, rf_write__doc__
},
237 {"seek", rf_seek
, 1, rf_seek__doc__
},
238 {"tell", rf_tell
, 1, rf_tell__doc__
},
239 {"close", rf_close
, 1, rf_close__doc__
},
241 {NULL
, NULL
} /* sentinel */
252 self
= PyObject_NEW(rfobject
, &Rftype
);
269 rf_getattr(self
, name
)
273 return Py_FindMethod(rf_methods
, (PyObject
*)self
, name
);
276 static char Rftype__doc__
[] =
277 "Resource fork file object"
280 static PyTypeObject Rftype
= {
281 PyObject_HEAD_INIT(&PyType_Type
)
283 "ResourceFork", /*tp_name*/
284 sizeof(rfobject
), /*tp_basicsize*/
287 (destructor
)rf_dealloc
, /*tp_dealloc*/
288 (printfunc
)0, /*tp_print*/
289 (getattrfunc
)rf_getattr
, /*tp_getattr*/
290 (setattrfunc
)0, /*tp_setattr*/
291 (cmpfunc
)0, /*tp_compare*/
292 (reprfunc
)0, /*tp_repr*/
294 0, /*tp_as_sequence*/
296 (hashfunc
)0, /*tp_hash*/
297 (ternaryfunc
)0, /*tp_call*/
298 (reprfunc
)0, /*tp_str*/
300 /* Space for future expansion */
302 Rftype__doc__
/* Documentation string */
305 /* End of code for Resource fork objects */
306 /* -------------------------------------------------------- */
308 /*----------------------------------------------------------------------*/
309 /* Miscellaneous File System Operations */
311 static char getcrtp_doc
[] = "Obsolete, use macfs module";
314 MacOS_GetCreatorAndType(PyObject
*self
, PyObject
*args
)
318 PyObject
*creator
, *type
, *res
;
321 if (!PyArg_ParseTuple(args
, "O&", PyMac_GetFSSpec
, &fss
))
323 if ((err
= FSpGetFInfo(&fss
, &info
)) != noErr
)
324 return PyErr_Mac(MacOS_Error
, err
);
325 creator
= PyString_FromStringAndSize((char *)&info
.fdCreator
, 4);
326 type
= PyString_FromStringAndSize((char *)&info
.fdType
, 4);
327 res
= Py_BuildValue("OO", creator
, type
);
333 static char setcrtp_doc
[] = "Obsolete, use macfs module";
336 MacOS_SetCreatorAndType(PyObject
*self
, PyObject
*args
)
339 ResType creator
, type
;
343 if (!PyArg_ParseTuple(args
, "O&O&O&",
344 PyMac_GetFSSpec
, &fss
, PyMac_GetOSType
, &creator
, PyMac_GetOSType
, &type
))
346 if ((err
= FSpGetFInfo(&fss
, &info
)) != noErr
)
347 return PyErr_Mac(MacOS_Error
, err
);
348 info
.fdCreator
= creator
;
350 if ((err
= FSpSetFInfo(&fss
, &info
)) != noErr
)
351 return PyErr_Mac(MacOS_Error
, err
);
356 /*----------------------------------------------------------------------*/
357 /* STDWIN High Level Event interface */
362 #if !TARGET_API_MAC_CARBON
363 static char accepthle_doc
[] = "Get arguments of pending high-level event";
366 MacOS_AcceptHighLevelEvent(self
, args
)
371 unsigned long refcon
;
379 err
= AcceptHighLevelEvent(&sender
, &refcon
, buf
, &len
);
380 if (err
== bufferIsSmall
) {
383 return PyErr_NoMemory();
384 err
= AcceptHighLevelEvent(&sender
, &refcon
, buf
, &len
);
387 return PyErr_Mac(MacOS_Error
, (int)err
);
390 else if (err
!= noErr
)
391 return PyErr_Mac(MacOS_Error
, (int)err
);
392 res
= Py_BuildValue("s#ls#",
393 (char *)&sender
, (int)(sizeof sender
), refcon
, (char *)buf
, (int)len
);
398 static char schedparams_doc
[] = "Set/return mainloop interrupt check flag, etc";
401 ** Set scheduler parameters
404 MacOS_SchedParams(PyObject
*self
, PyObject
*args
)
406 PyMacSchedParams old
, new;
408 PyMac_GetSchedParams(&old
);
410 if (!PyArg_ParseTuple(args
, "|iiidd", &new.check_interrupt
, &new.process_events
,
411 &new.besocial
, &new.check_interval
, &new.bg_yield
))
413 PyMac_SetSchedParams(&new);
414 return Py_BuildValue("iiidd", old
.check_interrupt
, old
.process_events
,
415 old
.besocial
, old
.check_interval
, old
.bg_yield
);
418 static char appswitch_doc
[] = "Obsolete, use SchedParams";
420 /* Obsolete, for backward compatability */
422 MacOS_EnableAppswitch(PyObject
*self
, PyObject
*args
)
425 PyMacSchedParams schp
;
427 if (!PyArg_ParseTuple(args
, "i", &new))
429 PyMac_GetSchedParams(&schp
);
430 if ( schp
.process_events
)
432 else if ( schp
.check_interrupt
)
437 schp
.process_events
= mDownMask
|keyDownMask
|osMask
;
438 schp
.check_interrupt
= 1;
439 } else if ( new == 0 ) {
440 schp
.process_events
= 0;
441 schp
.check_interrupt
= 1;
443 schp
.process_events
= 0;
444 schp
.check_interrupt
= 0;
446 PyMac_SetSchedParams(&schp
);
447 return Py_BuildValue("i", old
);
450 static char setevh_doc
[] = "Set python event handler to be called in mainloop";
453 MacOS_SetEventHandler(self
, args
)
457 PyObject
*evh
= NULL
;
459 if (!PyArg_ParseTuple(args
, "|O", &evh
))
463 if ( evh
&& !PyCallable_Check(evh
) ) {
464 PyErr_SetString(PyExc_ValueError
, "SetEventHandler argument must be callable");
467 if ( !PyMac_SetEventHandler(evh
) )
473 static char handleev_doc
[] = "Pass event to other interested parties like sioux";
476 MacOS_HandleEvent(PyObject
*self
, PyObject
*args
)
480 if (!PyArg_ParseTuple(args
, "O&", PyMac_GetEventRecord
, &ev
))
482 PyMac_HandleEventIntern(&ev
);
487 static char geterr_doc
[] = "Convert OSErr number to string";
490 MacOS_GetErrorString(PyObject
*self
, PyObject
*args
)
494 if (!PyArg_ParseTuple(args
, "i", &errn
))
496 return Py_BuildValue("s", PyMac_StrError(errn
));
499 static char splash_doc
[] = "Open a splash-screen dialog by resource-id (0=close)";
502 MacOS_splash(PyObject
*self
, PyObject
*args
)
505 static DialogPtr curdialog
= NULL
;
510 short xpos
, ypos
, width
, height
, swidth
, sheight
;
513 if (!PyArg_ParseTuple(args
, "|i", &resid
))
515 olddialog
= curdialog
;
519 curdialog
= GetNewDialog(resid
, NULL
, (WindowPtr
)-1);
521 theWindow
= GetDialogWindow(curdialog
);
522 thePort
= GetWindowPort(theWindow
);
524 width
= thePort
->portRect
.right
- thePort
->portRect
.left
;
525 height
= thePort
->portRect
.bottom
- thePort
->portRect
.top
;
526 swidth
= qd
.screenBits
.bounds
.right
- qd
.screenBits
.bounds
.left
;
527 sheight
= qd
.screenBits
.bounds
.bottom
- qd
.screenBits
.bounds
.top
- LMGetMBarHeight();
528 xpos
= (swidth
-width
)/2;
529 ypos
= (sheight
-height
)/5 + LMGetMBarHeight();
530 MoveWindow(theWindow
, xpos
, ypos
, 0);
531 ShowWindow(theWindow
);
533 DrawDialog(curdialog
);
537 DisposeDialog(olddialog
);
542 static char DebugStr_doc
[] = "Switch to low-level debugger with a message";
545 MacOS_DebugStr(PyObject
*self
, PyObject
*args
)
548 PyObject
*object
= 0;
550 if (!PyArg_ParseTuple(args
, "O&|O", PyMac_GetStr255
, message
, &object
))
557 static char SysBeep_doc
[] = "BEEEEEP!!!";
560 MacOS_SysBeep(PyObject
*self
, PyObject
*args
)
564 if (!PyArg_ParseTuple(args
, "|i", &duration
))
571 static char GetTicks_doc
[] = "Return number of ticks since bootup";
574 MacOS_GetTicks(PyObject
*self
, PyObject
*args
)
576 return Py_BuildValue("i", (int)TickCount());
579 static char openrf_doc
[] = "Open resource fork of a file";
582 MacOS_openrf(PyObject
*self
, PyObject
*args
)
587 SignedByte permission
= 1;
590 if (!PyArg_ParseTuple(args
, "O&|s", PyMac_GetFSSpec
, &fss
, &mode
))
595 case 'r': permission
= 1; break;
596 case 'w': permission
= 2; break;
604 if ( (fp
= newrfobject()) == NULL
)
607 err
= HOpenRF(fss
.vRefNum
, fss
.parID
, fss
.name
, permission
, &fp
->fRefNum
);
609 if ( err
== fnfErr
) {
610 /* In stead of doing complicated things here to get creator/type
611 ** correct we let the standard i/o library handle it
616 if ( err
=PyMac_GetFullPath(&fss
, pathname
) ) {
622 if ( (tfp
= fopen(pathname
, "w")) == NULL
) {
623 PyMac_Error(fnfErr
); /* What else... */
628 err
= HOpenRF(fss
.vRefNum
, fss
.parID
, fss
.name
, permission
, &fp
->fRefNum
);
636 return (PyObject
*)fp
;
639 static char FreeMem_doc
[] = "Return the total amount of free space in the heap";
642 MacOS_FreeMem(PyObject
*self
, PyObject
*args
)
646 if (!PyArg_ParseTuple(args
, ""))
649 return Py_BuildValue("l", rv
);
652 static char MaxBlock_doc
[] = "Return the largest contiguous block of free space in the heap";
655 MacOS_MaxBlock(PyObject
*self
, PyObject
*args
)
659 if (!PyArg_ParseTuple(args
, ""))
662 return Py_BuildValue("l", rv
);
665 static char CompactMem_doc
[] = "(wanted size)->actual largest block after compacting";
668 MacOS_CompactMem(PyObject
*self
, PyObject
*args
)
673 if (!PyArg_ParseTuple(args
, "l", &value
))
675 rv
= CompactMem(value
);
676 return Py_BuildValue("l", rv
);
679 static PyMethodDef MacOS_Methods
[] = {
680 #if !TARGET_API_MAC_CARBON
681 {"AcceptHighLevelEvent", MacOS_AcceptHighLevelEvent
, 1, accepthle_doc
},
683 {"GetCreatorAndType", MacOS_GetCreatorAndType
, 1, getcrtp_doc
},
684 {"SetCreatorAndType", MacOS_SetCreatorAndType
, 1, setcrtp_doc
},
685 {"SchedParams", MacOS_SchedParams
, 1, schedparams_doc
},
686 {"EnableAppswitch", MacOS_EnableAppswitch
, 1, appswitch_doc
},
687 {"SetEventHandler", MacOS_SetEventHandler
, 1, setevh_doc
},
688 {"HandleEvent", MacOS_HandleEvent
, 1, handleev_doc
},
689 {"GetErrorString", MacOS_GetErrorString
, 1, geterr_doc
},
690 {"openrf", MacOS_openrf
, 1, openrf_doc
},
691 {"splash", MacOS_splash
, 1, splash_doc
},
692 {"DebugStr", MacOS_DebugStr
, 1, DebugStr_doc
},
693 {"GetTicks", MacOS_GetTicks
, 1, GetTicks_doc
},
694 {"SysBeep", MacOS_SysBeep
, 1, SysBeep_doc
},
695 {"FreeMem", MacOS_FreeMem
, 1, FreeMem_doc
},
696 {"MaxBlock", MacOS_MaxBlock
, 1, MaxBlock_doc
},
697 {"CompactMem", MacOS_CompactMem
, 1, CompactMem_doc
},
698 {NULL
, NULL
} /* Sentinel */
707 m
= Py_InitModule("MacOS", MacOS_Methods
);
708 d
= PyModule_GetDict(m
);
710 /* Initialize MacOS.Error exception */
711 MacOS_Error
= PyMac_GetOSErrException();
712 if (MacOS_Error
== NULL
|| PyDict_SetItemString(d
, "Error", MacOS_Error
) != 0)
714 Rftype
.ob_type
= &PyType_Type
;
716 if (PyDict_SetItemString(d
, "ResourceForkType", (PyObject
*)&Rftype
) != 0)
719 ** This is a hack: the following constant added to the id() of a string
720 ** object gives you the address of the data. Unfortunately, it is needed for
721 ** some of the image and sound processing interfaces on the mac:-(
724 PyStringObject
*p
= 0;
725 long off
= (long)&(p
->ob_sval
[0]);
727 if( PyDict_SetItemString(d
, "string_id_to_buffer", Py_BuildValue("i", off
)) != 0)
730 if (PyDict_SetItemString(d
, "AppearanceCompliant",
731 Py_BuildValue("i", PyMac_AppearanceCompliant
)) != 0)