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 */
34 static PyObject
*MacOS_Error
; /* Exception MacOS.Error */
37 #define bufferIsSmall -607 /*error returns from Post and Accept */
40 static PyObject
*ErrorObject
;
42 /* ----------------------------------------------------- */
44 /* Declarations for objects of type Resource fork */
52 staticforward PyTypeObject Rftype
;
56 /* ---------------------------------------------------------------- */
62 if (self
->isclosed
) return;
63 (void)FSClose(self
->fRefNum
);
67 static char rf_read__doc__
[] =
68 "Read data from resource fork"
81 PyErr_SetString(PyExc_ValueError
, "Operation on closed file");
85 if (!PyArg_ParseTuple(args
, "l", &n
))
88 v
= PyString_FromStringAndSize((char *)NULL
, n
);
92 err
= FSRead(self
->fRefNum
, &n
, PyString_AsString(v
));
93 if (err
&& err
!= eofErr
) {
98 _PyString_Resize(&v
, n
);
103 static char rf_write__doc__
[] =
104 "Write to resource fork"
116 if (self
->isclosed
) {
117 PyErr_SetString(PyExc_ValueError
, "Operation on closed file");
120 if (!PyArg_ParseTuple(args
, "s#", &buffer
, &size
))
122 err
= FSWrite(self
->fRefNum
, &size
, buffer
);
132 static char rf_seek__doc__
[] =
142 int whence
= SEEK_SET
;
146 if (self
->isclosed
) {
147 PyErr_SetString(PyExc_ValueError
, "Operation on closed file");
150 if (!PyArg_ParseTuple(args
, "l|i", &amount
, &whence
))
153 if ( err
= GetEOF(self
->fRefNum
, &eof
))
158 if (err
= GetFPos(self
->fRefNum
, &pos
))
174 /* Don't bother implementing seek past EOF */
175 if (pos
> eof
|| pos
< 0) {
180 if ( err
= SetFPos(self
->fRefNum
, fsFromStart
, pos
) ) {
190 static char rf_tell__doc__
[] =
202 if (self
->isclosed
) {
203 PyErr_SetString(PyExc_ValueError
, "Operation on closed file");
206 if (!PyArg_ParseTuple(args
, ""))
208 if ( err
= GetFPos(self
->fRefNum
, &where
) ) {
212 return PyInt_FromLong(where
);
215 static char rf_close__doc__
[] =
216 "Close resource fork"
224 if (!PyArg_ParseTuple(args
, ""))
232 static struct PyMethodDef rf_methods
[] = {
233 {"read", rf_read
, 1, rf_read__doc__
},
234 {"write", rf_write
, 1, rf_write__doc__
},
235 {"seek", rf_seek
, 1, rf_seek__doc__
},
236 {"tell", rf_tell
, 1, rf_tell__doc__
},
237 {"close", rf_close
, 1, rf_close__doc__
},
239 {NULL
, NULL
} /* sentinel */
250 self
= PyObject_NEW(rfobject
, &Rftype
);
267 rf_getattr(self
, name
)
271 return Py_FindMethod(rf_methods
, (PyObject
*)self
, name
);
274 static char Rftype__doc__
[] =
275 "Resource fork file object"
278 static PyTypeObject Rftype
= {
279 PyObject_HEAD_INIT(&PyType_Type
)
281 "ResourceFork", /*tp_name*/
282 sizeof(rfobject
), /*tp_basicsize*/
285 (destructor
)rf_dealloc
, /*tp_dealloc*/
286 (printfunc
)0, /*tp_print*/
287 (getattrfunc
)rf_getattr
, /*tp_getattr*/
288 (setattrfunc
)0, /*tp_setattr*/
289 (cmpfunc
)0, /*tp_compare*/
290 (reprfunc
)0, /*tp_repr*/
292 0, /*tp_as_sequence*/
294 (hashfunc
)0, /*tp_hash*/
295 (ternaryfunc
)0, /*tp_call*/
296 (reprfunc
)0, /*tp_str*/
298 /* Space for future expansion */
300 Rftype__doc__
/* Documentation string */
303 /* End of code for Resource fork objects */
304 /* -------------------------------------------------------- */
306 /*----------------------------------------------------------------------*/
307 /* Miscellaneous File System Operations */
309 static char getcrtp_doc
[] = "Obsolete, use macfs module";
312 MacOS_GetCreatorAndType(PyObject
*self
, PyObject
*args
)
316 PyObject
*creator
, *type
, *res
;
319 if (!PyArg_ParseTuple(args
, "O&", PyMac_GetStr255
, &name
))
321 if ((err
= GetFInfo(name
, 0, &info
)) != noErr
)
322 return PyErr_Mac(MacOS_Error
, err
);
323 creator
= PyString_FromStringAndSize((char *)&info
.fdCreator
, 4);
324 type
= PyString_FromStringAndSize((char *)&info
.fdType
, 4);
325 res
= Py_BuildValue("OO", creator
, type
);
331 static char setcrtp_doc
[] = "Obsolete, use macfs module";
334 MacOS_SetCreatorAndType(PyObject
*self
, PyObject
*args
)
337 ResType creator
, type
;
341 if (!PyArg_ParseTuple(args
, "O&O&O&",
342 PyMac_GetStr255
, &name
, PyMac_GetOSType
, &creator
, PyMac_GetOSType
, &type
))
344 if ((err
= GetFInfo(name
, 0, &info
)) != noErr
)
345 return PyErr_Mac(MacOS_Error
, err
);
346 info
.fdCreator
= creator
;
348 if ((err
= SetFInfo(name
, 0, &info
)) != noErr
)
349 return PyErr_Mac(MacOS_Error
, err
);
354 /*----------------------------------------------------------------------*/
355 /* STDWIN High Level Event interface */
362 extern void (*_w_high_level_event_proc
)(EventRecord
*);
364 static PyObject
*MacOS_HighLevelEventHandler
= NULL
;
367 MacOS_HighLevelEventProc(EventRecord
*e
)
369 if (MacOS_HighLevelEventHandler
!= NULL
) {
370 PyObject
*args
= PyMac_BuildEventRecord(e
);
375 res
= PyEval_CallObject(MacOS_HighLevelEventHandler
, args
);
379 fprintf(stderr
, "Exception in MacOS_HighLevelEventProc:\n");
387 /* XXXX Need to come here from PyMac_DoYield too... */
390 MacOS_SetHighLevelEventHandler(self
, args
)
394 PyObject
*previous
= MacOS_HighLevelEventHandler
;
395 PyObject
*next
= NULL
;
396 if (!PyArg_ParseTuple(args
, "|O", &next
))
401 MacOS_HighLevelEventHandler
= next
;
403 _w_high_level_event_proc
= NULL
;
405 _w_high_level_event_proc
= MacOS_HighLevelEventProc
;
406 if (previous
== NULL
) {
413 #endif /* USE_STDWIN */
415 static char accepthle_doc
[] = "Get arguments of pending high-level event";
418 MacOS_AcceptHighLevelEvent(self
, args
)
423 unsigned long refcon
;
431 err
= AcceptHighLevelEvent(&sender
, &refcon
, buf
, &len
);
432 if (err
== bufferIsSmall
) {
435 return PyErr_NoMemory();
436 err
= AcceptHighLevelEvent(&sender
, &refcon
, buf
, &len
);
439 return PyErr_Mac(MacOS_Error
, (int)err
);
442 else if (err
!= noErr
)
443 return PyErr_Mac(MacOS_Error
, (int)err
);
444 res
= Py_BuildValue("s#ls#",
445 (char *)&sender
, (int)(sizeof sender
), refcon
, (char *)buf
, (int)len
);
450 static char schedparams_doc
[] = "Set/return mainloop interrupt check flag, etc";
453 ** Set scheduler parameters
456 MacOS_SchedParams(PyObject
*self
, PyObject
*args
)
458 PyMacSchedParams old
, new;
460 PyMac_GetSchedParams(&old
);
462 if (!PyArg_ParseTuple(args
, "|iiidd", &new.check_interrupt
, &new.process_events
,
463 &new.besocial
, &new.check_interval
, &new.bg_yield
))
465 PyMac_SetSchedParams(&new);
466 return Py_BuildValue("iiidd", old
.check_interrupt
, old
.process_events
,
467 old
.besocial
, old
.check_interval
, old
.bg_yield
);
470 static char appswitch_doc
[] = "Obsolete, use SchedParams";
472 /* Obsolete, for backward compatability */
474 MacOS_EnableAppswitch(PyObject
*self
, PyObject
*args
)
477 PyMacSchedParams schp
;
479 if (!PyArg_ParseTuple(args
, "i", &new))
481 PyMac_GetSchedParams(&schp
);
482 if ( schp
.process_events
)
484 else if ( schp
.check_interrupt
)
489 schp
.process_events
= mDownMask
|keyDownMask
|osMask
;
490 schp
.check_interrupt
= 1;
491 } else if ( new == 0 ) {
492 schp
.process_events
= 0;
493 schp
.check_interrupt
= 1;
495 schp
.process_events
= 0;
496 schp
.check_interrupt
= 0;
498 PyMac_SetSchedParams(&schp
);
499 return Py_BuildValue("i", old
);
502 static char setevh_doc
[] = "Set python event handler to be called in mainloop";
505 MacOS_SetEventHandler(self
, args
)
509 PyObject
*evh
= NULL
;
511 if (!PyArg_ParseTuple(args
, "|O", &evh
))
515 if ( evh
&& !PyCallable_Check(evh
) ) {
516 PyErr_SetString(PyExc_ValueError
, "SetEventHandler argument must be callable");
519 if ( !PyMac_SetEventHandler(evh
) )
525 static char handleev_doc
[] = "Pass event to other interested parties like sioux";
528 MacOS_HandleEvent(PyObject
*self
, PyObject
*args
)
532 if (!PyArg_ParseTuple(args
, "O&", PyMac_GetEventRecord
, &ev
))
534 PyMac_HandleEventIntern(&ev
);
539 static char geterr_doc
[] = "Convert OSErr number to string";
542 MacOS_GetErrorString(PyObject
*self
, PyObject
*args
)
546 if (!PyArg_ParseTuple(args
, "i", &errn
))
548 return Py_BuildValue("s", PyMac_StrError(errn
));
551 static char splash_doc
[] = "Open a splash-screen dialog by resource-id (0=close)";
554 MacOS_splash(PyObject
*self
, PyObject
*args
)
557 static DialogPtr curdialog
= NULL
;
561 short xpos
, ypos
, width
, height
, swidth
, sheight
;
563 if (!PyArg_ParseTuple(args
, "|i", &resid
))
565 olddialog
= curdialog
;
568 curdialog
= GetNewDialog(resid
, NULL
, (WindowPtr
)-1);
570 theWindow
= GetDialogWindow(curdialog
);
571 thePort
= GetWindowPort(theWindow
);
572 width
= thePort
->portRect
.right
- thePort
->portRect
.left
;
573 height
= thePort
->portRect
.bottom
- thePort
->portRect
.top
;
574 swidth
= qd
.screenBits
.bounds
.right
- qd
.screenBits
.bounds
.left
;
575 sheight
= qd
.screenBits
.bounds
.bottom
- qd
.screenBits
.bounds
.top
- LMGetMBarHeight();
576 xpos
= (swidth
-width
)/2;
577 ypos
= (sheight
-height
)/5 + LMGetMBarHeight();
578 MoveWindow(theWindow
, xpos
, ypos
, 0);
579 ShowWindow(theWindow
);
580 DrawDialog(curdialog
);
584 DisposeDialog(olddialog
);
589 static char DebugStr_doc
[] = "Switch to low-level debugger with a message";
592 MacOS_DebugStr(PyObject
*self
, PyObject
*args
)
595 PyObject
*object
= 0;
597 if (!PyArg_ParseTuple(args
, "O&|O", PyMac_GetStr255
, message
, &object
))
604 static char SysBeep_doc
[] = "BEEEEEP!!!";
607 MacOS_SysBeep(PyObject
*self
, PyObject
*args
)
611 if (!PyArg_ParseTuple(args
, "|i", &duration
))
618 static char GetTicks_doc
[] = "Return number of ticks since bootup";
621 MacOS_GetTicks(PyObject
*self
, PyObject
*args
)
623 return Py_BuildValue("i", (int)LMGetTicks());
626 static char openrf_doc
[] = "Open resource fork of a file";
629 MacOS_openrf(PyObject
*self
, PyObject
*args
)
634 SignedByte permission
= 1;
637 if (!PyArg_ParseTuple(args
, "O&|s", PyMac_GetFSSpec
, &fss
, &mode
))
642 case 'r': permission
= 1; break;
643 case 'w': permission
= 2; break;
651 if ( (fp
= newrfobject()) == NULL
)
654 err
= HOpenRF(fss
.vRefNum
, fss
.parID
, fss
.name
, permission
, &fp
->fRefNum
);
656 if ( err
== fnfErr
) {
657 /* In stead of doing complicated things here to get creator/type
658 ** correct we let the standard i/o library handle it
663 if ( err
=PyMac_GetFullPath(&fss
, pathname
) ) {
669 if ( (tfp
= fopen(pathname
, "w")) == NULL
) {
670 PyMac_Error(fnfErr
); /* What else... */
675 err
= HOpenRF(fss
.vRefNum
, fss
.parID
, fss
.name
, permission
, &fp
->fRefNum
);
683 return (PyObject
*)fp
;
686 static PyMethodDef MacOS_Methods
[] = {
687 {"AcceptHighLevelEvent", MacOS_AcceptHighLevelEvent
, 1, accepthle_doc
},
688 {"GetCreatorAndType", MacOS_GetCreatorAndType
, 1, getcrtp_doc
},
689 {"SetCreatorAndType", MacOS_SetCreatorAndType
, 1, setcrtp_doc
},
691 {"SetHighLevelEventHandler", MacOS_SetHighLevelEventHandler
, 1},
693 {"SchedParams", MacOS_SchedParams
, 1, schedparams_doc
},
694 {"EnableAppswitch", MacOS_EnableAppswitch
, 1, appswitch_doc
},
695 {"SetEventHandler", MacOS_SetEventHandler
, 1, setevh_doc
},
696 {"HandleEvent", MacOS_HandleEvent
, 1, handleev_doc
},
697 {"GetErrorString", MacOS_GetErrorString
, 1, geterr_doc
},
698 {"openrf", MacOS_openrf
, 1, openrf_doc
},
699 {"splash", MacOS_splash
, 1, splash_doc
},
700 {"DebugStr", MacOS_DebugStr
, 1, DebugStr_doc
},
701 {"GetTicks", MacOS_GetTicks
, 1, GetTicks_doc
},
702 {"SysBeep", MacOS_SysBeep
, 1, SysBeep_doc
},
703 {NULL
, NULL
} /* Sentinel */
712 m
= Py_InitModule("MacOS", MacOS_Methods
);
713 d
= PyModule_GetDict(m
);
715 /* Initialize MacOS.Error exception */
716 MacOS_Error
= PyMac_GetOSErrException();
717 if (MacOS_Error
== NULL
|| PyDict_SetItemString(d
, "Error", MacOS_Error
) != 0)
718 Py_FatalError("can't define MacOS.Error");
719 Rftype
.ob_type
= &PyType_Type
;
721 if (PyDict_SetItemString(d
, "ResourceForkType", (PyObject
*)&Rftype
) != 0)
722 Py_FatalError("can't define MacOS.ResourceForkType");
724 ** This is a hack: the following constant added to the id() of a string
725 ** object gives you the address of the data. Unfortunately, it is needed for
726 ** some of the image and sound processing interfaces on the mac:-(
729 PyStringObject
*p
= 0;
730 long off
= (long)&(p
->ob_sval
[0]);
732 if( PyDict_SetItemString(d
, "string_id_to_buffer", Py_BuildValue("i", off
)) != 0)
733 Py_FatalError("Can't define MacOS.string_id_to_buffer");