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 */
29 #include "pythonresources.h"
37 static PyObject
*MacOS_Error
; /* Exception MacOS.Error */
40 #define bufferIsSmall -607 /*error returns from Post and Accept */
43 static PyObject
*ErrorObject
;
45 /* ----------------------------------------------------- */
47 /* Declarations for objects of type Resource fork */
55 staticforward PyTypeObject Rftype
;
59 /* ---------------------------------------------------------------- */
65 if (self
->isclosed
) return;
66 (void)FSClose(self
->fRefNum
);
70 static char rf_read__doc__
[] =
71 "Read data from resource fork"
84 PyErr_SetString(PyExc_ValueError
, "Operation on closed file");
88 if (!PyArg_ParseTuple(args
, "l", &n
))
91 v
= PyString_FromStringAndSize((char *)NULL
, n
);
95 err
= FSRead(self
->fRefNum
, &n
, PyString_AsString(v
));
96 if (err
&& err
!= eofErr
) {
101 _PyString_Resize(&v
, n
);
106 static char rf_write__doc__
[] =
107 "Write to resource fork"
119 if (self
->isclosed
) {
120 PyErr_SetString(PyExc_ValueError
, "Operation on closed file");
123 if (!PyArg_ParseTuple(args
, "s#", &buffer
, &size
))
125 err
= FSWrite(self
->fRefNum
, &size
, buffer
);
135 static char rf_seek__doc__
[] =
145 int whence
= SEEK_SET
;
149 if (self
->isclosed
) {
150 PyErr_SetString(PyExc_ValueError
, "Operation on closed file");
153 if (!PyArg_ParseTuple(args
, "l|i", &amount
, &whence
))
156 if ( err
= GetEOF(self
->fRefNum
, &eof
))
161 if (err
= GetFPos(self
->fRefNum
, &pos
))
177 /* Don't bother implementing seek past EOF */
178 if (pos
> eof
|| pos
< 0) {
183 if ( err
= SetFPos(self
->fRefNum
, fsFromStart
, pos
) ) {
193 static char rf_tell__doc__
[] =
205 if (self
->isclosed
) {
206 PyErr_SetString(PyExc_ValueError
, "Operation on closed file");
209 if (!PyArg_ParseTuple(args
, ""))
211 if ( err
= GetFPos(self
->fRefNum
, &where
) ) {
215 return PyInt_FromLong(where
);
218 static char rf_close__doc__
[] =
219 "Close resource fork"
227 if (!PyArg_ParseTuple(args
, ""))
235 static struct PyMethodDef rf_methods
[] = {
236 {"read", rf_read
, 1, rf_read__doc__
},
237 {"write", rf_write
, 1, rf_write__doc__
},
238 {"seek", rf_seek
, 1, rf_seek__doc__
},
239 {"tell", rf_tell
, 1, rf_tell__doc__
},
240 {"close", rf_close
, 1, rf_close__doc__
},
242 {NULL
, NULL
} /* sentinel */
253 self
= PyObject_NEW(rfobject
, &Rftype
);
270 rf_getattr(self
, name
)
274 return Py_FindMethod(rf_methods
, (PyObject
*)self
, name
);
277 static char Rftype__doc__
[] =
278 "Resource fork file object"
281 static PyTypeObject Rftype
= {
282 PyObject_HEAD_INIT(&PyType_Type
)
284 "ResourceFork", /*tp_name*/
285 sizeof(rfobject
), /*tp_basicsize*/
288 (destructor
)rf_dealloc
, /*tp_dealloc*/
289 (printfunc
)0, /*tp_print*/
290 (getattrfunc
)rf_getattr
, /*tp_getattr*/
291 (setattrfunc
)0, /*tp_setattr*/
292 (cmpfunc
)0, /*tp_compare*/
293 (reprfunc
)0, /*tp_repr*/
295 0, /*tp_as_sequence*/
297 (hashfunc
)0, /*tp_hash*/
298 (ternaryfunc
)0, /*tp_call*/
299 (reprfunc
)0, /*tp_str*/
301 /* Space for future expansion */
303 Rftype__doc__
/* Documentation string */
306 /* End of code for Resource fork objects */
307 /* -------------------------------------------------------- */
309 /*----------------------------------------------------------------------*/
310 /* Miscellaneous File System Operations */
312 static char getcrtp_doc
[] = "Obsolete, use macfs module";
315 MacOS_GetCreatorAndType(PyObject
*self
, PyObject
*args
)
319 PyObject
*creator
, *type
, *res
;
322 if (!PyArg_ParseTuple(args
, "O&", PyMac_GetFSSpec
, &fss
))
324 if ((err
= FSpGetFInfo(&fss
, &info
)) != noErr
)
325 return PyErr_Mac(MacOS_Error
, err
);
326 creator
= PyString_FromStringAndSize((char *)&info
.fdCreator
, 4);
327 type
= PyString_FromStringAndSize((char *)&info
.fdType
, 4);
328 res
= Py_BuildValue("OO", creator
, type
);
334 static char setcrtp_doc
[] = "Obsolete, use macfs module";
337 MacOS_SetCreatorAndType(PyObject
*self
, PyObject
*args
)
340 ResType creator
, type
;
344 if (!PyArg_ParseTuple(args
, "O&O&O&",
345 PyMac_GetFSSpec
, &fss
, PyMac_GetOSType
, &creator
, PyMac_GetOSType
, &type
))
347 if ((err
= FSpGetFInfo(&fss
, &info
)) != noErr
)
348 return PyErr_Mac(MacOS_Error
, err
);
349 info
.fdCreator
= creator
;
351 if ((err
= FSpSetFInfo(&fss
, &info
)) != noErr
)
352 return PyErr_Mac(MacOS_Error
, err
);
357 /*----------------------------------------------------------------------*/
358 /* STDWIN High Level Event interface */
363 #if !TARGET_API_MAC_CARBON
364 static char accepthle_doc
[] = "Get arguments of pending high-level event";
367 MacOS_AcceptHighLevelEvent(self
, args
)
372 unsigned long refcon
;
380 err
= AcceptHighLevelEvent(&sender
, &refcon
, buf
, &len
);
381 if (err
== bufferIsSmall
) {
384 return PyErr_NoMemory();
385 err
= AcceptHighLevelEvent(&sender
, &refcon
, buf
, &len
);
388 return PyErr_Mac(MacOS_Error
, (int)err
);
391 else if (err
!= noErr
)
392 return PyErr_Mac(MacOS_Error
, (int)err
);
393 res
= Py_BuildValue("s#ls#",
394 (char *)&sender
, (int)(sizeof sender
), refcon
, (char *)buf
, (int)len
);
399 static char schedparams_doc
[] = "Set/return mainloop interrupt check flag, etc";
402 ** Set scheduler parameters
405 MacOS_SchedParams(PyObject
*self
, PyObject
*args
)
407 PyMacSchedParams old
, new;
409 PyMac_GetSchedParams(&old
);
411 if (!PyArg_ParseTuple(args
, "|iiidd", &new.check_interrupt
, &new.process_events
,
412 &new.besocial
, &new.check_interval
, &new.bg_yield
))
414 PyMac_SetSchedParams(&new);
415 return Py_BuildValue("iiidd", old
.check_interrupt
, old
.process_events
,
416 old
.besocial
, old
.check_interval
, old
.bg_yield
);
419 static char appswitch_doc
[] = "Obsolete, use SchedParams";
421 /* Obsolete, for backward compatability */
423 MacOS_EnableAppswitch(PyObject
*self
, PyObject
*args
)
426 PyMacSchedParams schp
;
428 if (!PyArg_ParseTuple(args
, "i", &new))
430 PyMac_GetSchedParams(&schp
);
431 if ( schp
.process_events
)
433 else if ( schp
.check_interrupt
)
438 schp
.process_events
= mDownMask
|keyDownMask
|osMask
;
439 schp
.check_interrupt
= 1;
440 } else if ( new == 0 ) {
441 schp
.process_events
= 0;
442 schp
.check_interrupt
= 1;
444 schp
.process_events
= 0;
445 schp
.check_interrupt
= 0;
447 PyMac_SetSchedParams(&schp
);
448 return Py_BuildValue("i", old
);
451 static char setevh_doc
[] = "Set python event handler to be called in mainloop";
454 MacOS_SetEventHandler(self
, args
)
458 PyObject
*evh
= NULL
;
460 if (!PyArg_ParseTuple(args
, "|O", &evh
))
464 if ( evh
&& !PyCallable_Check(evh
) ) {
465 PyErr_SetString(PyExc_ValueError
, "SetEventHandler argument must be callable");
468 if ( !PyMac_SetEventHandler(evh
) )
474 static char handleev_doc
[] = "Pass event to other interested parties like sioux";
477 MacOS_HandleEvent(PyObject
*self
, PyObject
*args
)
481 if (!PyArg_ParseTuple(args
, "O&", PyMac_GetEventRecord
, &ev
))
483 PyMac_HandleEventIntern(&ev
);
488 static char geterr_doc
[] = "Convert OSErr number to string";
491 MacOS_GetErrorString(PyObject
*self
, PyObject
*args
)
495 if (!PyArg_ParseTuple(args
, "i", &errn
))
497 return Py_BuildValue("s", PyMac_StrError(errn
));
500 static char splash_doc
[] = "Open a splash-screen dialog by resource-id (0=close)";
503 MacOS_splash(PyObject
*self
, PyObject
*args
)
506 static DialogPtr curdialog
= NULL
;
511 short xpos
, ypos
, width
, height
, swidth
, sheight
;
514 if (!PyArg_ParseTuple(args
, "|i", &resid
))
516 olddialog
= curdialog
;
520 curdialog
= GetNewDialog(resid
, NULL
, (WindowPtr
)-1);
522 theWindow
= GetDialogWindow(curdialog
);
523 thePort
= GetWindowPort(theWindow
);
525 width
= thePort
->portRect
.right
- thePort
->portRect
.left
;
526 height
= thePort
->portRect
.bottom
- thePort
->portRect
.top
;
527 swidth
= qd
.screenBits
.bounds
.right
- qd
.screenBits
.bounds
.left
;
528 sheight
= qd
.screenBits
.bounds
.bottom
- qd
.screenBits
.bounds
.top
- LMGetMBarHeight();
529 xpos
= (swidth
-width
)/2;
530 ypos
= (sheight
-height
)/5 + LMGetMBarHeight();
531 MoveWindow(theWindow
, xpos
, ypos
, 0);
532 ShowWindow(theWindow
);
534 DrawDialog(curdialog
);
538 DisposeDialog(olddialog
);
543 static char DebugStr_doc
[] = "Switch to low-level debugger with a message";
546 MacOS_DebugStr(PyObject
*self
, PyObject
*args
)
549 PyObject
*object
= 0;
551 if (!PyArg_ParseTuple(args
, "O&|O", PyMac_GetStr255
, message
, &object
))
558 static char SysBeep_doc
[] = "BEEEEEP!!!";
561 MacOS_SysBeep(PyObject
*self
, PyObject
*args
)
565 if (!PyArg_ParseTuple(args
, "|i", &duration
))
572 static char GetTicks_doc
[] = "Return number of ticks since bootup";
575 MacOS_GetTicks(PyObject
*self
, PyObject
*args
)
577 return Py_BuildValue("i", (int)TickCount());
580 static char openrf_doc
[] = "Open resource fork of a file";
583 MacOS_openrf(PyObject
*self
, PyObject
*args
)
588 SignedByte permission
= 1;
591 if (!PyArg_ParseTuple(args
, "O&|s", PyMac_GetFSSpec
, &fss
, &mode
))
596 case 'r': permission
= 1; break;
597 case 'w': permission
= 2; break;
605 if ( (fp
= newrfobject()) == NULL
)
608 err
= HOpenRF(fss
.vRefNum
, fss
.parID
, fss
.name
, permission
, &fp
->fRefNum
);
610 if ( err
== fnfErr
) {
611 /* In stead of doing complicated things here to get creator/type
612 ** correct we let the standard i/o library handle it
617 if ( err
=PyMac_GetFullPath(&fss
, pathname
) ) {
623 if ( (tfp
= fopen(pathname
, "w")) == NULL
) {
624 PyMac_Error(fnfErr
); /* What else... */
629 err
= HOpenRF(fss
.vRefNum
, fss
.parID
, fss
.name
, permission
, &fp
->fRefNum
);
637 return (PyObject
*)fp
;
640 static char FreeMem_doc
[] = "Return the total amount of free space in the heap";
643 MacOS_FreeMem(PyObject
*self
, PyObject
*args
)
647 if (!PyArg_ParseTuple(args
, ""))
650 return Py_BuildValue("l", rv
);
653 static char MaxBlock_doc
[] = "Return the largest contiguous block of free space in the heap";
656 MacOS_MaxBlock(PyObject
*self
, PyObject
*args
)
660 if (!PyArg_ParseTuple(args
, ""))
663 return Py_BuildValue("l", rv
);
666 static char CompactMem_doc
[] = "(wanted size)->actual largest block after compacting";
669 MacOS_CompactMem(PyObject
*self
, PyObject
*args
)
674 if (!PyArg_ParseTuple(args
, "l", &value
))
676 rv
= CompactMem(value
);
677 return Py_BuildValue("l", rv
);
680 static char KeepConsole_doc
[] = "(flag) Keep console open 0:never, 1:on output 2:on error, 3:always";
683 MacOS_KeepConsole(PyObject
*self
, PyObject
*args
)
687 if (!PyArg_ParseTuple(args
, "i", &value
))
689 PyMac_options
.keep_console
= value
;
694 static char OutputSeen_doc
[] = "Call to reset the 'unseen output' flag for the keep-console-open option";
697 MacOS_OutputSeen(PyObject
*self
, PyObject
*args
)
699 if (!PyArg_ParseTuple(args
, ""))
706 static PyMethodDef MacOS_Methods
[] = {
707 #if !TARGET_API_MAC_CARBON
708 {"AcceptHighLevelEvent", MacOS_AcceptHighLevelEvent
, 1, accepthle_doc
},
710 {"GetCreatorAndType", MacOS_GetCreatorAndType
, 1, getcrtp_doc
},
711 {"SetCreatorAndType", MacOS_SetCreatorAndType
, 1, setcrtp_doc
},
712 {"SchedParams", MacOS_SchedParams
, 1, schedparams_doc
},
713 {"EnableAppswitch", MacOS_EnableAppswitch
, 1, appswitch_doc
},
714 {"SetEventHandler", MacOS_SetEventHandler
, 1, setevh_doc
},
715 {"HandleEvent", MacOS_HandleEvent
, 1, handleev_doc
},
716 {"GetErrorString", MacOS_GetErrorString
, 1, geterr_doc
},
717 {"openrf", MacOS_openrf
, 1, openrf_doc
},
718 {"splash", MacOS_splash
, 1, splash_doc
},
719 {"DebugStr", MacOS_DebugStr
, 1, DebugStr_doc
},
720 {"GetTicks", MacOS_GetTicks
, 1, GetTicks_doc
},
721 {"SysBeep", MacOS_SysBeep
, 1, SysBeep_doc
},
722 {"FreeMem", MacOS_FreeMem
, 1, FreeMem_doc
},
723 {"MaxBlock", MacOS_MaxBlock
, 1, MaxBlock_doc
},
724 {"CompactMem", MacOS_CompactMem
, 1, CompactMem_doc
},
725 {"KeepConsole", MacOS_KeepConsole
, 1, KeepConsole_doc
},
726 {"OutputSeen", MacOS_OutputSeen
, 1, OutputSeen_doc
},
727 {NULL
, NULL
} /* Sentinel */
736 m
= Py_InitModule("MacOS", MacOS_Methods
);
737 d
= PyModule_GetDict(m
);
739 /* Initialize MacOS.Error exception */
740 MacOS_Error
= PyMac_GetOSErrException();
741 if (MacOS_Error
== NULL
|| PyDict_SetItemString(d
, "Error", MacOS_Error
) != 0)
743 Rftype
.ob_type
= &PyType_Type
;
745 if (PyDict_SetItemString(d
, "ResourceForkType", (PyObject
*)&Rftype
) != 0)
748 ** This is a hack: the following constant added to the id() of a string
749 ** object gives you the address of the data. Unfortunately, it is needed for
750 ** some of the image and sound processing interfaces on the mac:-(
753 PyStringObject
*p
= 0;
754 long off
= (long)&(p
->ob_sval
[0]);
756 if( PyDict_SetItemString(d
, "string_id_to_buffer", Py_BuildValue("i", off
)) != 0)
759 if (PyDict_SetItemString(d
, "AppearanceCompliant",
760 Py_BuildValue("i", PyMac_AppearanceCompliant
)) != 0)
762 #if TARGET_API_MAC_CARBON
763 /* Will need a different name for MachO-carbon later (macho?) */
764 #define PY_RUNTIMEMODEL "carbon"
766 #define PY_RUNTIMEMODEL "ppc"
768 if (PyDict_SetItemString(d
, "runtimemodel",
769 Py_BuildValue("s", PY_RUNTIMEMODEL
)) != 0)