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 */
35 static PyObject
*MacOS_Error
; /* Exception MacOS.Error */
38 #define bufferIsSmall -607 /*error returns from Post and Accept */
41 static PyObject
*ErrorObject
;
43 /* ----------------------------------------------------- */
45 /* Declarations for objects of type Resource fork */
53 staticforward PyTypeObject Rftype
;
57 /* ---------------------------------------------------------------- */
63 if (self
->isclosed
) return;
64 (void)FSClose(self
->fRefNum
);
68 static char rf_read__doc__
[] =
69 "Read data from resource fork"
82 PyErr_SetString(PyExc_ValueError
, "Operation on closed file");
86 if (!PyArg_ParseTuple(args
, "l", &n
))
89 v
= PyString_FromStringAndSize((char *)NULL
, n
);
93 err
= FSRead(self
->fRefNum
, &n
, PyString_AsString(v
));
94 if (err
&& err
!= eofErr
) {
99 _PyString_Resize(&v
, n
);
104 static char rf_write__doc__
[] =
105 "Write to resource fork"
117 if (self
->isclosed
) {
118 PyErr_SetString(PyExc_ValueError
, "Operation on closed file");
121 if (!PyArg_ParseTuple(args
, "s#", &buffer
, &size
))
123 err
= FSWrite(self
->fRefNum
, &size
, buffer
);
133 static char rf_seek__doc__
[] =
143 int whence
= SEEK_SET
;
147 if (self
->isclosed
) {
148 PyErr_SetString(PyExc_ValueError
, "Operation on closed file");
151 if (!PyArg_ParseTuple(args
, "l|i", &amount
, &whence
))
154 if ( err
= GetEOF(self
->fRefNum
, &eof
))
159 if (err
= GetFPos(self
->fRefNum
, &pos
))
175 /* Don't bother implementing seek past EOF */
176 if (pos
> eof
|| pos
< 0) {
181 if ( err
= SetFPos(self
->fRefNum
, fsFromStart
, pos
) ) {
191 static char rf_tell__doc__
[] =
203 if (self
->isclosed
) {
204 PyErr_SetString(PyExc_ValueError
, "Operation on closed file");
207 if (!PyArg_ParseTuple(args
, ""))
209 if ( err
= GetFPos(self
->fRefNum
, &where
) ) {
213 return PyInt_FromLong(where
);
216 static char rf_close__doc__
[] =
217 "Close resource fork"
225 if (!PyArg_ParseTuple(args
, ""))
233 static struct PyMethodDef rf_methods
[] = {
234 {"read", rf_read
, 1, rf_read__doc__
},
235 {"write", rf_write
, 1, rf_write__doc__
},
236 {"seek", rf_seek
, 1, rf_seek__doc__
},
237 {"tell", rf_tell
, 1, rf_tell__doc__
},
238 {"close", rf_close
, 1, rf_close__doc__
},
240 {NULL
, NULL
} /* sentinel */
251 self
= PyObject_NEW(rfobject
, &Rftype
);
268 rf_getattr(self
, name
)
272 return Py_FindMethod(rf_methods
, (PyObject
*)self
, name
);
275 static char Rftype__doc__
[] =
276 "Resource fork file object"
279 static PyTypeObject Rftype
= {
280 PyObject_HEAD_INIT(&PyType_Type
)
282 "ResourceFork", /*tp_name*/
283 sizeof(rfobject
), /*tp_basicsize*/
286 (destructor
)rf_dealloc
, /*tp_dealloc*/
287 (printfunc
)0, /*tp_print*/
288 (getattrfunc
)rf_getattr
, /*tp_getattr*/
289 (setattrfunc
)0, /*tp_setattr*/
290 (cmpfunc
)0, /*tp_compare*/
291 (reprfunc
)0, /*tp_repr*/
293 0, /*tp_as_sequence*/
295 (hashfunc
)0, /*tp_hash*/
296 (ternaryfunc
)0, /*tp_call*/
297 (reprfunc
)0, /*tp_str*/
299 /* Space for future expansion */
301 Rftype__doc__
/* Documentation string */
304 /* End of code for Resource fork objects */
305 /* -------------------------------------------------------- */
307 /*----------------------------------------------------------------------*/
308 /* Miscellaneous File System Operations */
310 static char getcrtp_doc
[] = "Obsolete, use macfs module";
313 MacOS_GetCreatorAndType(PyObject
*self
, PyObject
*args
)
317 PyObject
*creator
, *type
, *res
;
320 if (!PyArg_ParseTuple(args
, "O&", PyMac_GetStr255
, &name
))
322 if ((err
= GetFInfo(name
, 0, &info
)) != noErr
)
323 return PyErr_Mac(MacOS_Error
, err
);
324 creator
= PyString_FromStringAndSize((char *)&info
.fdCreator
, 4);
325 type
= PyString_FromStringAndSize((char *)&info
.fdType
, 4);
326 res
= Py_BuildValue("OO", creator
, type
);
332 static char setcrtp_doc
[] = "Obsolete, use macfs module";
335 MacOS_SetCreatorAndType(PyObject
*self
, PyObject
*args
)
338 ResType creator
, type
;
342 if (!PyArg_ParseTuple(args
, "O&O&O&",
343 PyMac_GetStr255
, &name
, PyMac_GetOSType
, &creator
, PyMac_GetOSType
, &type
))
345 if ((err
= GetFInfo(name
, 0, &info
)) != noErr
)
346 return PyErr_Mac(MacOS_Error
, err
);
347 info
.fdCreator
= creator
;
349 if ((err
= SetFInfo(name
, 0, &info
)) != noErr
)
350 return PyErr_Mac(MacOS_Error
, err
);
355 /*----------------------------------------------------------------------*/
356 /* STDWIN High Level Event interface */
363 extern void (*_w_high_level_event_proc
)(EventRecord
*);
365 static PyObject
*MacOS_HighLevelEventHandler
= NULL
;
368 MacOS_HighLevelEventProc(EventRecord
*e
)
370 if (MacOS_HighLevelEventHandler
!= NULL
) {
371 PyObject
*args
= PyMac_BuildEventRecord(e
);
376 res
= PyEval_CallObject(MacOS_HighLevelEventHandler
, args
);
380 PySys_WriteStderr("Exception in MacOS_HighLevelEventProc:\n");
388 /* XXXX Need to come here from PyMac_DoYield too... */
391 MacOS_SetHighLevelEventHandler(self
, args
)
395 PyObject
*previous
= MacOS_HighLevelEventHandler
;
396 PyObject
*next
= NULL
;
397 if (!PyArg_ParseTuple(args
, "|O", &next
))
402 MacOS_HighLevelEventHandler
= next
;
404 _w_high_level_event_proc
= NULL
;
406 _w_high_level_event_proc
= MacOS_HighLevelEventProc
;
407 if (previous
== NULL
) {
414 #endif /* USE_STDWIN */
416 static char accepthle_doc
[] = "Get arguments of pending high-level event";
419 MacOS_AcceptHighLevelEvent(self
, args
)
424 unsigned long refcon
;
432 err
= AcceptHighLevelEvent(&sender
, &refcon
, buf
, &len
);
433 if (err
== bufferIsSmall
) {
436 return PyErr_NoMemory();
437 err
= AcceptHighLevelEvent(&sender
, &refcon
, buf
, &len
);
440 return PyErr_Mac(MacOS_Error
, (int)err
);
443 else if (err
!= noErr
)
444 return PyErr_Mac(MacOS_Error
, (int)err
);
445 res
= Py_BuildValue("s#ls#",
446 (char *)&sender
, (int)(sizeof sender
), refcon
, (char *)buf
, (int)len
);
451 static char schedparams_doc
[] = "Set/return mainloop interrupt check flag, etc";
454 ** Set scheduler parameters
457 MacOS_SchedParams(PyObject
*self
, PyObject
*args
)
459 PyMacSchedParams old
, new;
461 PyMac_GetSchedParams(&old
);
463 if (!PyArg_ParseTuple(args
, "|iiidd", &new.check_interrupt
, &new.process_events
,
464 &new.besocial
, &new.check_interval
, &new.bg_yield
))
466 PyMac_SetSchedParams(&new);
467 return Py_BuildValue("iiidd", old
.check_interrupt
, old
.process_events
,
468 old
.besocial
, old
.check_interval
, old
.bg_yield
);
471 static char appswitch_doc
[] = "Obsolete, use SchedParams";
473 /* Obsolete, for backward compatability */
475 MacOS_EnableAppswitch(PyObject
*self
, PyObject
*args
)
478 PyMacSchedParams schp
;
480 if (!PyArg_ParseTuple(args
, "i", &new))
482 PyMac_GetSchedParams(&schp
);
483 if ( schp
.process_events
)
485 else if ( schp
.check_interrupt
)
490 schp
.process_events
= mDownMask
|keyDownMask
|osMask
;
491 schp
.check_interrupt
= 1;
492 } else if ( new == 0 ) {
493 schp
.process_events
= 0;
494 schp
.check_interrupt
= 1;
496 schp
.process_events
= 0;
497 schp
.check_interrupt
= 0;
499 PyMac_SetSchedParams(&schp
);
500 return Py_BuildValue("i", old
);
503 static char setevh_doc
[] = "Set python event handler to be called in mainloop";
506 MacOS_SetEventHandler(self
, args
)
510 PyObject
*evh
= NULL
;
512 if (!PyArg_ParseTuple(args
, "|O", &evh
))
516 if ( evh
&& !PyCallable_Check(evh
) ) {
517 PyErr_SetString(PyExc_ValueError
, "SetEventHandler argument must be callable");
520 if ( !PyMac_SetEventHandler(evh
) )
526 static char handleev_doc
[] = "Pass event to other interested parties like sioux";
529 MacOS_HandleEvent(PyObject
*self
, PyObject
*args
)
533 if (!PyArg_ParseTuple(args
, "O&", PyMac_GetEventRecord
, &ev
))
535 PyMac_HandleEventIntern(&ev
);
540 static char geterr_doc
[] = "Convert OSErr number to string";
543 MacOS_GetErrorString(PyObject
*self
, PyObject
*args
)
547 if (!PyArg_ParseTuple(args
, "i", &errn
))
549 return Py_BuildValue("s", PyMac_StrError(errn
));
552 static char splash_doc
[] = "Open a splash-screen dialog by resource-id (0=close)";
555 MacOS_splash(PyObject
*self
, PyObject
*args
)
558 static DialogPtr curdialog
= NULL
;
562 short xpos
, ypos
, width
, height
, swidth
, sheight
;
564 if (!PyArg_ParseTuple(args
, "|i", &resid
))
566 olddialog
= curdialog
;
570 curdialog
= GetNewDialog(resid
, NULL
, (WindowPtr
)-1);
572 theWindow
= GetDialogWindow(curdialog
);
573 thePort
= GetWindowPort(theWindow
);
574 width
= thePort
->portRect
.right
- thePort
->portRect
.left
;
575 height
= thePort
->portRect
.bottom
- thePort
->portRect
.top
;
576 swidth
= qd
.screenBits
.bounds
.right
- qd
.screenBits
.bounds
.left
;
577 sheight
= qd
.screenBits
.bounds
.bottom
- qd
.screenBits
.bounds
.top
- LMGetMBarHeight();
578 xpos
= (swidth
-width
)/2;
579 ypos
= (sheight
-height
)/5 + LMGetMBarHeight();
580 MoveWindow(theWindow
, xpos
, ypos
, 0);
581 ShowWindow(theWindow
);
582 DrawDialog(curdialog
);
586 DisposeDialog(olddialog
);
591 static char DebugStr_doc
[] = "Switch to low-level debugger with a message";
594 MacOS_DebugStr(PyObject
*self
, PyObject
*args
)
597 PyObject
*object
= 0;
599 if (!PyArg_ParseTuple(args
, "O&|O", PyMac_GetStr255
, message
, &object
))
606 static char SysBeep_doc
[] = "BEEEEEP!!!";
609 MacOS_SysBeep(PyObject
*self
, PyObject
*args
)
613 if (!PyArg_ParseTuple(args
, "|i", &duration
))
620 static char GetTicks_doc
[] = "Return number of ticks since bootup";
623 MacOS_GetTicks(PyObject
*self
, PyObject
*args
)
625 return Py_BuildValue("i", (int)LMGetTicks());
628 static char openrf_doc
[] = "Open resource fork of a file";
631 MacOS_openrf(PyObject
*self
, PyObject
*args
)
636 SignedByte permission
= 1;
639 if (!PyArg_ParseTuple(args
, "O&|s", PyMac_GetFSSpec
, &fss
, &mode
))
644 case 'r': permission
= 1; break;
645 case 'w': permission
= 2; break;
653 if ( (fp
= newrfobject()) == NULL
)
656 err
= HOpenRF(fss
.vRefNum
, fss
.parID
, fss
.name
, permission
, &fp
->fRefNum
);
658 if ( err
== fnfErr
) {
659 /* In stead of doing complicated things here to get creator/type
660 ** correct we let the standard i/o library handle it
665 if ( err
=PyMac_GetFullPath(&fss
, pathname
) ) {
671 if ( (tfp
= fopen(pathname
, "w")) == NULL
) {
672 PyMac_Error(fnfErr
); /* What else... */
677 err
= HOpenRF(fss
.vRefNum
, fss
.parID
, fss
.name
, permission
, &fp
->fRefNum
);
685 return (PyObject
*)fp
;
688 static PyMethodDef MacOS_Methods
[] = {
689 {"AcceptHighLevelEvent", MacOS_AcceptHighLevelEvent
, 1, accepthle_doc
},
690 {"GetCreatorAndType", MacOS_GetCreatorAndType
, 1, getcrtp_doc
},
691 {"SetCreatorAndType", MacOS_SetCreatorAndType
, 1, setcrtp_doc
},
693 {"SetHighLevelEventHandler", MacOS_SetHighLevelEventHandler
, 1},
695 {"SchedParams", MacOS_SchedParams
, 1, schedparams_doc
},
696 {"EnableAppswitch", MacOS_EnableAppswitch
, 1, appswitch_doc
},
697 {"SetEventHandler", MacOS_SetEventHandler
, 1, setevh_doc
},
698 {"HandleEvent", MacOS_HandleEvent
, 1, handleev_doc
},
699 {"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
},
703 {"GetTicks", MacOS_GetTicks
, 1, GetTicks_doc
},
704 {"SysBeep", MacOS_SysBeep
, 1, SysBeep_doc
},
705 {NULL
, NULL
} /* Sentinel */
714 m
= Py_InitModule("MacOS", MacOS_Methods
);
715 d
= PyModule_GetDict(m
);
717 /* Initialize MacOS.Error exception */
718 MacOS_Error
= PyMac_GetOSErrException();
719 if (MacOS_Error
== NULL
|| PyDict_SetItemString(d
, "Error", MacOS_Error
) != 0)
720 Py_FatalError("can't define MacOS.Error");
721 Rftype
.ob_type
= &PyType_Type
;
723 if (PyDict_SetItemString(d
, "ResourceForkType", (PyObject
*)&Rftype
) != 0)
724 Py_FatalError("can't define MacOS.ResourceForkType");
726 ** This is a hack: the following constant added to the id() of a string
727 ** object gives you the address of the data. Unfortunately, it is needed for
728 ** some of the image and sound processing interfaces on the mac:-(
731 PyStringObject
*p
= 0;
732 long off
= (long)&(p
->ob_sval
[0]);
734 if( PyDict_SetItemString(d
, "string_id_to_buffer", Py_BuildValue("i", off
)) != 0)
735 Py_FatalError("Can't define MacOS.string_id_to_buffer");