Fix an amazing number of typos & malformed sentences reported by Detlef
[python/dscho.git] / Mac / Modules / macosmodule.c
blob14f807c81c53609424d9f7b4de7ee54d2ed7cfbd
1 /***********************************************************
2 Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
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 */
27 #include "Python.h"
28 #include "macglue.h"
30 #include <Windows.h>
31 #include <Files.h>
32 #include <LowMem.h>
33 #include <Sound.h>
35 static PyObject *MacOS_Error; /* Exception MacOS.Error */
37 #ifdef MPW
38 #define bufferIsSmall -607 /*error returns from Post and Accept */
39 #endif
41 static PyObject *ErrorObject;
43 /* ----------------------------------------------------- */
45 /* Declarations for objects of type Resource fork */
47 typedef struct {
48 PyObject_HEAD
49 short fRefNum;
50 int isclosed;
51 } rfobject;
53 staticforward PyTypeObject Rftype;
57 /* ---------------------------------------------------------------- */
59 static void
60 do_close(self)
61 rfobject *self;
63 if (self->isclosed ) return;
64 (void)FSClose(self->fRefNum);
65 self->isclosed = 1;
68 static char rf_read__doc__[] =
69 "Read data from resource fork"
72 static PyObject *
73 rf_read(self, args)
74 rfobject *self;
75 PyObject *args;
77 long n;
78 PyObject *v;
79 OSErr err;
81 if (self->isclosed) {
82 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
83 return NULL;
86 if (!PyArg_ParseTuple(args, "l", &n))
87 return NULL;
89 v = PyString_FromStringAndSize((char *)NULL, n);
90 if (v == NULL)
91 return NULL;
93 err = FSRead(self->fRefNum, &n, PyString_AsString(v));
94 if (err && err != eofErr) {
95 PyMac_Error(err);
96 Py_DECREF(v);
97 return NULL;
99 _PyString_Resize(&v, n);
100 return v;
104 static char rf_write__doc__[] =
105 "Write to resource fork"
108 static PyObject *
109 rf_write(self, args)
110 rfobject *self;
111 PyObject *args;
113 char *buffer;
114 long size;
115 OSErr err;
117 if (self->isclosed) {
118 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
119 return NULL;
121 if (!PyArg_ParseTuple(args, "s#", &buffer, &size))
122 return NULL;
123 err = FSWrite(self->fRefNum, &size, buffer);
124 if (err) {
125 PyMac_Error(err);
126 return NULL;
128 Py_INCREF(Py_None);
129 return Py_None;
133 static char rf_seek__doc__[] =
134 "Set file position"
137 static PyObject *
138 rf_seek(self, args)
139 rfobject *self;
140 PyObject *args;
142 long amount, pos;
143 int whence = SEEK_SET;
144 long eof;
145 OSErr err;
147 if (self->isclosed) {
148 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
149 return NULL;
151 if (!PyArg_ParseTuple(args, "l|i", &amount, &whence))
152 return NULL;
154 if ( err = GetEOF(self->fRefNum, &eof))
155 goto ioerr;
157 switch (whence) {
158 case SEEK_CUR:
159 if (err = GetFPos(self->fRefNum, &pos))
160 goto ioerr;
161 break;
162 case SEEK_END:
163 pos = eof;
164 break;
165 case SEEK_SET:
166 pos = 0;
167 break;
168 default:
169 PyErr_BadArgument();
170 return NULL;
173 pos += amount;
175 /* Don't bother implementing seek past EOF */
176 if (pos > eof || pos < 0) {
177 PyErr_BadArgument();
178 return NULL;
181 if ( err = SetFPos(self->fRefNum, fsFromStart, pos) ) {
182 ioerr:
183 PyMac_Error(err);
184 return NULL;
186 Py_INCREF(Py_None);
187 return Py_None;
191 static char rf_tell__doc__[] =
192 "Get file position"
195 static PyObject *
196 rf_tell(self, args)
197 rfobject *self;
198 PyObject *args;
200 long where;
201 OSErr err;
203 if (self->isclosed) {
204 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
205 return NULL;
207 if (!PyArg_ParseTuple(args, ""))
208 return NULL;
209 if ( err = GetFPos(self->fRefNum, &where) ) {
210 PyMac_Error(err);
211 return NULL;
213 return PyInt_FromLong(where);
216 static char rf_close__doc__[] =
217 "Close resource fork"
220 static PyObject *
221 rf_close(self, args)
222 rfobject *self;
223 PyObject *args;
225 if (!PyArg_ParseTuple(args, ""))
226 return NULL;
227 do_close(self);
228 Py_INCREF(Py_None);
229 return Py_None;
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 */
243 /* ---------- */
246 static rfobject *
247 newrfobject()
249 rfobject *self;
251 self = PyObject_NEW(rfobject, &Rftype);
252 if (self == NULL)
253 return NULL;
254 self->isclosed = 1;
255 return self;
259 static void
260 rf_dealloc(self)
261 rfobject *self;
263 do_close(self);
264 PyMem_DEL(self);
267 static PyObject *
268 rf_getattr(self, name)
269 rfobject *self;
270 char *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)
281 0, /*ob_size*/
282 "ResourceFork", /*tp_name*/
283 sizeof(rfobject), /*tp_basicsize*/
284 0, /*tp_itemsize*/
285 /* methods */
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*/
292 0, /*tp_as_number*/
293 0, /*tp_as_sequence*/
294 0, /*tp_as_mapping*/
295 (hashfunc)0, /*tp_hash*/
296 (ternaryfunc)0, /*tp_call*/
297 (reprfunc)0, /*tp_str*/
299 /* Space for future expansion */
300 0L,0L,0L,0L,
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";
312 static PyObject *
313 MacOS_GetCreatorAndType(PyObject *self, PyObject *args)
315 Str255 name;
316 FInfo info;
317 PyObject *creator, *type, *res;
318 OSErr err;
320 if (!PyArg_ParseTuple(args, "O&", PyMac_GetStr255, &name))
321 return NULL;
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);
327 Py_DECREF(creator);
328 Py_DECREF(type);
329 return res;
332 static char setcrtp_doc[] = "Obsolete, use macfs module";
334 static PyObject *
335 MacOS_SetCreatorAndType(PyObject *self, PyObject *args)
337 Str255 name;
338 ResType creator, type;
339 FInfo info;
340 OSErr err;
342 if (!PyArg_ParseTuple(args, "O&O&O&",
343 PyMac_GetStr255, &name, PyMac_GetOSType, &creator, PyMac_GetOSType, &type))
344 return NULL;
345 if ((err = GetFInfo(name, 0, &info)) != noErr)
346 return PyErr_Mac(MacOS_Error, err);
347 info.fdCreator = creator;
348 info.fdType = type;
349 if ((err = SetFInfo(name, 0, &info)) != noErr)
350 return PyErr_Mac(MacOS_Error, err);
351 Py_INCREF(Py_None);
352 return Py_None;
355 /*----------------------------------------------------------------------*/
356 /* STDWIN High Level Event interface */
358 #include <EPPC.h>
359 #include <Events.h>
361 #ifdef USE_STDWIN
363 extern void (*_w_high_level_event_proc)(EventRecord *);
365 static PyObject *MacOS_HighLevelEventHandler = NULL;
367 static void
368 MacOS_HighLevelEventProc(EventRecord *e)
370 if (MacOS_HighLevelEventHandler != NULL) {
371 PyObject *args = PyMac_BuildEventRecord(e);
372 PyObject *res;
373 if (args == NULL)
374 res = NULL;
375 else {
376 res = PyEval_CallObject(MacOS_HighLevelEventHandler, args);
377 Py_DECREF(args);
379 if (res == NULL) {
380 PySys_WriteStderr("Exception in MacOS_HighLevelEventProc:\n");
381 PyErr_Print();
383 else
384 Py_DECREF(res);
388 /* XXXX Need to come here from PyMac_DoYield too... */
390 static PyObject *
391 MacOS_SetHighLevelEventHandler(self, args)
392 PyObject *self;
393 PyObject *args;
395 PyObject *previous = MacOS_HighLevelEventHandler;
396 PyObject *next = NULL;
397 if (!PyArg_ParseTuple(args, "|O", &next))
398 return NULL;
399 if (next == Py_None)
400 next = NULL;
401 Py_INCREF(next);
402 MacOS_HighLevelEventHandler = next;
403 if (next == NULL)
404 _w_high_level_event_proc = NULL;
405 else
406 _w_high_level_event_proc = MacOS_HighLevelEventProc;
407 if (previous == NULL) {
408 Py_INCREF(Py_None);
409 previous = Py_None;
411 return previous;
414 #endif /* USE_STDWIN */
416 static char accepthle_doc[] = "Get arguments of pending high-level event";
418 static PyObject *
419 MacOS_AcceptHighLevelEvent(self, args)
420 PyObject *self;
421 PyObject *args;
423 TargetID sender;
424 unsigned long refcon;
425 Ptr buf;
426 unsigned long len;
427 OSErr err;
428 PyObject *res;
430 buf = NULL;
431 len = 0;
432 err = AcceptHighLevelEvent(&sender, &refcon, buf, &len);
433 if (err == bufferIsSmall) {
434 buf = malloc(len);
435 if (buf == NULL)
436 return PyErr_NoMemory();
437 err = AcceptHighLevelEvent(&sender, &refcon, buf, &len);
438 if (err != noErr) {
439 free(buf);
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);
447 free(buf);
448 return res;
451 static char schedparams_doc[] = "Set/return mainloop interrupt check flag, etc";
454 ** Set scheduler parameters
456 static PyObject *
457 MacOS_SchedParams(PyObject *self, PyObject *args)
459 PyMacSchedParams old, new;
461 PyMac_GetSchedParams(&old);
462 new = old;
463 if (!PyArg_ParseTuple(args, "|iiidd", &new.check_interrupt, &new.process_events,
464 &new.besocial, &new.check_interval, &new.bg_yield))
465 return NULL;
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 */
474 static PyObject *
475 MacOS_EnableAppswitch(PyObject *self, PyObject *args)
477 int new, old;
478 PyMacSchedParams schp;
480 if (!PyArg_ParseTuple(args, "i", &new))
481 return NULL;
482 PyMac_GetSchedParams(&schp);
483 if ( schp.process_events )
484 old = 1;
485 else if ( schp.check_interrupt )
486 old = 0;
487 else
488 old = -1;
489 if ( new > 0 ) {
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;
495 } else {
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";
505 static PyObject *
506 MacOS_SetEventHandler(self, args)
507 PyObject *self;
508 PyObject *args;
510 PyObject *evh = NULL;
512 if (!PyArg_ParseTuple(args, "|O", &evh))
513 return NULL;
514 if (evh == Py_None)
515 evh = NULL;
516 if ( evh && !PyCallable_Check(evh) ) {
517 PyErr_SetString(PyExc_ValueError, "SetEventHandler argument must be callable");
518 return NULL;
520 if ( !PyMac_SetEventHandler(evh) )
521 return NULL;
522 Py_INCREF(Py_None);
523 return Py_None;
526 static char handleev_doc[] = "Pass event to other interested parties like sioux";
528 static PyObject *
529 MacOS_HandleEvent(PyObject *self, PyObject *args)
531 EventRecord ev;
533 if (!PyArg_ParseTuple(args, "O&", PyMac_GetEventRecord, &ev))
534 return NULL;
535 PyMac_HandleEventIntern(&ev);
536 Py_INCREF(Py_None);
537 return Py_None;
540 static char geterr_doc[] = "Convert OSErr number to string";
542 static PyObject *
543 MacOS_GetErrorString(PyObject *self, PyObject *args)
545 int errn;
547 if (!PyArg_ParseTuple(args, "i", &errn))
548 return NULL;
549 return Py_BuildValue("s", PyMac_StrError(errn));
552 static char splash_doc[] = "Open a splash-screen dialog by resource-id (0=close)";
554 static PyObject *
555 MacOS_splash(PyObject *self, PyObject *args)
557 int resid = -1;
558 static DialogPtr curdialog = NULL;
559 DialogPtr olddialog;
560 WindowRef theWindow;
561 CGrafPtr thePort;
562 short xpos, ypos, width, height, swidth, sheight;
564 if (!PyArg_ParseTuple(args, "|i", &resid))
565 return NULL;
566 olddialog = curdialog;
567 curdialog = NULL;
569 if ( resid != -1 ) {
570 curdialog = GetNewDialog(resid, NULL, (WindowPtr)-1);
571 if ( curdialog ) {
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);
585 if (olddialog)
586 DisposeDialog(olddialog);
587 Py_INCREF(Py_None);
588 return Py_None;
591 static char DebugStr_doc[] = "Switch to low-level debugger with a message";
593 static PyObject *
594 MacOS_DebugStr(PyObject *self, PyObject *args)
596 Str255 message;
597 PyObject *object = 0;
599 if (!PyArg_ParseTuple(args, "O&|O", PyMac_GetStr255, message, &object))
600 return NULL;
601 DebugStr(message);
602 Py_INCREF(Py_None);
603 return Py_None;
606 static char SysBeep_doc[] = "BEEEEEP!!!";
608 static PyObject *
609 MacOS_SysBeep(PyObject *self, PyObject *args)
611 int duration = 6;
613 if (!PyArg_ParseTuple(args, "|i", &duration))
614 return NULL;
615 SysBeep(duration);
616 Py_INCREF(Py_None);
617 return Py_None;
620 static char GetTicks_doc[] = "Return number of ticks since bootup";
622 static PyObject *
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";
630 static PyObject *
631 MacOS_openrf(PyObject *self, PyObject *args)
633 OSErr err;
634 char *mode = "r";
635 FSSpec fss;
636 SignedByte permission = 1;
637 rfobject *fp;
639 if (!PyArg_ParseTuple(args, "O&|s", PyMac_GetFSSpec, &fss, &mode))
640 return NULL;
641 while (*mode) {
642 switch (*mode++) {
643 case '*': break;
644 case 'r': permission = 1; break;
645 case 'w': permission = 2; break;
646 case 'b': break;
647 default:
648 PyErr_BadArgument();
649 return NULL;
653 if ( (fp = newrfobject()) == NULL )
654 return 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
662 FILE *tfp;
663 char pathname[257];
665 if ( err=PyMac_GetFullPath(&fss, pathname) ) {
666 PyMac_Error(err);
667 Py_DECREF(fp);
668 return NULL;
671 if ( (tfp = fopen(pathname, "w")) == NULL ) {
672 PyMac_Error(fnfErr); /* What else... */
673 Py_DECREF(fp);
674 return NULL;
676 fclose(tfp);
677 err = HOpenRF(fss.vRefNum, fss.parID, fss.name, permission, &fp->fRefNum);
679 if ( err ) {
680 Py_DECREF(fp);
681 PyMac_Error(err);
682 return NULL;
684 fp->isclosed = 0;
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},
692 #ifdef USE_STDWIN
693 {"SetHighLevelEventHandler", MacOS_SetHighLevelEventHandler, 1},
694 #endif
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 */
709 void
710 initMacOS()
712 PyObject *m, *d;
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;
722 Py_INCREF(&Rftype);
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");