AddressList.__str__(): Get rid of useless, and broken method. Closes
[python/dscho.git] / Mac / Modules / macosmodule.c
blob6790418b9619758997ce9e98d00472d43b8e5c4c
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"
29 #include "pythonresources.h"
31 #ifdef WITHOUT_FRAMEWORKS
32 #include <Windows.h>
33 #include <Files.h>
34 #include <LowMem.h>
35 #include <Sound.h>
36 #include <Events.h>
37 #else
38 #include <Carbon/Carbon.h>
39 #include <ApplicationServices/ApplicationServices.h>
40 #endif
42 static PyObject *MacOS_Error; /* Exception MacOS.Error */
44 #ifdef TARGET_API_MAC_OSX
45 #define PATHNAMELEN 1024
46 #else
47 #define PATHNAMELEN 256
48 #endif
50 #ifdef MPW
51 #define bufferIsSmall -607 /*error returns from Post and Accept */
52 #endif
54 /* ----------------------------------------------------- */
56 /* Declarations for objects of type Resource fork */
58 typedef struct {
59 PyObject_HEAD
60 short fRefNum;
61 int isclosed;
62 } rfobject;
64 static PyTypeObject Rftype;
68 /* ---------------------------------------------------------------- */
70 static void
71 do_close(rfobject *self)
73 if (self->isclosed ) return;
74 (void)FSClose(self->fRefNum);
75 self->isclosed = 1;
78 static char rf_read__doc__[] =
79 "Read data from resource fork"
82 static PyObject *
83 rf_read(rfobject *self, PyObject *args)
85 long n;
86 PyObject *v;
87 OSErr err;
89 if (self->isclosed) {
90 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
91 return NULL;
94 if (!PyArg_ParseTuple(args, "l", &n))
95 return NULL;
97 v = PyString_FromStringAndSize((char *)NULL, n);
98 if (v == NULL)
99 return NULL;
101 err = FSRead(self->fRefNum, &n, PyString_AsString(v));
102 if (err && err != eofErr) {
103 PyMac_Error(err);
104 Py_DECREF(v);
105 return NULL;
107 _PyString_Resize(&v, n);
108 return v;
112 static char rf_write__doc__[] =
113 "Write to resource fork"
116 static PyObject *
117 rf_write(rfobject *self, PyObject *args)
119 char *buffer;
120 long size;
121 OSErr err;
123 if (self->isclosed) {
124 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
125 return NULL;
127 if (!PyArg_ParseTuple(args, "s#", &buffer, &size))
128 return NULL;
129 err = FSWrite(self->fRefNum, &size, buffer);
130 if (err) {
131 PyMac_Error(err);
132 return NULL;
134 Py_INCREF(Py_None);
135 return Py_None;
139 static char rf_seek__doc__[] =
140 "Set file position"
143 static PyObject *
144 rf_seek(rfobject *self, PyObject *args)
146 long amount, pos;
147 int whence = SEEK_SET;
148 long eof;
149 OSErr err;
151 if (self->isclosed) {
152 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
153 return NULL;
155 if (!PyArg_ParseTuple(args, "l|i", &amount, &whence))
156 return NULL;
158 if ((err = GetEOF(self->fRefNum, &eof)))
159 goto ioerr;
161 switch (whence) {
162 case SEEK_CUR:
163 if ((err = GetFPos(self->fRefNum, &pos)))
164 goto ioerr;
165 break;
166 case SEEK_END:
167 pos = eof;
168 break;
169 case SEEK_SET:
170 pos = 0;
171 break;
172 default:
173 PyErr_BadArgument();
174 return NULL;
177 pos += amount;
179 /* Don't bother implementing seek past EOF */
180 if (pos > eof || pos < 0) {
181 PyErr_BadArgument();
182 return NULL;
185 if ((err = SetFPos(self->fRefNum, fsFromStart, pos)) ) {
186 ioerr:
187 PyMac_Error(err);
188 return NULL;
190 Py_INCREF(Py_None);
191 return Py_None;
195 static char rf_tell__doc__[] =
196 "Get file position"
199 static PyObject *
200 rf_tell(rfobject *self, PyObject *args)
202 long where;
203 OSErr err;
205 if (self->isclosed) {
206 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
207 return NULL;
209 if (!PyArg_ParseTuple(args, ""))
210 return NULL;
211 if ((err = GetFPos(self->fRefNum, &where)) ) {
212 PyMac_Error(err);
213 return NULL;
215 return PyInt_FromLong(where);
218 static char rf_close__doc__[] =
219 "Close resource fork"
222 static PyObject *
223 rf_close(rfobject *self, 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", (PyCFunction)rf_read, 1, rf_read__doc__},
235 {"write", (PyCFunction)rf_write, 1, rf_write__doc__},
236 {"seek", (PyCFunction)rf_seek, 1, rf_seek__doc__},
237 {"tell", (PyCFunction)rf_tell, 1, rf_tell__doc__},
238 {"close", (PyCFunction)rf_close, 1, rf_close__doc__},
240 {NULL, NULL} /* sentinel */
243 /* ---------- */
246 static rfobject *
247 newrfobject(void)
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(rfobject *self)
262 do_close(self);
263 PyObject_DEL(self);
266 static PyObject *
267 rf_getattr(rfobject *self, char *name)
269 return Py_FindMethod(rf_methods, (PyObject *)self, name);
272 static char Rftype__doc__[] =
273 "Resource fork file object"
276 static PyTypeObject Rftype = {
277 PyObject_HEAD_INIT(&PyType_Type)
278 0, /*ob_size*/
279 "MacOS.ResourceFork", /*tp_name*/
280 sizeof(rfobject), /*tp_basicsize*/
281 0, /*tp_itemsize*/
282 /* methods */
283 (destructor)rf_dealloc, /*tp_dealloc*/
284 (printfunc)0, /*tp_print*/
285 (getattrfunc)rf_getattr, /*tp_getattr*/
286 (setattrfunc)0, /*tp_setattr*/
287 (cmpfunc)0, /*tp_compare*/
288 (reprfunc)0, /*tp_repr*/
289 0, /*tp_as_number*/
290 0, /*tp_as_sequence*/
291 0, /*tp_as_mapping*/
292 (hashfunc)0, /*tp_hash*/
293 (ternaryfunc)0, /*tp_call*/
294 (reprfunc)0, /*tp_str*/
296 /* Space for future expansion */
297 0L,0L,0L,0L,
298 Rftype__doc__ /* Documentation string */
301 /* End of code for Resource fork objects */
302 /* -------------------------------------------------------- */
304 /*----------------------------------------------------------------------*/
305 /* Miscellaneous File System Operations */
307 static char getcrtp_doc[] = "Get MacOS 4-char creator and type for a file";
309 static PyObject *
310 MacOS_GetCreatorAndType(PyObject *self, PyObject *args)
312 FSSpec fss;
313 FInfo info;
314 PyObject *creator, *type, *res;
315 OSErr err;
317 if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSSpec, &fss))
318 return NULL;
319 if ((err = FSpGetFInfo(&fss, &info)) != noErr)
320 return PyErr_Mac(MacOS_Error, err);
321 creator = PyString_FromStringAndSize((char *)&info.fdCreator, 4);
322 type = PyString_FromStringAndSize((char *)&info.fdType, 4);
323 res = Py_BuildValue("OO", creator, type);
324 Py_DECREF(creator);
325 Py_DECREF(type);
326 return res;
329 static char setcrtp_doc[] = "Set MacOS 4-char creator and type for a file";
331 static PyObject *
332 MacOS_SetCreatorAndType(PyObject *self, PyObject *args)
334 FSSpec fss;
335 ResType creator, type;
336 FInfo info;
337 OSErr err;
339 if (!PyArg_ParseTuple(args, "O&O&O&",
340 PyMac_GetFSSpec, &fss, PyMac_GetOSType, &creator, PyMac_GetOSType, &type))
341 return NULL;
342 if ((err = FSpGetFInfo(&fss, &info)) != noErr)
343 return PyErr_Mac(MacOS_Error, err);
344 info.fdCreator = creator;
345 info.fdType = type;
346 if ((err = FSpSetFInfo(&fss, &info)) != noErr)
347 return PyErr_Mac(MacOS_Error, err);
348 Py_INCREF(Py_None);
349 return Py_None;
352 #if !TARGET_API_MAC_OSX
353 static char schedparams_doc[] = "Set/return mainloop interrupt check flag, etc";
356 ** Set scheduler parameters
358 static PyObject *
359 MacOS_SchedParams(PyObject *self, PyObject *args)
361 PyMacSchedParams old, new;
363 PyMac_GetSchedParams(&old);
364 new = old;
365 if (!PyArg_ParseTuple(args, "|iiidd", &new.check_interrupt, &new.process_events,
366 &new.besocial, &new.check_interval, &new.bg_yield))
367 return NULL;
368 PyMac_SetSchedParams(&new);
369 return Py_BuildValue("iiidd", old.check_interrupt, old.process_events,
370 old.besocial, old.check_interval, old.bg_yield);
373 static char appswitch_doc[] = "Obsolete, use SchedParams";
375 /* Obsolete, for backward compatability */
376 static PyObject *
377 MacOS_EnableAppswitch(PyObject *self, PyObject *args)
379 int new, old;
380 PyMacSchedParams schp;
382 if (!PyArg_ParseTuple(args, "i", &new))
383 return NULL;
384 PyMac_GetSchedParams(&schp);
385 if ( schp.process_events )
386 old = 1;
387 else if ( schp.check_interrupt )
388 old = 0;
389 else
390 old = -1;
391 if ( new > 0 ) {
392 schp.process_events = mDownMask|keyDownMask|osMask;
393 schp.check_interrupt = 1;
394 } else if ( new == 0 ) {
395 schp.process_events = 0;
396 schp.check_interrupt = 1;
397 } else {
398 schp.process_events = 0;
399 schp.check_interrupt = 0;
401 PyMac_SetSchedParams(&schp);
402 return Py_BuildValue("i", old);
405 static char setevh_doc[] = "Set python event handler to be called in mainloop";
407 static PyObject *
408 MacOS_SetEventHandler(PyObject *self, PyObject *args)
410 PyObject *evh = NULL;
412 if (!PyArg_ParseTuple(args, "|O", &evh))
413 return NULL;
414 if (evh == Py_None)
415 evh = NULL;
416 if ( evh && !PyCallable_Check(evh) ) {
417 PyErr_SetString(PyExc_ValueError, "SetEventHandler argument must be callable");
418 return NULL;
420 if ( !PyMac_SetEventHandler(evh) )
421 return NULL;
422 Py_INCREF(Py_None);
423 return Py_None;
426 static char handleev_doc[] = "Pass event to other interested parties like sioux";
428 static PyObject *
429 MacOS_HandleEvent(PyObject *self, PyObject *args)
431 EventRecord ev;
433 if (!PyArg_ParseTuple(args, "O&", PyMac_GetEventRecord, &ev))
434 return NULL;
435 PyMac_HandleEventIntern(&ev);
436 Py_INCREF(Py_None);
437 return Py_None;
439 #endif /* !TARGET_API_MAC_OSX */
441 static char geterr_doc[] = "Convert OSErr number to string";
443 static PyObject *
444 MacOS_GetErrorString(PyObject *self, PyObject *args)
446 int errn;
448 if (!PyArg_ParseTuple(args, "i", &errn))
449 return NULL;
450 return Py_BuildValue("s", PyMac_StrError(errn));
453 static char splash_doc[] = "Open a splash-screen dialog by resource-id (0=close)";
455 static PyObject *
456 MacOS_splash(PyObject *self, PyObject *args)
458 int resid = -1;
459 static DialogPtr curdialog = NULL;
460 DialogPtr olddialog;
461 WindowRef theWindow;
462 CGrafPtr thePort;
463 #if 0
464 short xpos, ypos, width, height, swidth, sheight;
465 #endif
467 if (!PyArg_ParseTuple(args, "|i", &resid))
468 return NULL;
469 olddialog = curdialog;
470 curdialog = NULL;
472 if ( resid != -1 ) {
473 curdialog = GetNewDialog(resid, NULL, (WindowPtr)-1);
474 if ( curdialog ) {
475 theWindow = GetDialogWindow(curdialog);
476 thePort = GetWindowPort(theWindow);
477 #if 0
478 width = thePort->portRect.right - thePort->portRect.left;
479 height = thePort->portRect.bottom - thePort->portRect.top;
480 swidth = qd.screenBits.bounds.right - qd.screenBits.bounds.left;
481 sheight = qd.screenBits.bounds.bottom - qd.screenBits.bounds.top - LMGetMBarHeight();
482 xpos = (swidth-width)/2;
483 ypos = (sheight-height)/5 + LMGetMBarHeight();
484 MoveWindow(theWindow, xpos, ypos, 0);
485 ShowWindow(theWindow);
486 #endif
487 DrawDialog(curdialog);
490 if (olddialog)
491 DisposeDialog(olddialog);
492 Py_INCREF(Py_None);
493 return Py_None;
496 static char DebugStr_doc[] = "Switch to low-level debugger with a message";
498 static PyObject *
499 MacOS_DebugStr(PyObject *self, PyObject *args)
501 Str255 message;
502 PyObject *object = 0;
504 if (!PyArg_ParseTuple(args, "O&|O", PyMac_GetStr255, message, &object))
505 return NULL;
506 DebugStr(message);
507 Py_INCREF(Py_None);
508 return Py_None;
511 static char SysBeep_doc[] = "BEEEEEP!!!";
513 static PyObject *
514 MacOS_SysBeep(PyObject *self, PyObject *args)
516 int duration = 6;
518 if (!PyArg_ParseTuple(args, "|i", &duration))
519 return NULL;
520 SysBeep(duration);
521 Py_INCREF(Py_None);
522 return Py_None;
525 static char WMAvailable_doc[] =
526 "True if this process can interact with the display."
527 "Will foreground the application on the first call as a side-effect."
530 static PyObject *
531 MacOS_WMAvailable(PyObject *self, PyObject *args)
533 static PyObject *rv = NULL;
535 if (!PyArg_ParseTuple(args, ""))
536 return NULL;
537 if (!rv) {
538 #if TARGET_API_MAC_OSX
539 ProcessSerialNumber psn;
542 ** This is a fairly innocuous call to make if we don't have a window
543 ** manager, or if we have no permission to talk to it. It will print
544 ** a message on stderr, but at least it won't abort the process.
545 ** It appears the function caches the result itself, and it's cheap, so
546 ** no need for us to cache.
548 if (CGMainDisplayID() == 0) {
549 rv = Py_False;
550 } else {
551 if (GetCurrentProcess(&psn) < 0 ||
552 SetFrontProcess(&psn) < 0) {
553 rv = Py_False;
554 } else {
555 rv = Py_True;
558 #else
559 rv = Py_True;
560 #endif
562 Py_INCREF(rv);
563 return rv;
566 static char GetTicks_doc[] = "Return number of ticks since bootup";
568 static PyObject *
569 MacOS_GetTicks(PyObject *self, PyObject *args)
571 return Py_BuildValue("i", (int)TickCount());
574 static char openrf_doc[] = "Open resource fork of a file";
576 static PyObject *
577 MacOS_openrf(PyObject *self, PyObject *args)
579 OSErr err;
580 char *mode = "r";
581 FSSpec fss;
582 SignedByte permission = 1;
583 rfobject *fp;
585 if (!PyArg_ParseTuple(args, "O&|s", PyMac_GetFSSpec, &fss, &mode))
586 return NULL;
587 while (*mode) {
588 switch (*mode++) {
589 case '*': break;
590 case 'r': permission = 1; break;
591 case 'w': permission = 2; break;
592 case 'b': break;
593 default:
594 PyErr_BadArgument();
595 return NULL;
599 if ( (fp = newrfobject()) == NULL )
600 return NULL;
602 err = HOpenRF(fss.vRefNum, fss.parID, fss.name, permission, &fp->fRefNum);
604 if ( err == fnfErr ) {
605 /* In stead of doing complicated things here to get creator/type
606 ** correct we let the standard i/o library handle it
608 FILE *tfp;
609 char pathname[PATHNAMELEN];
611 if ( (err=PyMac_GetFullPathname(&fss, pathname, PATHNAMELEN)) ) {
612 PyMac_Error(err);
613 Py_DECREF(fp);
614 return NULL;
617 if ( (tfp = fopen(pathname, "w")) == NULL ) {
618 PyMac_Error(fnfErr); /* What else... */
619 Py_DECREF(fp);
620 return NULL;
622 fclose(tfp);
623 err = HOpenRF(fss.vRefNum, fss.parID, fss.name, permission, &fp->fRefNum);
625 if ( err ) {
626 Py_DECREF(fp);
627 PyMac_Error(err);
628 return NULL;
630 fp->isclosed = 0;
631 return (PyObject *)fp;
634 #if !TARGET_API_MAC_OSX
635 static char FreeMem_doc[] = "Return the total amount of free space in the heap";
637 static PyObject *
638 MacOS_FreeMem(PyObject *self, PyObject *args)
640 long rv;
642 if (!PyArg_ParseTuple(args, ""))
643 return NULL;
644 rv = FreeMem();
645 return Py_BuildValue("l", rv);
648 static char MaxBlock_doc[] = "Return the largest contiguous block of free space in the heap";
650 static PyObject *
651 MacOS_MaxBlock(PyObject *self, PyObject *args)
653 long rv;
655 if (!PyArg_ParseTuple(args, ""))
656 return NULL;
657 rv = MaxBlock();
658 return Py_BuildValue("l", rv);
661 static char CompactMem_doc[] = "(wanted size)->actual largest block after compacting";
663 static PyObject *
664 MacOS_CompactMem(PyObject *self, PyObject *args)
666 long value;
667 long rv;
669 if (!PyArg_ParseTuple(args, "l", &value))
670 return NULL;
671 rv = CompactMem(value);
672 return Py_BuildValue("l", rv);
675 static char KeepConsole_doc[] = "(flag) Keep console open 0:never, 1:on output 2:on error, 3:always";
677 static PyObject *
678 MacOS_KeepConsole(PyObject *self, PyObject *args)
680 int value;
682 if (!PyArg_ParseTuple(args, "i", &value))
683 return NULL;
684 PyMac_options.keep_console = value;
685 Py_INCREF(Py_None);
686 return Py_None;
689 static char OutputSeen_doc[] = "Call to reset the 'unseen output' flag for the keep-console-open option";
691 static PyObject *
692 MacOS_OutputSeen(PyObject *self, PyObject *args)
694 if (!PyArg_ParseTuple(args, ""))
695 return NULL;
696 PyMac_OutputSeen();
697 Py_INCREF(Py_None);
698 return Py_None;
700 #endif /* !TARGET_API_MAC_OSX */
702 static PyMethodDef MacOS_Methods[] = {
703 {"GetCreatorAndType", MacOS_GetCreatorAndType, 1, getcrtp_doc},
704 {"SetCreatorAndType", MacOS_SetCreatorAndType, 1, setcrtp_doc},
705 #if !TARGET_API_MAC_OSX
706 {"SchedParams", MacOS_SchedParams, 1, schedparams_doc},
707 {"EnableAppswitch", MacOS_EnableAppswitch, 1, appswitch_doc},
708 {"SetEventHandler", MacOS_SetEventHandler, 1, setevh_doc},
709 {"HandleEvent", MacOS_HandleEvent, 1, handleev_doc},
710 #endif
711 {"GetErrorString", MacOS_GetErrorString, 1, geterr_doc},
712 {"openrf", MacOS_openrf, 1, openrf_doc},
713 {"splash", MacOS_splash, 1, splash_doc},
714 {"DebugStr", MacOS_DebugStr, 1, DebugStr_doc},
715 {"GetTicks", MacOS_GetTicks, 1, GetTicks_doc},
716 {"SysBeep", MacOS_SysBeep, 1, SysBeep_doc},
717 {"WMAvailable", MacOS_WMAvailable, 1, WMAvailable_doc},
718 #if !TARGET_API_MAC_OSX
719 {"FreeMem", MacOS_FreeMem, 1, FreeMem_doc},
720 {"MaxBlock", MacOS_MaxBlock, 1, MaxBlock_doc},
721 {"CompactMem", MacOS_CompactMem, 1, CompactMem_doc},
722 {"KeepConsole", MacOS_KeepConsole, 1, KeepConsole_doc},
723 {"OutputSeen", MacOS_OutputSeen, 1, OutputSeen_doc},
724 #endif
725 {NULL, NULL} /* Sentinel */
729 void
730 initMacOS(void)
732 PyObject *m, *d;
734 m = Py_InitModule("MacOS", MacOS_Methods);
735 d = PyModule_GetDict(m);
737 /* Initialize MacOS.Error exception */
738 MacOS_Error = PyMac_GetOSErrException();
739 if (MacOS_Error == NULL || PyDict_SetItemString(d, "Error", MacOS_Error) != 0)
740 return;
741 Rftype.ob_type = &PyType_Type;
742 Py_INCREF(&Rftype);
743 if (PyDict_SetItemString(d, "ResourceForkType", (PyObject *)&Rftype) != 0)
744 return;
746 ** This is a hack: the following constant added to the id() of a string
747 ** object gives you the address of the data. Unfortunately, it is needed for
748 ** some of the image and sound processing interfaces on the mac:-(
751 PyStringObject *p = 0;
752 long off = (long)&(p->ob_sval[0]);
754 if( PyDict_SetItemString(d, "string_id_to_buffer", Py_BuildValue("i", off)) != 0)
755 return;
757 #if TARGET_API_MAC_OSX
758 #define PY_RUNTIMEMODEL "macho"
759 #elif TARGET_API_MAC_CARBON
760 #define PY_RUNTIMEMODEL "carbon"
761 #else
762 #error "None of the TARGET_API_MAC_XXX I know about is set"
763 #endif
764 if (PyDict_SetItemString(d, "runtimemodel",
765 Py_BuildValue("s", PY_RUNTIMEMODEL)) != 0)
766 return;
767 #if !TARGET_API_MAC_OSX
768 #define PY_LINKMODEL "cfm"
769 #elif defined(WITH_NEXT_FRAMEWORK)
770 #define PY_LINKMODEL "framework"
771 #elif defined(Py_ENABLE_SHARED)
772 #define PY_LINKMODEL "shared"
773 #else
774 #define PY_LINKMODEL "static"
775 #endif
776 if (PyDict_SetItemString(d, "linkmodel",
777 Py_BuildValue("s", PY_LINKMODEL)) != 0)
778 return;