blob: 434c547d1cc8ac1a1ec105a79b1872a4018a4599 [file] [log] [blame]
Guido van Rossum2d167031994-09-16 10:54:21 +00001/***********************************************************
Jack Jansen42218ce1997-01-31 16:15:11 +00002Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
Guido van Rossum99546991995-01-08 14:33:34 +00003The Netherlands.
Guido van Rossum2d167031994-09-16 10:54:21 +00004
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
25/* Macintosh OS-specific interface */
26
27#include "Python.h"
Jack Jansen7107c1a2003-11-20 13:31:00 +000028#include "pymactoolbox.h"
Guido van Rossum2d167031994-09-16 10:54:21 +000029
Jack Jansen6143d532001-05-19 12:34:59 +000030#include <Carbon/Carbon.h>
Jack Jansend7c17232003-02-21 16:31:11 +000031#include <ApplicationServices/ApplicationServices.h>
Jack Jansenee23d6e1995-01-27 14:43:25 +000032
Guido van Rossum2d167031994-09-16 10:54:21 +000033static PyObject *MacOS_Error; /* Exception MacOS.Error */
34
Jack Jansen697842f2001-09-10 22:00:39 +000035#define PATHNAMELEN 1024
Jack Jansen697842f2001-09-10 22:00:39 +000036
Jack Jansen76a05891996-02-29 16:11:32 +000037/* ----------------------------------------------------- */
38
39/* Declarations for objects of type Resource fork */
40
41typedef struct {
42 PyObject_HEAD
43 short fRefNum;
44 int isclosed;
45} rfobject;
46
Jeremy Hylton938ace62002-07-17 16:30:39 +000047static PyTypeObject Rftype;
Jack Jansen76a05891996-02-29 16:11:32 +000048
49
50
51/* ---------------------------------------------------------------- */
52
53static void
Jack Jansendeefbe52001-08-08 13:46:49 +000054do_close(rfobject *self)
Jack Jansen76a05891996-02-29 16:11:32 +000055{
56 if (self->isclosed ) return;
57 (void)FSClose(self->fRefNum);
58 self->isclosed = 1;
59}
60
61static char rf_read__doc__[] =
62"Read data from resource fork"
63;
64
65static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +000066rf_read(rfobject *self, PyObject *args)
Jack Jansen76a05891996-02-29 16:11:32 +000067{
68 long n;
69 PyObject *v;
70 OSErr err;
71
72 if (self->isclosed) {
73 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
74 return NULL;
75 }
76
77 if (!PyArg_ParseTuple(args, "l", &n))
78 return NULL;
79
80 v = PyString_FromStringAndSize((char *)NULL, n);
81 if (v == NULL)
82 return NULL;
83
84 err = FSRead(self->fRefNum, &n, PyString_AsString(v));
85 if (err && err != eofErr) {
86 PyMac_Error(err);
87 Py_DECREF(v);
88 return NULL;
89 }
90 _PyString_Resize(&v, n);
91 return v;
92}
93
94
95static char rf_write__doc__[] =
96"Write to resource fork"
97;
98
99static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000100rf_write(rfobject *self, PyObject *args)
Jack Jansen76a05891996-02-29 16:11:32 +0000101{
102 char *buffer;
103 long size;
104 OSErr err;
105
106 if (self->isclosed) {
107 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
108 return NULL;
109 }
Jack Janseneeccca91997-05-07 15:46:31 +0000110 if (!PyArg_ParseTuple(args, "s#", &buffer, &size))
Jack Jansen76a05891996-02-29 16:11:32 +0000111 return NULL;
112 err = FSWrite(self->fRefNum, &size, buffer);
113 if (err) {
114 PyMac_Error(err);
115 return NULL;
116 }
117 Py_INCREF(Py_None);
118 return Py_None;
119}
120
121
122static char rf_seek__doc__[] =
123"Set file position"
124;
125
126static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000127rf_seek(rfobject *self, PyObject *args)
Jack Jansen76a05891996-02-29 16:11:32 +0000128{
129 long amount, pos;
130 int whence = SEEK_SET;
131 long eof;
132 OSErr err;
133
134 if (self->isclosed) {
135 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
136 return NULL;
137 }
138 if (!PyArg_ParseTuple(args, "l|i", &amount, &whence))
139 return NULL;
140
Jack Jansendeefbe52001-08-08 13:46:49 +0000141 if ((err = GetEOF(self->fRefNum, &eof)))
Jack Jansen76a05891996-02-29 16:11:32 +0000142 goto ioerr;
143
144 switch (whence) {
145 case SEEK_CUR:
Jack Jansendeefbe52001-08-08 13:46:49 +0000146 if ((err = GetFPos(self->fRefNum, &pos)))
Jack Jansen76a05891996-02-29 16:11:32 +0000147 goto ioerr;
148 break;
149 case SEEK_END:
150 pos = eof;
151 break;
152 case SEEK_SET:
153 pos = 0;
154 break;
155 default:
156 PyErr_BadArgument();
157 return NULL;
158 }
159
160 pos += amount;
161
162 /* Don't bother implementing seek past EOF */
163 if (pos > eof || pos < 0) {
164 PyErr_BadArgument();
165 return NULL;
166 }
167
Jack Jansendeefbe52001-08-08 13:46:49 +0000168 if ((err = SetFPos(self->fRefNum, fsFromStart, pos)) ) {
Jack Jansen76a05891996-02-29 16:11:32 +0000169ioerr:
170 PyMac_Error(err);
171 return NULL;
172 }
173 Py_INCREF(Py_None);
174 return Py_None;
175}
176
177
178static char rf_tell__doc__[] =
179"Get file position"
180;
181
182static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000183rf_tell(rfobject *self, PyObject *args)
Jack Jansen76a05891996-02-29 16:11:32 +0000184{
185 long where;
186 OSErr err;
187
188 if (self->isclosed) {
189 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
190 return NULL;
191 }
192 if (!PyArg_ParseTuple(args, ""))
193 return NULL;
Jack Jansendeefbe52001-08-08 13:46:49 +0000194 if ((err = GetFPos(self->fRefNum, &where)) ) {
Jack Jansen76a05891996-02-29 16:11:32 +0000195 PyMac_Error(err);
196 return NULL;
197 }
198 return PyInt_FromLong(where);
199}
200
201static char rf_close__doc__[] =
202"Close resource fork"
203;
204
205static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000206rf_close(rfobject *self, PyObject *args)
Jack Jansen76a05891996-02-29 16:11:32 +0000207{
Jack Jansen76a05891996-02-29 16:11:32 +0000208 if (!PyArg_ParseTuple(args, ""))
209 return NULL;
210 do_close(self);
211 Py_INCREF(Py_None);
212 return Py_None;
213}
214
215
216static struct PyMethodDef rf_methods[] = {
Jack Jansendeefbe52001-08-08 13:46:49 +0000217 {"read", (PyCFunction)rf_read, 1, rf_read__doc__},
218 {"write", (PyCFunction)rf_write, 1, rf_write__doc__},
219 {"seek", (PyCFunction)rf_seek, 1, rf_seek__doc__},
220 {"tell", (PyCFunction)rf_tell, 1, rf_tell__doc__},
221 {"close", (PyCFunction)rf_close, 1, rf_close__doc__},
Jack Jansen76a05891996-02-29 16:11:32 +0000222
223 {NULL, NULL} /* sentinel */
224};
225
226/* ---------- */
227
228
229static rfobject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000230newrfobject(void)
Jack Jansen76a05891996-02-29 16:11:32 +0000231{
232 rfobject *self;
233
234 self = PyObject_NEW(rfobject, &Rftype);
235 if (self == NULL)
236 return NULL;
237 self->isclosed = 1;
238 return self;
239}
240
241
242static void
Jack Jansendeefbe52001-08-08 13:46:49 +0000243rf_dealloc(rfobject *self)
Jack Jansen76a05891996-02-29 16:11:32 +0000244{
245 do_close(self);
Jack Jansen0e2f7982002-05-22 14:31:48 +0000246 PyObject_DEL(self);
Jack Jansen76a05891996-02-29 16:11:32 +0000247}
248
249static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000250rf_getattr(rfobject *self, char *name)
Jack Jansen76a05891996-02-29 16:11:32 +0000251{
252 return Py_FindMethod(rf_methods, (PyObject *)self, name);
253}
254
255static char Rftype__doc__[] =
256"Resource fork file object"
257;
258
259static PyTypeObject Rftype = {
Martin v. Löwis95c95ce2007-07-22 14:41:55 +0000260 PyVarObject_HEAD_INIT(&PyType_Type, 0)
Guido van Rossum14648392001-12-08 18:02:58 +0000261 "MacOS.ResourceFork", /*tp_name*/
Jack Jansen76a05891996-02-29 16:11:32 +0000262 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/* End of code for Resource fork objects */
284/* -------------------------------------------------------- */
Guido van Rossum2d167031994-09-16 10:54:21 +0000285
286/*----------------------------------------------------------------------*/
Guido van Rossume791c2e1995-01-09 13:20:04 +0000287/* Miscellaneous File System Operations */
288
Jack Jansenfe94e972003-03-19 22:51:42 +0000289static char getcrtp_doc[] = "Get MacOS 4-char creator and type for a file";
Jack Jansen120a1051997-06-03 15:29:41 +0000290
Guido van Rossume791c2e1995-01-09 13:20:04 +0000291static PyObject *
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000292MacOS_GetCreatorAndType(PyObject *self, PyObject *args)
Guido van Rossume791c2e1995-01-09 13:20:04 +0000293{
Jack Jansene79dc762000-06-02 21:35:07 +0000294 FSSpec fss;
Guido van Rossume791c2e1995-01-09 13:20:04 +0000295 FInfo info;
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000296 PyObject *creator, *type, *res;
Guido van Rossume791c2e1995-01-09 13:20:04 +0000297 OSErr err;
298
Jack Jansene79dc762000-06-02 21:35:07 +0000299 if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSSpec, &fss))
Guido van Rossume791c2e1995-01-09 13:20:04 +0000300 return NULL;
Jack Jansene79dc762000-06-02 21:35:07 +0000301 if ((err = FSpGetFInfo(&fss, &info)) != noErr)
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000302 return PyErr_Mac(MacOS_Error, err);
Guido van Rossume791c2e1995-01-09 13:20:04 +0000303 creator = PyString_FromStringAndSize((char *)&info.fdCreator, 4);
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000304 type = PyString_FromStringAndSize((char *)&info.fdType, 4);
305 res = Py_BuildValue("OO", creator, type);
Guido van Rossumfffb8bb1995-01-12 12:37:24 +0000306 Py_DECREF(creator);
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000307 Py_DECREF(type);
Guido van Rossume791c2e1995-01-09 13:20:04 +0000308 return res;
309}
310
Jack Jansenfe94e972003-03-19 22:51:42 +0000311static char setcrtp_doc[] = "Set MacOS 4-char creator and type for a file";
Jack Jansen120a1051997-06-03 15:29:41 +0000312
Guido van Rossume791c2e1995-01-09 13:20:04 +0000313static PyObject *
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000314MacOS_SetCreatorAndType(PyObject *self, PyObject *args)
Guido van Rossume791c2e1995-01-09 13:20:04 +0000315{
Jack Jansene79dc762000-06-02 21:35:07 +0000316 FSSpec fss;
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000317 ResType creator, type;
Guido van Rossume791c2e1995-01-09 13:20:04 +0000318 FInfo info;
319 OSErr err;
320
321 if (!PyArg_ParseTuple(args, "O&O&O&",
Jack Jansene79dc762000-06-02 21:35:07 +0000322 PyMac_GetFSSpec, &fss, PyMac_GetOSType, &creator, PyMac_GetOSType, &type))
Guido van Rossume791c2e1995-01-09 13:20:04 +0000323 return NULL;
Jack Jansene79dc762000-06-02 21:35:07 +0000324 if ((err = FSpGetFInfo(&fss, &info)) != noErr)
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000325 return PyErr_Mac(MacOS_Error, err);
Guido van Rossume791c2e1995-01-09 13:20:04 +0000326 info.fdCreator = creator;
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000327 info.fdType = type;
Jack Jansene79dc762000-06-02 21:35:07 +0000328 if ((err = FSpSetFInfo(&fss, &info)) != noErr)
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000329 return PyErr_Mac(MacOS_Error, err);
Guido van Rossume791c2e1995-01-09 13:20:04 +0000330 Py_INCREF(Py_None);
331 return Py_None;
332}
333
Jack Jansena76382a1995-02-02 14:25:56 +0000334
Jack Jansen120a1051997-06-03 15:29:41 +0000335static char geterr_doc[] = "Convert OSErr number to string";
336
Jack Jansen829f88c1995-07-17 11:36:01 +0000337static PyObject *
338MacOS_GetErrorString(PyObject *self, PyObject *args)
339{
Raymond Hettingerec6eb362004-11-05 07:02:59 +0000340 int err;
341 char buf[256];
342 Handle h;
343 char *str;
344 static int errors_loaded;
Jack Jansen829f88c1995-07-17 11:36:01 +0000345
Raymond Hettingerec6eb362004-11-05 07:02:59 +0000346 if (!PyArg_ParseTuple(args, "i", &err))
Jack Jansen829f88c1995-07-17 11:36:01 +0000347 return NULL;
Raymond Hettingerec6eb362004-11-05 07:02:59 +0000348
349 h = GetResource('Estr', err);
350 if (!h && !errors_loaded) {
351 /*
352 ** Attempt to open the resource file containing the
353 ** Estr resources. We ignore all errors. We also try
354 ** this only once.
355 */
356 PyObject *m, *rv;
357 errors_loaded = 1;
358
359 m = PyImport_ImportModule("macresource");
360 if (!m) {
361 if (Py_VerboseFlag)
362 PyErr_Print();
363 PyErr_Clear();
364 }
365 else {
366 rv = PyObject_CallMethod(m, "open_error_resource", "");
367 if (!rv) {
368 if (Py_VerboseFlag)
369 PyErr_Print();
370 PyErr_Clear();
371 }
372 else {
373 Py_DECREF(rv);
374 /* And try again... */
375 h = GetResource('Estr', err);
376 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000377 Py_DECREF(m);
Raymond Hettingerec6eb362004-11-05 07:02:59 +0000378 }
379 }
380 /*
381 ** Whether the code above succeeded or not, we won't try
382 ** again.
383 */
384 errors_loaded = 1;
385
386 if (h) {
387 HLock(h);
388 str = (char *)*h;
389 memcpy(buf, str+1, (unsigned char)str[0]);
390 buf[(unsigned char)str[0]] = '\0';
391 HUnlock(h);
392 ReleaseResource(h);
393 }
394 else {
395 PyOS_snprintf(buf, sizeof(buf), "Mac OS error code %d", err);
396 }
397
398 return Py_BuildValue("s", buf);
Jack Jansen829f88c1995-07-17 11:36:01 +0000399}
400
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000401static char splash_doc[] = "Open a splash-screen dialog by resource-id (0=close)";
402
403static PyObject *
404MacOS_splash(PyObject *self, PyObject *args)
405{
Jack Jansendf34cf11996-09-15 22:12:00 +0000406 int resid = -1;
Jack Jansen450ae9f1997-05-13 15:41:48 +0000407 static DialogPtr curdialog = NULL;
Jack Jansen2e871e41997-09-08 13:23:19 +0000408 DialogPtr olddialog;
Jack Jansen04df9d51996-09-23 15:49:43 +0000409 WindowRef theWindow;
410 CGrafPtr thePort;
Jack Jansene79dc762000-06-02 21:35:07 +0000411#if 0
Jack Jansen04df9d51996-09-23 15:49:43 +0000412 short xpos, ypos, width, height, swidth, sheight;
Jack Jansene79dc762000-06-02 21:35:07 +0000413#endif
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000414
Jack Jansendf34cf11996-09-15 22:12:00 +0000415 if (!PyArg_ParseTuple(args, "|i", &resid))
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000416 return NULL;
Jack Jansen2e871e41997-09-08 13:23:19 +0000417 olddialog = curdialog;
Jack Jansencbe6a531998-02-20 15:59:59 +0000418 curdialog = NULL;
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000419
Jack Jansendf34cf11996-09-15 22:12:00 +0000420 if ( resid != -1 ) {
421 curdialog = GetNewDialog(resid, NULL, (WindowPtr)-1);
Jack Jansen04df9d51996-09-23 15:49:43 +0000422 if ( curdialog ) {
423 theWindow = GetDialogWindow(curdialog);
424 thePort = GetWindowPort(theWindow);
Jack Jansene79dc762000-06-02 21:35:07 +0000425#if 0
Jack Jansen04df9d51996-09-23 15:49:43 +0000426 width = thePort->portRect.right - thePort->portRect.left;
427 height = thePort->portRect.bottom - thePort->portRect.top;
428 swidth = qd.screenBits.bounds.right - qd.screenBits.bounds.left;
429 sheight = qd.screenBits.bounds.bottom - qd.screenBits.bounds.top - LMGetMBarHeight();
430 xpos = (swidth-width)/2;
431 ypos = (sheight-height)/5 + LMGetMBarHeight();
432 MoveWindow(theWindow, xpos, ypos, 0);
433 ShowWindow(theWindow);
Jack Jansene79dc762000-06-02 21:35:07 +0000434#endif
Jack Jansendf34cf11996-09-15 22:12:00 +0000435 DrawDialog(curdialog);
Jack Jansen04df9d51996-09-23 15:49:43 +0000436 }
Jack Jansendf34cf11996-09-15 22:12:00 +0000437 }
Jack Jansen2e871e41997-09-08 13:23:19 +0000438 if (olddialog)
439 DisposeDialog(olddialog);
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000440 Py_INCREF(Py_None);
441 return Py_None;
442}
443
Jack Janseneb76b841996-09-30 14:43:22 +0000444static char DebugStr_doc[] = "Switch to low-level debugger with a message";
445
446static PyObject *
447MacOS_DebugStr(PyObject *self, PyObject *args)
448{
449 Str255 message;
450 PyObject *object = 0;
451
452 if (!PyArg_ParseTuple(args, "O&|O", PyMac_GetStr255, message, &object))
453 return NULL;
454 DebugStr(message);
455 Py_INCREF(Py_None);
456 return Py_None;
457}
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000458
Jack Jansen2e871e41997-09-08 13:23:19 +0000459static char SysBeep_doc[] = "BEEEEEP!!!";
460
461static PyObject *
462MacOS_SysBeep(PyObject *self, PyObject *args)
463{
464 int duration = 6;
465
466 if (!PyArg_ParseTuple(args, "|i", &duration))
467 return NULL;
468 SysBeep(duration);
469 Py_INCREF(Py_None);
470 return Py_None;
471}
472
Jack Jansend7c17232003-02-21 16:31:11 +0000473static char WMAvailable_doc[] =
474 "True if this process can interact with the display."
475 "Will foreground the application on the first call as a side-effect."
476 ;
477
478static PyObject *
479MacOS_WMAvailable(PyObject *self, PyObject *args)
480{
481 static PyObject *rv = NULL;
482
483 if (!PyArg_ParseTuple(args, ""))
484 return NULL;
485 if (!rv) {
Jack Jansend7c17232003-02-21 16:31:11 +0000486 ProcessSerialNumber psn;
487
488 /*
489 ** This is a fairly innocuous call to make if we don't have a window
490 ** manager, or if we have no permission to talk to it. It will print
491 ** a message on stderr, but at least it won't abort the process.
492 ** It appears the function caches the result itself, and it's cheap, so
493 ** no need for us to cache.
494 */
Jack Jansen43285d42004-06-02 13:44:05 +0000495#ifdef kCGNullDirectDisplay
496 /* On 10.1 CGMainDisplayID() isn't available, and
497 ** kCGNullDirectDisplay isn't defined.
498 */
Jack Jansend7c17232003-02-21 16:31:11 +0000499 if (CGMainDisplayID() == 0) {
500 rv = Py_False;
501 } else {
Jack Jansen43285d42004-06-02 13:44:05 +0000502#else
503 {
504#endif
Jack Jansend7c17232003-02-21 16:31:11 +0000505 if (GetCurrentProcess(&psn) < 0 ||
506 SetFrontProcess(&psn) < 0) {
507 rv = Py_False;
508 } else {
509 rv = Py_True;
510 }
511 }
Jack Jansend7c17232003-02-21 16:31:11 +0000512 }
513 Py_INCREF(rv);
514 return rv;
515}
516
Jack Jansen898ac1b1997-09-01 15:38:12 +0000517static char GetTicks_doc[] = "Return number of ticks since bootup";
518
519static PyObject *
520MacOS_GetTicks(PyObject *self, PyObject *args)
521{
Jack Jansene79dc762000-06-02 21:35:07 +0000522 return Py_BuildValue("i", (int)TickCount());
Jack Jansen898ac1b1997-09-01 15:38:12 +0000523}
524
Jack Jansen76a05891996-02-29 16:11:32 +0000525static char openrf_doc[] = "Open resource fork of a file";
526
527static PyObject *
528MacOS_openrf(PyObject *self, PyObject *args)
529{
530 OSErr err;
531 char *mode = "r";
532 FSSpec fss;
533 SignedByte permission = 1;
534 rfobject *fp;
535
536 if (!PyArg_ParseTuple(args, "O&|s", PyMac_GetFSSpec, &fss, &mode))
537 return NULL;
538 while (*mode) {
539 switch (*mode++) {
540 case '*': break;
541 case 'r': permission = 1; break;
542 case 'w': permission = 2; break;
543 case 'b': break;
544 default:
545 PyErr_BadArgument();
546 return NULL;
547 }
548 }
549
550 if ( (fp = newrfobject()) == NULL )
551 return NULL;
552
553 err = HOpenRF(fss.vRefNum, fss.parID, fss.name, permission, &fp->fRefNum);
554
555 if ( err == fnfErr ) {
556 /* In stead of doing complicated things here to get creator/type
557 ** correct we let the standard i/o library handle it
558 */
559 FILE *tfp;
Jack Jansen697842f2001-09-10 22:00:39 +0000560 char pathname[PATHNAMELEN];
Jack Jansen76a05891996-02-29 16:11:32 +0000561
Jack Jansenb7348692002-12-23 23:16:25 +0000562 if ( (err=PyMac_GetFullPathname(&fss, pathname, PATHNAMELEN)) ) {
Jack Jansen76a05891996-02-29 16:11:32 +0000563 PyMac_Error(err);
564 Py_DECREF(fp);
565 return NULL;
566 }
567
568 if ( (tfp = fopen(pathname, "w")) == NULL ) {
569 PyMac_Error(fnfErr); /* What else... */
570 Py_DECREF(fp);
571 return NULL;
572 }
573 fclose(tfp);
574 err = HOpenRF(fss.vRefNum, fss.parID, fss.name, permission, &fp->fRefNum);
575 }
576 if ( err ) {
577 Py_DECREF(fp);
578 PyMac_Error(err);
579 return NULL;
580 }
581 fp->isclosed = 0;
582 return (PyObject *)fp;
583}
584
Jack Jansen8413b472000-10-19 22:02:16 +0000585
Guido van Rossum2d167031994-09-16 10:54:21 +0000586static PyMethodDef MacOS_Methods[] = {
Jack Jansen120a1051997-06-03 15:29:41 +0000587 {"GetCreatorAndType", MacOS_GetCreatorAndType, 1, getcrtp_doc},
588 {"SetCreatorAndType", MacOS_SetCreatorAndType, 1, setcrtp_doc},
Jack Jansen120a1051997-06-03 15:29:41 +0000589 {"GetErrorString", MacOS_GetErrorString, 1, geterr_doc},
590 {"openrf", MacOS_openrf, 1, openrf_doc},
591 {"splash", MacOS_splash, 1, splash_doc},
592 {"DebugStr", MacOS_DebugStr, 1, DebugStr_doc},
Jack Jansen898ac1b1997-09-01 15:38:12 +0000593 {"GetTicks", MacOS_GetTicks, 1, GetTicks_doc},
Jack Jansen2e871e41997-09-08 13:23:19 +0000594 {"SysBeep", MacOS_SysBeep, 1, SysBeep_doc},
Jack Jansend7c17232003-02-21 16:31:11 +0000595 {"WMAvailable", MacOS_WMAvailable, 1, WMAvailable_doc},
Guido van Rossumf74d4e21995-01-18 23:58:07 +0000596 {NULL, NULL} /* Sentinel */
Guido van Rossum2d167031994-09-16 10:54:21 +0000597};
598
599
600void
Jack Jansendeefbe52001-08-08 13:46:49 +0000601initMacOS(void)
Guido van Rossum2d167031994-09-16 10:54:21 +0000602{
603 PyObject *m, *d;
604
605 m = Py_InitModule("MacOS", MacOS_Methods);
606 d = PyModule_GetDict(m);
607
608 /* Initialize MacOS.Error exception */
Guido van Rossumbf068b11995-01-25 23:09:20 +0000609 MacOS_Error = PyMac_GetOSErrException();
Guido van Rossume433c971994-09-29 10:02:56 +0000610 if (MacOS_Error == NULL || PyDict_SetItemString(d, "Error", MacOS_Error) != 0)
Jack Jansenfa1e27d2000-09-08 10:21:44 +0000611 return;
Martin v. Löwis95c95ce2007-07-22 14:41:55 +0000612 Py_Type(&Rftype) = &PyType_Type;
Jack Jansena755e681997-09-20 17:40:22 +0000613 Py_INCREF(&Rftype);
614 if (PyDict_SetItemString(d, "ResourceForkType", (PyObject *)&Rftype) != 0)
Jack Jansenfa1e27d2000-09-08 10:21:44 +0000615 return;
Jack Jansenf73bab71997-04-03 14:51:03 +0000616 /*
617 ** This is a hack: the following constant added to the id() of a string
618 ** object gives you the address of the data. Unfortunately, it is needed for
619 ** some of the image and sound processing interfaces on the mac:-(
620 */
621 {
622 PyStringObject *p = 0;
623 long off = (long)&(p->ob_sval[0]);
624
625 if( PyDict_SetItemString(d, "string_id_to_buffer", Py_BuildValue("i", off)) != 0)
Jack Jansenfa1e27d2000-09-08 10:21:44 +0000626 return;
Jack Jansenf73bab71997-04-03 14:51:03 +0000627 }
Jack Jansenf3163302001-05-19 12:50:05 +0000628#define PY_RUNTIMEMODEL "macho"
Jack Jansen193509b2001-01-23 22:38:23 +0000629 if (PyDict_SetItemString(d, "runtimemodel",
630 Py_BuildValue("s", PY_RUNTIMEMODEL)) != 0)
631 return;
Jack Jansena53f4eb2003-11-19 16:34:04 +0000632#if defined(WITH_NEXT_FRAMEWORK)
Jack Jansen8cd9a4f2003-02-23 23:23:47 +0000633#define PY_LINKMODEL "framework"
634#elif defined(Py_ENABLE_SHARED)
635#define PY_LINKMODEL "shared"
636#else
637#define PY_LINKMODEL "static"
638#endif
639 if (PyDict_SetItemString(d, "linkmodel",
640 Py_BuildValue("s", PY_LINKMODEL)) != 0)
641 return;
642
Guido van Rossum2d167031994-09-16 10:54:21 +0000643}