blob: 4eabb3951d912c7033f336ca246f22ae69ccbb29 [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 = {
260 PyObject_HEAD_INIT(&PyType_Type)
261 0, /*ob_size*/
Guido van Rossum14648392001-12-08 18:02:58 +0000262 "MacOS.ResourceFork", /*tp_name*/
Jack Jansen76a05891996-02-29 16:11:32 +0000263 sizeof(rfobject), /*tp_basicsize*/
264 0, /*tp_itemsize*/
265 /* methods */
266 (destructor)rf_dealloc, /*tp_dealloc*/
267 (printfunc)0, /*tp_print*/
268 (getattrfunc)rf_getattr, /*tp_getattr*/
269 (setattrfunc)0, /*tp_setattr*/
270 (cmpfunc)0, /*tp_compare*/
271 (reprfunc)0, /*tp_repr*/
272 0, /*tp_as_number*/
273 0, /*tp_as_sequence*/
274 0, /*tp_as_mapping*/
275 (hashfunc)0, /*tp_hash*/
276 (ternaryfunc)0, /*tp_call*/
277 (reprfunc)0, /*tp_str*/
278
279 /* Space for future expansion */
280 0L,0L,0L,0L,
281 Rftype__doc__ /* Documentation string */
282};
283
284/* End of code for Resource fork objects */
285/* -------------------------------------------------------- */
Guido van Rossum2d167031994-09-16 10:54:21 +0000286
287/*----------------------------------------------------------------------*/
Guido van Rossume791c2e1995-01-09 13:20:04 +0000288/* Miscellaneous File System Operations */
289
Jack Jansenfe94e972003-03-19 22:51:42 +0000290static char getcrtp_doc[] = "Get MacOS 4-char creator and type for a file";
Jack Jansen120a1051997-06-03 15:29:41 +0000291
Guido van Rossume791c2e1995-01-09 13:20:04 +0000292static PyObject *
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000293MacOS_GetCreatorAndType(PyObject *self, PyObject *args)
Guido van Rossume791c2e1995-01-09 13:20:04 +0000294{
Jack Jansene79dc762000-06-02 21:35:07 +0000295 FSSpec fss;
Guido van Rossume791c2e1995-01-09 13:20:04 +0000296 FInfo info;
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000297 PyObject *creator, *type, *res;
Guido van Rossume791c2e1995-01-09 13:20:04 +0000298 OSErr err;
299
Jack Jansene79dc762000-06-02 21:35:07 +0000300 if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSSpec, &fss))
Guido van Rossume791c2e1995-01-09 13:20:04 +0000301 return NULL;
Jack Jansene79dc762000-06-02 21:35:07 +0000302 if ((err = FSpGetFInfo(&fss, &info)) != noErr)
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000303 return PyErr_Mac(MacOS_Error, err);
Guido van Rossume791c2e1995-01-09 13:20:04 +0000304 creator = PyString_FromStringAndSize((char *)&info.fdCreator, 4);
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000305 type = PyString_FromStringAndSize((char *)&info.fdType, 4);
306 res = Py_BuildValue("OO", creator, type);
Guido van Rossumfffb8bb1995-01-12 12:37:24 +0000307 Py_DECREF(creator);
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000308 Py_DECREF(type);
Guido van Rossume791c2e1995-01-09 13:20:04 +0000309 return res;
310}
311
Jack Jansenfe94e972003-03-19 22:51:42 +0000312static char setcrtp_doc[] = "Set MacOS 4-char creator and type for a file";
Jack Jansen120a1051997-06-03 15:29:41 +0000313
Guido van Rossume791c2e1995-01-09 13:20:04 +0000314static PyObject *
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000315MacOS_SetCreatorAndType(PyObject *self, PyObject *args)
Guido van Rossume791c2e1995-01-09 13:20:04 +0000316{
Jack Jansene79dc762000-06-02 21:35:07 +0000317 FSSpec fss;
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000318 ResType creator, type;
Guido van Rossume791c2e1995-01-09 13:20:04 +0000319 FInfo info;
320 OSErr err;
321
322 if (!PyArg_ParseTuple(args, "O&O&O&",
Jack Jansene79dc762000-06-02 21:35:07 +0000323 PyMac_GetFSSpec, &fss, PyMac_GetOSType, &creator, PyMac_GetOSType, &type))
Guido van Rossume791c2e1995-01-09 13:20:04 +0000324 return NULL;
Jack Jansene79dc762000-06-02 21:35:07 +0000325 if ((err = FSpGetFInfo(&fss, &info)) != noErr)
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000326 return PyErr_Mac(MacOS_Error, err);
Guido van Rossume791c2e1995-01-09 13:20:04 +0000327 info.fdCreator = creator;
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000328 info.fdType = type;
Jack Jansene79dc762000-06-02 21:35:07 +0000329 if ((err = FSpSetFInfo(&fss, &info)) != noErr)
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000330 return PyErr_Mac(MacOS_Error, err);
Guido van Rossume791c2e1995-01-09 13:20:04 +0000331 Py_INCREF(Py_None);
332 return Py_None;
333}
334
Jack Jansena76382a1995-02-02 14:25:56 +0000335
Jack Jansen120a1051997-06-03 15:29:41 +0000336static char geterr_doc[] = "Convert OSErr number to string";
337
Jack Jansen829f88c1995-07-17 11:36:01 +0000338static PyObject *
339MacOS_GetErrorString(PyObject *self, PyObject *args)
340{
Raymond Hettingerec6eb362004-11-05 07:02:59 +0000341 int err;
342 char buf[256];
343 Handle h;
344 char *str;
345 static int errors_loaded;
Jack Jansen829f88c1995-07-17 11:36:01 +0000346
Raymond Hettingerec6eb362004-11-05 07:02:59 +0000347 if (!PyArg_ParseTuple(args, "i", &err))
Jack Jansen829f88c1995-07-17 11:36:01 +0000348 return NULL;
Raymond Hettingerec6eb362004-11-05 07:02:59 +0000349
350 h = GetResource('Estr', err);
351 if (!h && !errors_loaded) {
352 /*
353 ** Attempt to open the resource file containing the
354 ** Estr resources. We ignore all errors. We also try
355 ** this only once.
356 */
357 PyObject *m, *rv;
358 errors_loaded = 1;
359
360 m = PyImport_ImportModule("macresource");
361 if (!m) {
362 if (Py_VerboseFlag)
363 PyErr_Print();
364 PyErr_Clear();
365 }
366 else {
367 rv = PyObject_CallMethod(m, "open_error_resource", "");
368 if (!rv) {
369 if (Py_VerboseFlag)
370 PyErr_Print();
371 PyErr_Clear();
372 }
373 else {
374 Py_DECREF(rv);
375 /* And try again... */
376 h = GetResource('Estr', err);
377 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000378 Py_DECREF(m);
Raymond Hettingerec6eb362004-11-05 07:02:59 +0000379 }
380 }
381 /*
382 ** Whether the code above succeeded or not, we won't try
383 ** again.
384 */
385 errors_loaded = 1;
386
387 if (h) {
388 HLock(h);
389 str = (char *)*h;
390 memcpy(buf, str+1, (unsigned char)str[0]);
391 buf[(unsigned char)str[0]] = '\0';
392 HUnlock(h);
393 ReleaseResource(h);
394 }
395 else {
396 PyOS_snprintf(buf, sizeof(buf), "Mac OS error code %d", err);
397 }
398
399 return Py_BuildValue("s", buf);
Jack Jansen829f88c1995-07-17 11:36:01 +0000400}
401
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000402static char splash_doc[] = "Open a splash-screen dialog by resource-id (0=close)";
403
404static PyObject *
405MacOS_splash(PyObject *self, PyObject *args)
406{
Jack Jansendf34cf11996-09-15 22:12:00 +0000407 int resid = -1;
Jack Jansen450ae9f1997-05-13 15:41:48 +0000408 static DialogPtr curdialog = NULL;
Jack Jansen2e871e41997-09-08 13:23:19 +0000409 DialogPtr olddialog;
Jack Jansen04df9d51996-09-23 15:49:43 +0000410 WindowRef theWindow;
411 CGrafPtr thePort;
Jack Jansene79dc762000-06-02 21:35:07 +0000412#if 0
Jack Jansen04df9d51996-09-23 15:49:43 +0000413 short xpos, ypos, width, height, swidth, sheight;
Jack Jansene79dc762000-06-02 21:35:07 +0000414#endif
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000415
Jack Jansendf34cf11996-09-15 22:12:00 +0000416 if (!PyArg_ParseTuple(args, "|i", &resid))
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000417 return NULL;
Jack Jansen2e871e41997-09-08 13:23:19 +0000418 olddialog = curdialog;
Jack Jansencbe6a531998-02-20 15:59:59 +0000419 curdialog = NULL;
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000420
Jack Jansendf34cf11996-09-15 22:12:00 +0000421 if ( resid != -1 ) {
422 curdialog = GetNewDialog(resid, NULL, (WindowPtr)-1);
Jack Jansen04df9d51996-09-23 15:49:43 +0000423 if ( curdialog ) {
424 theWindow = GetDialogWindow(curdialog);
425 thePort = GetWindowPort(theWindow);
Jack Jansene79dc762000-06-02 21:35:07 +0000426#if 0
Jack Jansen04df9d51996-09-23 15:49:43 +0000427 width = thePort->portRect.right - thePort->portRect.left;
428 height = thePort->portRect.bottom - thePort->portRect.top;
429 swidth = qd.screenBits.bounds.right - qd.screenBits.bounds.left;
430 sheight = qd.screenBits.bounds.bottom - qd.screenBits.bounds.top - LMGetMBarHeight();
431 xpos = (swidth-width)/2;
432 ypos = (sheight-height)/5 + LMGetMBarHeight();
433 MoveWindow(theWindow, xpos, ypos, 0);
434 ShowWindow(theWindow);
Jack Jansene79dc762000-06-02 21:35:07 +0000435#endif
Jack Jansendf34cf11996-09-15 22:12:00 +0000436 DrawDialog(curdialog);
Jack Jansen04df9d51996-09-23 15:49:43 +0000437 }
Jack Jansendf34cf11996-09-15 22:12:00 +0000438 }
Jack Jansen2e871e41997-09-08 13:23:19 +0000439 if (olddialog)
440 DisposeDialog(olddialog);
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000441 Py_INCREF(Py_None);
442 return Py_None;
443}
444
Jack Janseneb76b841996-09-30 14:43:22 +0000445static char DebugStr_doc[] = "Switch to low-level debugger with a message";
446
447static PyObject *
448MacOS_DebugStr(PyObject *self, PyObject *args)
449{
450 Str255 message;
451 PyObject *object = 0;
452
453 if (!PyArg_ParseTuple(args, "O&|O", PyMac_GetStr255, message, &object))
454 return NULL;
455 DebugStr(message);
456 Py_INCREF(Py_None);
457 return Py_None;
458}
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000459
Jack Jansen2e871e41997-09-08 13:23:19 +0000460static char SysBeep_doc[] = "BEEEEEP!!!";
461
462static PyObject *
463MacOS_SysBeep(PyObject *self, PyObject *args)
464{
465 int duration = 6;
466
467 if (!PyArg_ParseTuple(args, "|i", &duration))
468 return NULL;
469 SysBeep(duration);
470 Py_INCREF(Py_None);
471 return Py_None;
472}
473
Jack Jansend7c17232003-02-21 16:31:11 +0000474static char WMAvailable_doc[] =
475 "True if this process can interact with the display."
476 "Will foreground the application on the first call as a side-effect."
477 ;
478
479static PyObject *
480MacOS_WMAvailable(PyObject *self, PyObject *args)
481{
482 static PyObject *rv = NULL;
483
484 if (!PyArg_ParseTuple(args, ""))
485 return NULL;
486 if (!rv) {
Jack Jansend7c17232003-02-21 16:31:11 +0000487 ProcessSerialNumber psn;
488
489 /*
490 ** This is a fairly innocuous call to make if we don't have a window
491 ** manager, or if we have no permission to talk to it. It will print
492 ** a message on stderr, but at least it won't abort the process.
493 ** It appears the function caches the result itself, and it's cheap, so
494 ** no need for us to cache.
495 */
Jack Jansen43285d42004-06-02 13:44:05 +0000496#ifdef kCGNullDirectDisplay
497 /* On 10.1 CGMainDisplayID() isn't available, and
498 ** kCGNullDirectDisplay isn't defined.
499 */
Jack Jansend7c17232003-02-21 16:31:11 +0000500 if (CGMainDisplayID() == 0) {
501 rv = Py_False;
502 } else {
Jack Jansen43285d42004-06-02 13:44:05 +0000503#else
504 {
505#endif
Jack Jansend7c17232003-02-21 16:31:11 +0000506 if (GetCurrentProcess(&psn) < 0 ||
507 SetFrontProcess(&psn) < 0) {
508 rv = Py_False;
509 } else {
510 rv = Py_True;
511 }
512 }
Jack Jansend7c17232003-02-21 16:31:11 +0000513 }
514 Py_INCREF(rv);
515 return rv;
516}
517
Jack Jansen898ac1b1997-09-01 15:38:12 +0000518static char GetTicks_doc[] = "Return number of ticks since bootup";
519
520static PyObject *
521MacOS_GetTicks(PyObject *self, PyObject *args)
522{
Jack Jansene79dc762000-06-02 21:35:07 +0000523 return Py_BuildValue("i", (int)TickCount());
Jack Jansen898ac1b1997-09-01 15:38:12 +0000524}
525
Jack Jansen76a05891996-02-29 16:11:32 +0000526static char openrf_doc[] = "Open resource fork of a file";
527
528static PyObject *
529MacOS_openrf(PyObject *self, PyObject *args)
530{
531 OSErr err;
532 char *mode = "r";
533 FSSpec fss;
534 SignedByte permission = 1;
535 rfobject *fp;
536
537 if (!PyArg_ParseTuple(args, "O&|s", PyMac_GetFSSpec, &fss, &mode))
538 return NULL;
539 while (*mode) {
540 switch (*mode++) {
541 case '*': break;
542 case 'r': permission = 1; break;
543 case 'w': permission = 2; break;
544 case 'b': break;
545 default:
546 PyErr_BadArgument();
547 return NULL;
548 }
549 }
550
551 if ( (fp = newrfobject()) == NULL )
552 return NULL;
553
554 err = HOpenRF(fss.vRefNum, fss.parID, fss.name, permission, &fp->fRefNum);
555
556 if ( err == fnfErr ) {
557 /* In stead of doing complicated things here to get creator/type
558 ** correct we let the standard i/o library handle it
559 */
560 FILE *tfp;
Jack Jansen697842f2001-09-10 22:00:39 +0000561 char pathname[PATHNAMELEN];
Jack Jansen76a05891996-02-29 16:11:32 +0000562
Jack Jansenb7348692002-12-23 23:16:25 +0000563 if ( (err=PyMac_GetFullPathname(&fss, pathname, PATHNAMELEN)) ) {
Jack Jansen76a05891996-02-29 16:11:32 +0000564 PyMac_Error(err);
565 Py_DECREF(fp);
566 return NULL;
567 }
568
569 if ( (tfp = fopen(pathname, "w")) == NULL ) {
570 PyMac_Error(fnfErr); /* What else... */
571 Py_DECREF(fp);
572 return NULL;
573 }
574 fclose(tfp);
575 err = HOpenRF(fss.vRefNum, fss.parID, fss.name, permission, &fp->fRefNum);
576 }
577 if ( err ) {
578 Py_DECREF(fp);
579 PyMac_Error(err);
580 return NULL;
581 }
582 fp->isclosed = 0;
583 return (PyObject *)fp;
584}
585
Jack Jansen8413b472000-10-19 22:02:16 +0000586
Guido van Rossum2d167031994-09-16 10:54:21 +0000587static PyMethodDef MacOS_Methods[] = {
Jack Jansen120a1051997-06-03 15:29:41 +0000588 {"GetCreatorAndType", MacOS_GetCreatorAndType, 1, getcrtp_doc},
589 {"SetCreatorAndType", MacOS_SetCreatorAndType, 1, setcrtp_doc},
Jack Jansen120a1051997-06-03 15:29:41 +0000590 {"GetErrorString", MacOS_GetErrorString, 1, geterr_doc},
591 {"openrf", MacOS_openrf, 1, openrf_doc},
592 {"splash", MacOS_splash, 1, splash_doc},
593 {"DebugStr", MacOS_DebugStr, 1, DebugStr_doc},
Jack Jansen898ac1b1997-09-01 15:38:12 +0000594 {"GetTicks", MacOS_GetTicks, 1, GetTicks_doc},
Jack Jansen2e871e41997-09-08 13:23:19 +0000595 {"SysBeep", MacOS_SysBeep, 1, SysBeep_doc},
Jack Jansend7c17232003-02-21 16:31:11 +0000596 {"WMAvailable", MacOS_WMAvailable, 1, WMAvailable_doc},
Guido van Rossumf74d4e21995-01-18 23:58:07 +0000597 {NULL, NULL} /* Sentinel */
Guido van Rossum2d167031994-09-16 10:54:21 +0000598};
599
600
601void
Jack Jansendeefbe52001-08-08 13:46:49 +0000602initMacOS(void)
Guido van Rossum2d167031994-09-16 10:54:21 +0000603{
604 PyObject *m, *d;
605
606 m = Py_InitModule("MacOS", MacOS_Methods);
607 d = PyModule_GetDict(m);
608
609 /* Initialize MacOS.Error exception */
Guido van Rossumbf068b11995-01-25 23:09:20 +0000610 MacOS_Error = PyMac_GetOSErrException();
Guido van Rossume433c971994-09-29 10:02:56 +0000611 if (MacOS_Error == NULL || PyDict_SetItemString(d, "Error", MacOS_Error) != 0)
Jack Jansenfa1e27d2000-09-08 10:21:44 +0000612 return;
Jack Jansena755e681997-09-20 17:40:22 +0000613 Rftype.ob_type = &PyType_Type;
614 Py_INCREF(&Rftype);
615 if (PyDict_SetItemString(d, "ResourceForkType", (PyObject *)&Rftype) != 0)
Jack Jansenfa1e27d2000-09-08 10:21:44 +0000616 return;
Jack Jansenf73bab71997-04-03 14:51:03 +0000617 /*
618 ** This is a hack: the following constant added to the id() of a string
619 ** object gives you the address of the data. Unfortunately, it is needed for
620 ** some of the image and sound processing interfaces on the mac:-(
621 */
622 {
623 PyStringObject *p = 0;
624 long off = (long)&(p->ob_sval[0]);
625
626 if( PyDict_SetItemString(d, "string_id_to_buffer", Py_BuildValue("i", off)) != 0)
Jack Jansenfa1e27d2000-09-08 10:21:44 +0000627 return;
Jack Jansenf73bab71997-04-03 14:51:03 +0000628 }
Jack Jansenf3163302001-05-19 12:50:05 +0000629#define PY_RUNTIMEMODEL "macho"
Jack Jansen193509b2001-01-23 22:38:23 +0000630 if (PyDict_SetItemString(d, "runtimemodel",
631 Py_BuildValue("s", PY_RUNTIMEMODEL)) != 0)
632 return;
Jack Jansena53f4eb2003-11-19 16:34:04 +0000633#if defined(WITH_NEXT_FRAMEWORK)
Jack Jansen8cd9a4f2003-02-23 23:23:47 +0000634#define PY_LINKMODEL "framework"
635#elif defined(Py_ENABLE_SHARED)
636#define PY_LINKMODEL "shared"
637#else
638#define PY_LINKMODEL "static"
639#endif
640 if (PyDict_SetItemString(d, "linkmodel",
641 Py_BuildValue("s", PY_LINKMODEL)) != 0)
642 return;
643
Guido van Rossum2d167031994-09-16 10:54:21 +0000644}