blob: bef7f88ceee8e620be990380326362a70c529ce0 [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
Ronald Oussoren0238497e2009-01-02 14:10:20 +000033#include <arpa/inet.h> /* for ntohl, htonl */
34
35
Ronald Oussorenaa8efbf2008-08-12 12:41:45 +000036#ifndef HAVE_OSX105_SDK
Ronald Oussoren0d236eb2008-06-06 21:31:33 +000037typedef SInt16 FSIORefNum;
38#endif
Ronald Oussoren5640ce22008-06-05 12:58:24 +000039
Guido van Rossum2d167031994-09-16 10:54:21 +000040static PyObject *MacOS_Error; /* Exception MacOS.Error */
41
Jack Jansen697842f2001-09-10 22:00:39 +000042#define PATHNAMELEN 1024
Jack Jansen697842f2001-09-10 22:00:39 +000043
Jack Jansen76a05891996-02-29 16:11:32 +000044/* ----------------------------------------------------- */
45
46/* Declarations for objects of type Resource fork */
47
48typedef struct {
49 PyObject_HEAD
Ronald Oussoren5640ce22008-06-05 12:58:24 +000050 FSIORefNum fRefNum;
Jack Jansen76a05891996-02-29 16:11:32 +000051 int isclosed;
52} rfobject;
53
Jeremy Hylton938ace62002-07-17 16:30:39 +000054static PyTypeObject Rftype;
Jack Jansen76a05891996-02-29 16:11:32 +000055
56
57
58/* ---------------------------------------------------------------- */
59
60static void
Jack Jansendeefbe52001-08-08 13:46:49 +000061do_close(rfobject *self)
Jack Jansen76a05891996-02-29 16:11:32 +000062{
63 if (self->isclosed ) return;
Ronald Oussoren5640ce22008-06-05 12:58:24 +000064 (void)FSCloseFork(self->fRefNum);
Jack Jansen76a05891996-02-29 16:11:32 +000065 self->isclosed = 1;
66}
67
68static char rf_read__doc__[] =
69"Read data from resource fork"
70;
71
72static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +000073rf_read(rfobject *self, PyObject *args)
Jack Jansen76a05891996-02-29 16:11:32 +000074{
75 long n;
76 PyObject *v;
77 OSErr err;
Ronald Oussoren5640ce22008-06-05 12:58:24 +000078 ByteCount n2;
Jack Jansen76a05891996-02-29 16:11:32 +000079
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
Christian Heimes593daf52008-05-26 12:51:38 +000088 v = PyBytes_FromStringAndSize((char *)NULL, n);
Jack Jansen76a05891996-02-29 16:11:32 +000089 if (v == NULL)
90 return NULL;
91
Ronald Oussoren5640ce22008-06-05 12:58:24 +000092 err = FSReadFork(self->fRefNum, fsAtMark, 0, n, PyString_AsString(v), &n2);
Jack Jansen76a05891996-02-29 16:11:32 +000093 if (err && err != eofErr) {
94 PyMac_Error(err);
95 Py_DECREF(v);
96 return NULL;
97 }
Ronald Oussoren5640ce22008-06-05 12:58:24 +000098 _PyString_Resize(&v, n2);
Jack Jansen76a05891996-02-29 16:11:32 +000099 return v;
100}
101
102
103static char rf_write__doc__[] =
104"Write to resource fork"
105;
106
107static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000108rf_write(rfobject *self, PyObject *args)
Jack Jansen76a05891996-02-29 16:11:32 +0000109{
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 }
Jack Janseneeccca91997-05-07 15:46:31 +0000118 if (!PyArg_ParseTuple(args, "s#", &buffer, &size))
Jack Jansen76a05891996-02-29 16:11:32 +0000119 return NULL;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000120 err = FSWriteFork(self->fRefNum, fsAtMark, 0, size, buffer, NULL);
Jack Jansen76a05891996-02-29 16:11:32 +0000121 if (err) {
122 PyMac_Error(err);
123 return NULL;
124 }
125 Py_INCREF(Py_None);
126 return Py_None;
127}
128
129
130static char rf_seek__doc__[] =
131"Set file position"
132;
133
134static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000135rf_seek(rfobject *self, PyObject *args)
Jack Jansen76a05891996-02-29 16:11:32 +0000136{
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000137 long amount;
Jack Jansen76a05891996-02-29 16:11:32 +0000138 int whence = SEEK_SET;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000139 int mode;
Jack Jansen76a05891996-02-29 16:11:32 +0000140 OSErr err;
141
142 if (self->isclosed) {
143 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
144 return NULL;
145 }
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000146 if (!PyArg_ParseTuple(args, "l|i", &amount, &whence)) {
Jack Jansen76a05891996-02-29 16:11:32 +0000147 return NULL;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000148 }
Jack Jansen76a05891996-02-29 16:11:32 +0000149
150 switch (whence) {
151 case SEEK_CUR:
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000152 mode = fsFromMark;
Jack Jansen76a05891996-02-29 16:11:32 +0000153 break;
154 case SEEK_END:
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000155 mode = fsFromLEOF;
Jack Jansen76a05891996-02-29 16:11:32 +0000156 break;
157 case SEEK_SET:
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000158 mode = fsFromStart;
Jack Jansen76a05891996-02-29 16:11:32 +0000159 break;
160 default:
161 PyErr_BadArgument();
162 return NULL;
163 }
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000164
165 err = FSSetForkPosition(self->fRefNum, mode, amount);
166 if (err != noErr) {
Jack Jansen76a05891996-02-29 16:11:32 +0000167 PyMac_Error(err);
168 return NULL;
169 }
170 Py_INCREF(Py_None);
171 return Py_None;
172}
173
174
175static char rf_tell__doc__[] =
176"Get file position"
177;
178
179static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000180rf_tell(rfobject *self, PyObject *args)
Jack Jansen76a05891996-02-29 16:11:32 +0000181{
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000182 long long where;
Jack Jansen76a05891996-02-29 16:11:32 +0000183 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;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000191
192 err = FSGetForkPosition(self->fRefNum, &where);
193 if (err != noErr) {
Jack Jansen76a05891996-02-29 16:11:32 +0000194 PyMac_Error(err);
195 return NULL;
196 }
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000197 return PyLong_FromLongLong(where);
Jack Jansen76a05891996-02-29 16:11:32 +0000198}
199
200static char rf_close__doc__[] =
201"Close resource fork"
202;
203
204static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000205rf_close(rfobject *self, PyObject *args)
Jack Jansen76a05891996-02-29 16:11:32 +0000206{
Jack Jansen76a05891996-02-29 16:11:32 +0000207 if (!PyArg_ParseTuple(args, ""))
208 return NULL;
209 do_close(self);
210 Py_INCREF(Py_None);
211 return Py_None;
212}
213
214
215static struct PyMethodDef rf_methods[] = {
Jack Jansendeefbe52001-08-08 13:46:49 +0000216 {"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__},
Jack Jansen76a05891996-02-29 16:11:32 +0000221
222 {NULL, NULL} /* sentinel */
223};
224
225/* ---------- */
226
227
228static rfobject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000229newrfobject(void)
Jack Jansen76a05891996-02-29 16:11:32 +0000230{
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
241static void
Jack Jansendeefbe52001-08-08 13:46:49 +0000242rf_dealloc(rfobject *self)
Jack Jansen76a05891996-02-29 16:11:32 +0000243{
244 do_close(self);
Jack Jansen0e2f7982002-05-22 14:31:48 +0000245 PyObject_DEL(self);
Jack Jansen76a05891996-02-29 16:11:32 +0000246}
247
248static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000249rf_getattr(rfobject *self, char *name)
Jack Jansen76a05891996-02-29 16:11:32 +0000250{
251 return Py_FindMethod(rf_methods, (PyObject *)self, name);
252}
253
254static char Rftype__doc__[] =
255"Resource fork file object"
256;
257
258static PyTypeObject Rftype = {
259 PyObject_HEAD_INIT(&PyType_Type)
260 0, /*ob_size*/
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
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000283
Jack Jansen76a05891996-02-29 16:11:32 +0000284/* 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{
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000295 PyObject *creator, *type, *res;
Guido van Rossume791c2e1995-01-09 13:20:04 +0000296 OSErr err;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000297 FSRef ref;
298 FSCatalogInfo cataloginfo;
299 FileInfo* finfo;
300
301 if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSRef, &ref)) {
302#ifndef __LP64__
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 }
Ronald Oussoren0238497e2009-01-02 14:10:20 +0000316
317 info.fdCreator = ntohl(info.fdCreator);
318 info.fdType = ntohl(info.fdType);
319
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000320 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 /* __LP64__ */
Guido van Rossume791c2e1995-01-09 13:20:04 +0000328 return NULL;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000329#endif /* __LP64__ */
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);
Ronald Oussoren0238497e2009-01-02 14:10:20 +0000351 finfo->fileCreator = ntohl(finfo->fileCreator);
352 finfo->fileType = ntohl(finfo->fileType);
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000353 creator = PyString_FromStringAndSize((char*)&(finfo->fileCreator), 4);
354 type = PyString_FromStringAndSize((char*)&(finfo->fileType), 4);
355
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000356 res = Py_BuildValue("OO", creator, type);
Guido van Rossumfffb8bb1995-01-12 12:37:24 +0000357 Py_DECREF(creator);
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000358 Py_DECREF(type);
Guido van Rossume791c2e1995-01-09 13:20:04 +0000359 return res;
360}
361
Jack Jansenfe94e972003-03-19 22:51:42 +0000362static char setcrtp_doc[] = "Set MacOS 4-char creator and type for a file";
Jack Jansen120a1051997-06-03 15:29:41 +0000363
Guido van Rossume791c2e1995-01-09 13:20:04 +0000364static PyObject *
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000365MacOS_SetCreatorAndType(PyObject *self, PyObject *args)
Guido van Rossume791c2e1995-01-09 13:20:04 +0000366{
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000367 ResType creator, type;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000368 FSRef ref;
369 FileInfo* finfo;
Guido van Rossume791c2e1995-01-09 13:20:04 +0000370 OSErr err;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000371 FSCatalogInfo cataloginfo;
372
Guido van Rossume791c2e1995-01-09 13:20:04 +0000373 if (!PyArg_ParseTuple(args, "O&O&O&",
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000374 PyMac_GetFSRef, &ref, PyMac_GetOSType, &creator, PyMac_GetOSType, &type)) {
375#ifndef __LP64__
376 /* Try to handle FSSpec arguments, for backward compatibility */
377 FSSpec fss;
378 FInfo info;
379
380 if (!PyArg_ParseTuple(args, "O&O&O&",
Jack Jansene79dc762000-06-02 21:35:07 +0000381 PyMac_GetFSSpec, &fss, PyMac_GetOSType, &creator, PyMac_GetOSType, &type))
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000382 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 /* __LP64__ */
Guido van Rossume791c2e1995-01-09 13:20:04 +0000395 return NULL;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000396#endif /* __LP64__ */
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
Guido van Rossume791c2e1995-01-09 13:20:04 +0000427 Py_INCREF(Py_None);
428 return Py_None;
429}
430
Jack Jansena76382a1995-02-02 14:25:56 +0000431
Jack Jansen120a1051997-06-03 15:29:41 +0000432static char geterr_doc[] = "Convert OSErr number to string";
433
Jack Jansen829f88c1995-07-17 11:36:01 +0000434static PyObject *
435MacOS_GetErrorString(PyObject *self, PyObject *args)
436{
Raymond Hettingerec6eb362004-11-05 07:02:59 +0000437 int err;
438 char buf[256];
439 Handle h;
440 char *str;
441 static int errors_loaded;
Jack Jansen829f88c1995-07-17 11:36:01 +0000442
Raymond Hettingerec6eb362004-11-05 07:02:59 +0000443 if (!PyArg_ParseTuple(args, "i", &err))
Jack Jansen829f88c1995-07-17 11:36:01 +0000444 return NULL;
Raymond Hettingerec6eb362004-11-05 07:02:59 +0000445
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
Christian Heimes000a0742008-01-03 22:16:32 +0000456 m = PyImport_ImportModuleNoBlock("macresource");
Raymond Hettingerec6eb362004-11-05 07:02:59 +0000457 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 }
Thomas Hellerdd827342006-07-11 16:42:05 +0000474 Py_DECREF(m);
Raymond Hettingerec6eb362004-11-05 07:02:59 +0000475 }
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);
Jack Jansen829f88c1995-07-17 11:36:01 +0000496}
497
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000498
499#ifndef __LP64__
500
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000501static char splash_doc[] = "Open a splash-screen dialog by resource-id (0=close)";
502
503static PyObject *
504MacOS_splash(PyObject *self, PyObject *args)
505{
Jack Jansendf34cf11996-09-15 22:12:00 +0000506 int resid = -1;
Jack Jansen450ae9f1997-05-13 15:41:48 +0000507 static DialogPtr curdialog = NULL;
Jack Jansen2e871e41997-09-08 13:23:19 +0000508 DialogPtr olddialog;
Jack Jansen04df9d51996-09-23 15:49:43 +0000509 WindowRef theWindow;
510 CGrafPtr thePort;
Jack Jansene79dc762000-06-02 21:35:07 +0000511#if 0
Jack Jansen04df9d51996-09-23 15:49:43 +0000512 short xpos, ypos, width, height, swidth, sheight;
Jack Jansene79dc762000-06-02 21:35:07 +0000513#endif
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000514
Jack Jansendf34cf11996-09-15 22:12:00 +0000515 if (!PyArg_ParseTuple(args, "|i", &resid))
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000516 return NULL;
Jack Jansen2e871e41997-09-08 13:23:19 +0000517 olddialog = curdialog;
Jack Jansencbe6a531998-02-20 15:59:59 +0000518 curdialog = NULL;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000519
Jack Jansendf34cf11996-09-15 22:12:00 +0000520 if ( resid != -1 ) {
521 curdialog = GetNewDialog(resid, NULL, (WindowPtr)-1);
Jack Jansen04df9d51996-09-23 15:49:43 +0000522 if ( curdialog ) {
523 theWindow = GetDialogWindow(curdialog);
524 thePort = GetWindowPort(theWindow);
Jack Jansene79dc762000-06-02 21:35:07 +0000525#if 0
Jack Jansen04df9d51996-09-23 15:49:43 +0000526 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);
Jack Jansene79dc762000-06-02 21:35:07 +0000534#endif
Jack Jansendf34cf11996-09-15 22:12:00 +0000535 DrawDialog(curdialog);
Jack Jansen04df9d51996-09-23 15:49:43 +0000536 }
Jack Jansendf34cf11996-09-15 22:12:00 +0000537 }
Jack Jansen2e871e41997-09-08 13:23:19 +0000538 if (olddialog)
539 DisposeDialog(olddialog);
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000540 Py_INCREF(Py_None);
541 return Py_None;
542}
543
Jack Janseneb76b841996-09-30 14:43:22 +0000544static char DebugStr_doc[] = "Switch to low-level debugger with a message";
545
546static PyObject *
547MacOS_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;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000554
Jack Janseneb76b841996-09-30 14:43:22 +0000555 DebugStr(message);
556 Py_INCREF(Py_None);
557 return Py_None;
558}
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000559
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000560
Jack Jansen2e871e41997-09-08 13:23:19 +0000561static char SysBeep_doc[] = "BEEEEEP!!!";
562
563static PyObject *
564MacOS_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
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000575#endif /* __LP64__ */
576
Jack Jansend7c17232003-02-21 16:31:11 +0000577static 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
582static PyObject *
583MacOS_WMAvailable(PyObject *self, PyObject *args)
584{
585 static PyObject *rv = NULL;
586
587 if (!PyArg_ParseTuple(args, ""))
588 return NULL;
589 if (!rv) {
Jack Jansend7c17232003-02-21 16:31:11 +0000590 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 */
Jack Jansen43285d42004-06-02 13:44:05 +0000599#ifdef kCGNullDirectDisplay
600 /* On 10.1 CGMainDisplayID() isn't available, and
601 ** kCGNullDirectDisplay isn't defined.
602 */
Jack Jansend7c17232003-02-21 16:31:11 +0000603 if (CGMainDisplayID() == 0) {
604 rv = Py_False;
605 } else {
Jack Jansen43285d42004-06-02 13:44:05 +0000606#else
607 {
608#endif
Jack Jansend7c17232003-02-21 16:31:11 +0000609 if (GetCurrentProcess(&psn) < 0 ||
610 SetFrontProcess(&psn) < 0) {
611 rv = Py_False;
612 } else {
613 rv = Py_True;
614 }
615 }
Jack Jansend7c17232003-02-21 16:31:11 +0000616 }
617 Py_INCREF(rv);
618 return rv;
619}
620
Jack Jansen898ac1b1997-09-01 15:38:12 +0000621static char GetTicks_doc[] = "Return number of ticks since bootup";
622
623static PyObject *
624MacOS_GetTicks(PyObject *self, PyObject *args)
625{
Jack Jansene79dc762000-06-02 21:35:07 +0000626 return Py_BuildValue("i", (int)TickCount());
Jack Jansen898ac1b1997-09-01 15:38:12 +0000627}
628
Jack Jansen76a05891996-02-29 16:11:32 +0000629static char openrf_doc[] = "Open resource fork of a file";
630
631static PyObject *
632MacOS_openrf(PyObject *self, PyObject *args)
633{
634 OSErr err;
635 char *mode = "r";
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000636 FSRef ref;
637 SInt8 permission = fsRdPerm;
Jack Jansen76a05891996-02-29 16:11:32 +0000638 rfobject *fp;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000639 HFSUniStr255 name;
Jack Jansen76a05891996-02-29 16:11:32 +0000640
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000641 if (!PyArg_ParseTuple(args, "O&|s", PyMac_GetFSRef, &ref, &mode))
Jack Jansen76a05891996-02-29 16:11:32 +0000642 return NULL;
643 while (*mode) {
644 switch (*mode++) {
645 case '*': break;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000646 case 'r': permission = fsRdPerm; break;
647 case 'w': permission = fsWrPerm; break;
Jack Jansen76a05891996-02-29 16:11:32 +0000648 case 'b': break;
649 default:
650 PyErr_BadArgument();
651 return NULL;
652 }
653 }
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000654
655 err = FSGetResourceForkName(&name);
656 if (err != noErr) {
657 PyMac_Error(err);
658 return NULL;
659 }
Jack Jansen76a05891996-02-29 16:11:32 +0000660
661 if ( (fp = newrfobject()) == NULL )
662 return NULL;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000663
Jack Jansen76a05891996-02-29 16:11:32 +0000664
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000665 err = FSOpenFork(&ref, name.length, name.unicode, permission, &fp->fRefNum);
666 if (err != noErr) {
Jack Jansen76a05891996-02-29 16:11:32 +0000667 Py_DECREF(fp);
668 PyMac_Error(err);
669 return NULL;
670 }
671 fp->isclosed = 0;
672 return (PyObject *)fp;
673}
674
Jack Jansen8413b472000-10-19 22:02:16 +0000675
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000676
Guido van Rossum2d167031994-09-16 10:54:21 +0000677static PyMethodDef MacOS_Methods[] = {
Jack Jansen120a1051997-06-03 15:29:41 +0000678 {"GetCreatorAndType", MacOS_GetCreatorAndType, 1, getcrtp_doc},
679 {"SetCreatorAndType", MacOS_SetCreatorAndType, 1, setcrtp_doc},
Jack Jansen120a1051997-06-03 15:29:41 +0000680 {"GetErrorString", MacOS_GetErrorString, 1, geterr_doc},
681 {"openrf", MacOS_openrf, 1, openrf_doc},
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000682#ifndef __LP64__
Jack Jansen120a1051997-06-03 15:29:41 +0000683 {"splash", MacOS_splash, 1, splash_doc},
684 {"DebugStr", MacOS_DebugStr, 1, DebugStr_doc},
Jack Jansen2e871e41997-09-08 13:23:19 +0000685 {"SysBeep", MacOS_SysBeep, 1, SysBeep_doc},
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000686#endif /* __LP64__ */
687 {"GetTicks", MacOS_GetTicks, 1, GetTicks_doc},
Jack Jansend7c17232003-02-21 16:31:11 +0000688 {"WMAvailable", MacOS_WMAvailable, 1, WMAvailable_doc},
Guido van Rossumf74d4e21995-01-18 23:58:07 +0000689 {NULL, NULL} /* Sentinel */
Guido van Rossum2d167031994-09-16 10:54:21 +0000690};
691
692
693void
Jack Jansendeefbe52001-08-08 13:46:49 +0000694initMacOS(void)
Guido van Rossum2d167031994-09-16 10:54:21 +0000695{
696 PyObject *m, *d;
697
Benjamin Peterson23681932008-05-12 21:42:13 +0000698 if (PyErr_WarnPy3k("In 3.x, MacOS is removed.", 1))
699 return;
700
Guido van Rossum2d167031994-09-16 10:54:21 +0000701 m = Py_InitModule("MacOS", MacOS_Methods);
702 d = PyModule_GetDict(m);
703
704 /* Initialize MacOS.Error exception */
Guido van Rossumbf068b11995-01-25 23:09:20 +0000705 MacOS_Error = PyMac_GetOSErrException();
Guido van Rossume433c971994-09-29 10:02:56 +0000706 if (MacOS_Error == NULL || PyDict_SetItemString(d, "Error", MacOS_Error) != 0)
Jack Jansenfa1e27d2000-09-08 10:21:44 +0000707 return;
Jack Jansena755e681997-09-20 17:40:22 +0000708 Rftype.ob_type = &PyType_Type;
709 Py_INCREF(&Rftype);
710 if (PyDict_SetItemString(d, "ResourceForkType", (PyObject *)&Rftype) != 0)
Jack Jansenfa1e27d2000-09-08 10:21:44 +0000711 return;
Jack Jansenf73bab71997-04-03 14:51:03 +0000712 /*
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 {
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000718 PyStringObject *p = 0;
Jack Jansenf73bab71997-04-03 14:51:03 +0000719 long off = (long)&(p->ob_sval[0]);
720
721 if( PyDict_SetItemString(d, "string_id_to_buffer", Py_BuildValue("i", off)) != 0)
Jack Jansenfa1e27d2000-09-08 10:21:44 +0000722 return;
Jack Jansenf73bab71997-04-03 14:51:03 +0000723 }
Jack Jansenf3163302001-05-19 12:50:05 +0000724#define PY_RUNTIMEMODEL "macho"
Jack Jansen193509b2001-01-23 22:38:23 +0000725 if (PyDict_SetItemString(d, "runtimemodel",
726 Py_BuildValue("s", PY_RUNTIMEMODEL)) != 0)
727 return;
Jack Jansena53f4eb2003-11-19 16:34:04 +0000728#if defined(WITH_NEXT_FRAMEWORK)
Jack Jansen8cd9a4f2003-02-23 23:23:47 +0000729#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
Guido van Rossum2d167031994-09-16 10:54:21 +0000739}