Home | History | Annotate | Download | only in Modules
      1 /***********************************************************
      2 Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
      3 The Netherlands.
      4 
      5                         All Rights Reserved
      6 
      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.
     14 
     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.
     22 
     23 ******************************************************************/
     24 
     25 /* Macintosh OS-specific interface */
     26 
     27 #include "Python.h"
     28 #include "pymactoolbox.h"
     29 
     30 #include <Carbon/Carbon.h>
     31 #include <ApplicationServices/ApplicationServices.h>
     32 
     33 #include <arpa/inet.h>  /* for ntohl, htonl */
     34 
     35 
     36 #ifndef HAVE_OSX105_SDK
     37 typedef SInt16  FSIORefNum;
     38 #endif
     39 
     40 static PyObject *MacOS_Error; /* Exception MacOS.Error */
     41 
     42 #define PATHNAMELEN 1024
     43 
     44 /* ----------------------------------------------------- */
     45 
     46 /* Declarations for objects of type Resource fork */
     47 
     48 typedef struct {
     49     PyObject_HEAD
     50     FSIORefNum fRefNum;
     51     int isclosed;
     52 } rfobject;
     53 
     54 static PyTypeObject Rftype;
     55 
     56 
     57 
     58 /* ---------------------------------------------------------------- */
     59 
     60 static void
     61 do_close(rfobject *self)
     62 {
     63     if (self->isclosed ) return;
     64     (void)FSCloseFork(self->fRefNum);
     65     self->isclosed = 1;
     66 }
     67 
     68 static char rf_read__doc__[] =
     69 "Read data from resource fork"
     70 ;
     71 
     72 static PyObject *
     73 rf_read(rfobject *self, PyObject *args)
     74 {
     75     long n;
     76     PyObject *v;
     77     OSErr err;
     78     ByteCount n2;
     79 
     80     if (self->isclosed) {
     81         PyErr_SetString(PyExc_ValueError, "Operation on closed file");
     82         return NULL;
     83     }
     84 
     85     if (!PyArg_ParseTuple(args, "l", &n))
     86         return NULL;
     87 
     88     v = PyBytes_FromStringAndSize((char *)NULL, n);
     89     if (v == NULL)
     90         return NULL;
     91 
     92     err = FSReadFork(self->fRefNum, fsAtMark, 0, n, PyString_AsString(v), &n2);
     93     if (err && err != eofErr) {
     94         PyMac_Error(err);
     95         Py_DECREF(v);
     96         return NULL;
     97     }
     98     _PyString_Resize(&v, n2);
     99     return v;
    100 }
    101 
    102 
    103 static char rf_write__doc__[] =
    104 "Write to resource fork"
    105 ;
    106 
    107 static PyObject *
    108 rf_write(rfobject *self, PyObject *args)
    109 {
    110     char *buffer;
    111     long size;
    112     OSErr err;
    113 
    114     if (self->isclosed) {
    115         PyErr_SetString(PyExc_ValueError, "Operation on closed file");
    116         return NULL;
    117     }
    118     if (!PyArg_ParseTuple(args, "s#", &buffer, &size))
    119         return NULL;
    120     err = FSWriteFork(self->fRefNum, fsAtMark, 0, size, buffer, NULL);
    121     if (err) {
    122         PyMac_Error(err);
    123         return NULL;
    124     }
    125     Py_INCREF(Py_None);
    126     return Py_None;
    127 }
    128 
    129 
    130 static char rf_seek__doc__[] =
    131 "Set file position"
    132 ;
    133 
    134 static PyObject *
    135 rf_seek(rfobject *self, PyObject *args)
    136 {
    137     long amount;
    138     int whence = SEEK_SET;
    139     int mode;
    140     OSErr err;
    141 
    142     if (self->isclosed) {
    143         PyErr_SetString(PyExc_ValueError, "Operation on closed file");
    144         return NULL;
    145     }
    146     if (!PyArg_ParseTuple(args, "l|i", &amount, &whence)) {
    147         return NULL;
    148     }
    149 
    150     switch (whence) {
    151     case SEEK_CUR:
    152         mode = fsFromMark;
    153         break;
    154     case SEEK_END:
    155         mode = fsFromLEOF;
    156         break;
    157     case SEEK_SET:
    158         mode = fsFromStart;
    159         break;
    160     default:
    161         PyErr_BadArgument();
    162         return NULL;
    163     }
    164 
    165     err = FSSetForkPosition(self->fRefNum, mode, amount);
    166     if (err != noErr) {
    167         PyMac_Error(err);
    168         return NULL;
    169     }
    170     Py_INCREF(Py_None);
    171     return Py_None;
    172 }
    173 
    174 
    175 static char rf_tell__doc__[] =
    176 "Get file position"
    177 ;
    178 
    179 static PyObject *
    180 rf_tell(rfobject *self, PyObject *args)
    181 {
    182     long long where;
    183     OSErr err;
    184 
    185     if (self->isclosed) {
    186         PyErr_SetString(PyExc_ValueError, "Operation on closed file");
    187         return NULL;
    188     }
    189     if (!PyArg_ParseTuple(args, ""))
    190         return NULL;
    191 
    192     err = FSGetForkPosition(self->fRefNum, &where);
    193     if (err != noErr) {
    194         PyMac_Error(err);
    195         return NULL;
    196     }
    197     return PyLong_FromLongLong(where);
    198 }
    199 
    200 static char rf_close__doc__[] =
    201 "Close resource fork"
    202 ;
    203 
    204 static PyObject *
    205 rf_close(rfobject *self, PyObject *args)
    206 {
    207     if (!PyArg_ParseTuple(args, ""))
    208         return NULL;
    209     do_close(self);
    210     Py_INCREF(Py_None);
    211     return Py_None;
    212 }
    213 
    214 
    215 static struct PyMethodDef rf_methods[] = {
    216  {"read",       (PyCFunction)rf_read,   1,      rf_read__doc__},
    217  {"write",      (PyCFunction)rf_write,  1,      rf_write__doc__},
    218  {"seek",       (PyCFunction)rf_seek,   1,      rf_seek__doc__},
    219  {"tell",       (PyCFunction)rf_tell,   1,      rf_tell__doc__},
    220  {"close",      (PyCFunction)rf_close,  1,      rf_close__doc__},
    221 
    222     {NULL,              NULL}           /* sentinel */
    223 };
    224 
    225 /* ---------- */
    226 
    227 
    228 static rfobject *
    229 newrfobject(void)
    230 {
    231     rfobject *self;
    232 
    233     self = PyObject_NEW(rfobject, &Rftype);
    234     if (self == NULL)
    235         return NULL;
    236     self->isclosed = 1;
    237     return self;
    238 }
    239 
    240 
    241 static void
    242 rf_dealloc(rfobject *self)
    243 {
    244     do_close(self);
    245     PyObject_DEL(self);
    246 }
    247 
    248 static PyObject *
    249 rf_getattr(rfobject *self, char *name)
    250 {
    251     return Py_FindMethod(rf_methods, (PyObject *)self, name);
    252 }
    253 
    254 static char Rftype__doc__[] =
    255 "Resource fork file object"
    256 ;
    257 
    258 static PyTypeObject Rftype = {
    259     PyObject_HEAD_INIT(&PyType_Type)
    260     0,                                  /*ob_size*/
    261     "MacOS.ResourceFork",               /*tp_name*/
    262     sizeof(rfobject),                   /*tp_basicsize*/
    263     0,                                  /*tp_itemsize*/
    264     /* methods */
    265     (destructor)rf_dealloc,     /*tp_dealloc*/
    266     (printfunc)0,               /*tp_print*/
    267     (getattrfunc)rf_getattr,            /*tp_getattr*/
    268     (setattrfunc)0,     /*tp_setattr*/
    269     (cmpfunc)0,                 /*tp_compare*/
    270     (reprfunc)0,                /*tp_repr*/
    271     0,                          /*tp_as_number*/
    272     0,                  /*tp_as_sequence*/
    273     0,                  /*tp_as_mapping*/
    274     (hashfunc)0,                /*tp_hash*/
    275     (ternaryfunc)0,             /*tp_call*/
    276     (reprfunc)0,                /*tp_str*/
    277 
    278     /* Space for future expansion */
    279     0L,0L,0L,0L,
    280     Rftype__doc__ /* Documentation string */
    281 };
    282 
    283 
    284 /* End of code for Resource fork objects */
    285 /* -------------------------------------------------------- */
    286 
    287 /*----------------------------------------------------------------------*/
    288 /* Miscellaneous File System Operations */
    289 
    290 static char getcrtp_doc[] = "Get MacOS 4-char creator and type for a file";
    291 
    292 static PyObject *
    293 MacOS_GetCreatorAndType(PyObject *self, PyObject *args)
    294 {
    295     PyObject *creator, *type, *res;
    296     OSErr err;
    297     FSRef ref;
    298     FSCatalogInfo       cataloginfo;
    299     FileInfo* finfo;
    300 
    301     if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSRef, &ref)) {
    302 #if APPLE_SUPPORTS_QUICKTIME
    303         /* This function is documented to take an FSSpec as well,
    304          * which only works in 32-bit mode.
    305          */
    306         PyErr_Clear();
    307         FSSpec fss;
    308         FInfo info;
    309 
    310         if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSSpec, &fss))
    311             return NULL;
    312 
    313         if ((err = FSpGetFInfo(&fss, &info)) != noErr) {
    314             return PyErr_Mac(MacOS_Error, err);
    315         }
    316 
    317         info.fdCreator = ntohl(info.fdCreator);
    318         info.fdType = ntohl(info.fdType);
    319 
    320         creator = PyString_FromStringAndSize(
    321                         (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;
    327 #else   /* APPLE_SUPPORTS_QUICKTIME */
    328         return NULL;
    329 #endif  /* APPLE_SUPPORTS_QUICKTIME */
    330     }
    331 
    332     err = FSGetCatalogInfo(&ref,
    333                     kFSCatInfoFinderInfo|kFSCatInfoNodeFlags, &cataloginfo,
    334                     NULL, NULL, NULL);
    335     if (err != noErr) {
    336         PyErr_Mac(MacOS_Error, err);
    337         return NULL;
    338     }
    339 
    340     if ((cataloginfo.nodeFlags & kFSNodeIsDirectoryMask) != 0) {
    341         /* Directory: doesn't have type/creator info.
    342          *
    343          * The specific error code is for backward compatibility with
    344          * earlier versions.
    345          */
    346         PyErr_Mac(MacOS_Error, fnfErr);
    347         return NULL;
    348 
    349     }
    350     finfo = (FileInfo*)&(cataloginfo.finderInfo);
    351     finfo->fileCreator = ntohl(finfo->fileCreator);
    352     finfo->fileType = ntohl(finfo->fileType);
    353     creator = PyString_FromStringAndSize((char*)&(finfo->fileCreator), 4);
    354     type = PyString_FromStringAndSize((char*)&(finfo->fileType), 4);
    355 
    356     res = Py_BuildValue("OO", creator, type);
    357     Py_DECREF(creator);
    358     Py_DECREF(type);
    359     return res;
    360 }
    361 
    362 static char setcrtp_doc[] = "Set MacOS 4-char creator and type for a file";
    363 
    364 static PyObject *
    365 MacOS_SetCreatorAndType(PyObject *self, PyObject *args)
    366 {
    367     ResType creator, type;
    368     FSRef ref;
    369     FileInfo* finfo;
    370     OSErr err;
    371     FSCatalogInfo       cataloginfo;
    372 
    373     if (!PyArg_ParseTuple(args, "O&O&O&",
    374                     PyMac_GetFSRef, &ref, PyMac_GetOSType, &creator, PyMac_GetOSType, &type)) {
    375 #if APPLE_SUPPORTS_QUICKTIME
    376         /* Try to handle FSSpec arguments, for backward compatibility */
    377         FSSpec fss;
    378         FInfo info;
    379 
    380         if (!PyArg_ParseTuple(args, "O&O&O&",
    381             PyMac_GetFSSpec, &fss, PyMac_GetOSType, &creator, PyMac_GetOSType, &type))
    382             return NULL;
    383 
    384         if ((err = FSpGetFInfo(&fss, &info)) != noErr)
    385             return PyErr_Mac(MacOS_Error, err);
    386 
    387         info.fdCreator = creator;
    388         info.fdType = type;
    389 
    390         if ((err = FSpSetFInfo(&fss, &info)) != noErr)
    391             return PyErr_Mac(MacOS_Error, err);
    392         Py_INCREF(Py_None);
    393         return Py_None;
    394 #else /* APPLE_SUPPORTS_QUICKTIME */
    395         return NULL;
    396 #endif /* APPLE_SUPPORTS_QUICKTIME */
    397     }
    398 
    399     err = FSGetCatalogInfo(&ref,
    400                     kFSCatInfoFinderInfo|kFSCatInfoNodeFlags, &cataloginfo,
    401                     NULL, NULL, NULL);
    402     if (err != noErr) {
    403         PyErr_Mac(MacOS_Error, err);
    404         return NULL;
    405     }
    406 
    407     if ((cataloginfo.nodeFlags & kFSNodeIsDirectoryMask) != 0) {
    408         /* Directory: doesn't have type/creator info.
    409          *
    410          * The specific error code is for backward compatibility with
    411          * earlier versions.
    412          */
    413         PyErr_Mac(MacOS_Error, fnfErr);
    414         return NULL;
    415 
    416     }
    417     finfo = (FileInfo*)&(cataloginfo.finderInfo);
    418     finfo->fileCreator = creator;
    419     finfo->fileType = type;
    420 
    421     err = FSSetCatalogInfo(&ref, kFSCatInfoFinderInfo, &cataloginfo);
    422     if (err != noErr) {
    423         PyErr_Mac(MacOS_Error, fnfErr);
    424         return NULL;
    425     }
    426 
    427     Py_INCREF(Py_None);
    428     return Py_None;
    429 }
    430 
    431 
    432 static char geterr_doc[] = "Convert OSErr number to string";
    433 
    434 static PyObject *
    435 MacOS_GetErrorString(PyObject *self, PyObject *args)
    436 {
    437     int err;
    438     char buf[256];
    439     Handle h;
    440     char *str;
    441     static int errors_loaded;
    442 
    443     if (!PyArg_ParseTuple(args, "i", &err))
    444         return NULL;
    445 
    446     h = GetResource('Estr', err);
    447     if (!h && !errors_loaded) {
    448         /*
    449         ** Attempt to open the resource file containing the
    450         ** Estr resources. We ignore all errors. We also try
    451         ** this only once.
    452         */
    453         PyObject *m, *rv;
    454         errors_loaded = 1;
    455 
    456         m = PyImport_ImportModuleNoBlock("macresource");
    457         if (!m) {
    458             if (Py_VerboseFlag)
    459                 PyErr_Print();
    460             PyErr_Clear();
    461         }
    462         else {
    463             rv = PyObject_CallMethod(m, "open_error_resource", "");
    464             if (!rv) {
    465                 if (Py_VerboseFlag)
    466                     PyErr_Print();
    467                 PyErr_Clear();
    468             }
    469             else {
    470                 Py_DECREF(rv);
    471                 /* And try again... */
    472                 h = GetResource('Estr', err);
    473             }
    474             Py_DECREF(m);
    475         }
    476     }
    477     /*
    478     ** Whether the code above succeeded or not, we won't try
    479     ** again.
    480     */
    481     errors_loaded = 1;
    482 
    483     if (h) {
    484         HLock(h);
    485         str = (char *)*h;
    486         memcpy(buf, str+1, (unsigned char)str[0]);
    487         buf[(unsigned char)str[0]] = '\0';
    488         HUnlock(h);
    489         ReleaseResource(h);
    490     }
    491     else {
    492         PyOS_snprintf(buf, sizeof(buf), "Mac OS error code %d", err);
    493     }
    494 
    495     return Py_BuildValue("s", buf);
    496 }
    497 
    498 
    499 #ifndef __LP64__
    500 
    501 static char splash_doc[] = "Open a splash-screen dialog by resource-id (0=close)";
    502 
    503 static PyObject *
    504 MacOS_splash(PyObject *self, PyObject *args)
    505 {
    506     int resid = -1;
    507     static DialogPtr curdialog = NULL;
    508     DialogPtr olddialog;
    509     WindowRef theWindow;
    510     CGrafPtr thePort;
    511 #if 0
    512     short xpos, ypos, width, height, swidth, sheight;
    513 #endif
    514 
    515     if (!PyArg_ParseTuple(args, "|i", &resid))
    516         return NULL;
    517     olddialog = curdialog;
    518     curdialog = NULL;
    519 
    520     if ( resid != -1 ) {
    521         curdialog = GetNewDialog(resid, NULL, (WindowPtr)-1);
    522         if ( curdialog ) {
    523             theWindow = GetDialogWindow(curdialog);
    524             thePort = GetWindowPort(theWindow);
    525 #if 0
    526             width = thePort->portRect.right - thePort->portRect.left;
    527             height = thePort->portRect.bottom - thePort->portRect.top;
    528             swidth = qd.screenBits.bounds.right - qd.screenBits.bounds.left;
    529             sheight = qd.screenBits.bounds.bottom - qd.screenBits.bounds.top - LMGetMBarHeight();
    530             xpos = (swidth-width)/2;
    531             ypos = (sheight-height)/5 + LMGetMBarHeight();
    532             MoveWindow(theWindow, xpos, ypos, 0);
    533             ShowWindow(theWindow);
    534 #endif
    535             DrawDialog(curdialog);
    536         }
    537     }
    538     if (olddialog)
    539         DisposeDialog(olddialog);
    540     Py_INCREF(Py_None);
    541     return Py_None;
    542 }
    543 
    544 static char DebugStr_doc[] = "Switch to low-level debugger with a message";
    545 
    546 static PyObject *
    547 MacOS_DebugStr(PyObject *self, PyObject *args)
    548 {
    549     Str255 message;
    550     PyObject *object = 0;
    551 
    552     if (!PyArg_ParseTuple(args, "O&|O", PyMac_GetStr255, message, &object))
    553         return NULL;
    554 
    555     DebugStr(message);
    556     Py_INCREF(Py_None);
    557     return Py_None;
    558 }
    559 
    560 
    561 static char SysBeep_doc[] = "BEEEEEP!!!";
    562 
    563 static PyObject *
    564 MacOS_SysBeep(PyObject *self, PyObject *args)
    565 {
    566     int duration = 6;
    567 
    568     if (!PyArg_ParseTuple(args, "|i", &duration))
    569         return NULL;
    570     SysBeep(duration);
    571     Py_INCREF(Py_None);
    572     return Py_None;
    573 }
    574 
    575 #endif /* __LP64__ */
    576 
    577 static char WMAvailable_doc[] =
    578     "True if this process can interact with the display."
    579     "Will foreground the application on the first call as a side-effect."
    580     ;
    581 
    582 static PyObject *
    583 MacOS_WMAvailable(PyObject *self, PyObject *args)
    584 {
    585     static PyObject *rv = NULL;
    586 
    587     if (!PyArg_ParseTuple(args, ""))
    588         return NULL;
    589     if (!rv) {
    590         ProcessSerialNumber psn;
    591 
    592         /*
    593         ** This is a fairly innocuous call to make if we don't have a window
    594         ** manager, or if we have no permission to talk to it. It will print
    595         ** a message on stderr, but at least it won't abort the process.
    596         ** It appears the function caches the result itself, and it's cheap, so
    597         ** no need for us to cache.
    598         */
    599 #ifdef kCGNullDirectDisplay
    600         /* On 10.1 CGMainDisplayID() isn't available, and
    601         ** kCGNullDirectDisplay isn't defined.
    602         */
    603         if (CGMainDisplayID() == 0) {
    604             rv = Py_False;
    605         } else {
    606 #else
    607         {
    608 #endif
    609             if (GetCurrentProcess(&psn) < 0 ||
    610                 SetFrontProcess(&psn) < 0) {
    611                 rv = Py_False;
    612             } else {
    613                 rv = Py_True;
    614             }
    615         }
    616     }
    617     Py_INCREF(rv);
    618     return rv;
    619 }
    620 
    621 static char GetTicks_doc[] = "Return number of ticks since bootup";
    622 
    623 static PyObject *
    624 MacOS_GetTicks(PyObject *self, PyObject *args)
    625 {
    626     return Py_BuildValue("i", (int)TickCount());
    627 }
    628 
    629 static char openrf_doc[] = "Open resource fork of a file";
    630 
    631 static PyObject *
    632 MacOS_openrf(PyObject *self, PyObject *args)
    633 {
    634     OSErr err;
    635     char *mode = "r";
    636     FSRef ref;
    637     SInt8 permission = fsRdPerm;
    638     rfobject *fp;
    639     HFSUniStr255 name;
    640 
    641     if (!PyArg_ParseTuple(args, "O&|s", PyMac_GetFSRef, &ref, &mode))
    642         return NULL;
    643     while (*mode) {
    644         switch (*mode++) {
    645         case '*': break;
    646         case 'r': permission = fsRdPerm; break;
    647         case 'w': permission = fsWrPerm; break;
    648         case 'b': break;
    649         default:
    650             PyErr_BadArgument();
    651             return NULL;
    652         }
    653     }
    654 
    655     err = FSGetResourceForkName(&name);
    656     if (err != noErr) {
    657         PyMac_Error(err);
    658         return NULL;
    659     }
    660 
    661     if ( (fp = newrfobject()) == NULL )
    662         return NULL;
    663 
    664 
    665     err = FSOpenFork(&ref, name.length, name.unicode, permission, &fp->fRefNum);
    666     if (err != noErr) {
    667         Py_DECREF(fp);
    668         PyMac_Error(err);
    669         return NULL;
    670     }
    671     fp->isclosed = 0;
    672     return (PyObject *)fp;
    673 }
    674 
    675 
    676 
    677 static PyMethodDef MacOS_Methods[] = {
    678     {"GetCreatorAndType",               MacOS_GetCreatorAndType, 1,     getcrtp_doc},
    679     {"SetCreatorAndType",               MacOS_SetCreatorAndType, 1,     setcrtp_doc},
    680     {"GetErrorString",                  MacOS_GetErrorString,   1,      geterr_doc},
    681     {"openrf",                          MacOS_openrf,           1,      openrf_doc},
    682 #ifndef __LP64__
    683     {"splash",                          MacOS_splash,           1,      splash_doc},
    684     {"DebugStr",                        MacOS_DebugStr,         1,      DebugStr_doc},
    685     {"SysBeep",                         MacOS_SysBeep,          1,      SysBeep_doc},
    686 #endif /* __LP64__ */
    687     {"GetTicks",                        MacOS_GetTicks,         1,      GetTicks_doc},
    688     {"WMAvailable",                     MacOS_WMAvailable,              1,      WMAvailable_doc},
    689     {NULL,                              NULL}            /* Sentinel */
    690 };
    691 
    692 
    693 void
    694 initMacOS(void)
    695 {
    696     PyObject *m, *d;
    697 
    698     if (PyErr_WarnPy3k("In 3.x, the MacOS module is removed.", 1))
    699         return;
    700 
    701     m = Py_InitModule("MacOS", MacOS_Methods);
    702     d = PyModule_GetDict(m);
    703 
    704     /* Initialize MacOS.Error exception */
    705     MacOS_Error = PyMac_GetOSErrException();
    706     if (MacOS_Error == NULL || PyDict_SetItemString(d, "Error", MacOS_Error) != 0)
    707         return;
    708     Rftype.ob_type = &PyType_Type;
    709     Py_INCREF(&Rftype);
    710     if (PyDict_SetItemString(d, "ResourceForkType", (PyObject *)&Rftype) != 0)
    711         return;
    712     /*
    713     ** This is a hack: the following constant added to the id() of a string
    714     ** object gives you the address of the data. Unfortunately, it is needed for
    715     ** some of the image and sound processing interfaces on the mac:-(
    716     */
    717     {
    718         PyStringObject *p = 0;
    719         long off = (long)&(p->ob_sval[0]);
    720 
    721         if( PyDict_SetItemString(d, "string_id_to_buffer", Py_BuildValue("i", off)) != 0)
    722             return;
    723     }
    724 #define PY_RUNTIMEMODEL "macho"
    725     if (PyDict_SetItemString(d, "runtimemodel",
    726                             Py_BuildValue("s", PY_RUNTIMEMODEL)) != 0)
    727         return;
    728 #if defined(WITH_NEXT_FRAMEWORK)
    729 #define PY_LINKMODEL "framework"
    730 #elif defined(Py_ENABLE_SHARED)
    731 #define PY_LINKMODEL "shared"
    732 #else
    733 #define PY_LINKMODEL "static"
    734 #endif
    735     if (PyDict_SetItemString(d, "linkmodel",
    736                             Py_BuildValue("s", PY_LINKMODEL)) != 0)
    737         return;
    738 
    739 }
    740