blob: 272fe8d55d9292791786cf7d5d4139b29fe1959e [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 Oussorenaa8efbf2008-08-12 12:41:45 +000033#ifndef HAVE_OSX105_SDK
Ronald Oussoren0d236eb2008-06-06 21:31:33 +000034typedef SInt16 FSIORefNum;
35#endif
Ronald Oussoren5640ce22008-06-05 12:58:24 +000036
Guido van Rossum2d167031994-09-16 10:54:21 +000037static PyObject *MacOS_Error; /* Exception MacOS.Error */
38
Jack Jansen697842f2001-09-10 22:00:39 +000039#define PATHNAMELEN 1024
Jack Jansen697842f2001-09-10 22:00:39 +000040
Jack Jansen76a05891996-02-29 16:11:32 +000041/* ----------------------------------------------------- */
42
43/* Declarations for objects of type Resource fork */
44
45typedef struct {
46 PyObject_HEAD
Ronald Oussoren5640ce22008-06-05 12:58:24 +000047 FSIORefNum fRefNum;
Jack Jansen76a05891996-02-29 16:11:32 +000048 int isclosed;
49} rfobject;
50
Jeremy Hylton938ace62002-07-17 16:30:39 +000051static PyTypeObject Rftype;
Jack Jansen76a05891996-02-29 16:11:32 +000052
53
54
55/* ---------------------------------------------------------------- */
56
57static void
Jack Jansendeefbe52001-08-08 13:46:49 +000058do_close(rfobject *self)
Jack Jansen76a05891996-02-29 16:11:32 +000059{
60 if (self->isclosed ) return;
Ronald Oussoren5640ce22008-06-05 12:58:24 +000061 (void)FSCloseFork(self->fRefNum);
Jack Jansen76a05891996-02-29 16:11:32 +000062 self->isclosed = 1;
63}
64
65static char rf_read__doc__[] =
66"Read data from resource fork"
67;
68
69static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +000070rf_read(rfobject *self, PyObject *args)
Jack Jansen76a05891996-02-29 16:11:32 +000071{
72 long n;
73 PyObject *v;
74 OSErr err;
Ronald Oussoren5640ce22008-06-05 12:58:24 +000075 ByteCount n2;
Jack Jansen76a05891996-02-29 16:11:32 +000076
77 if (self->isclosed) {
78 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
79 return NULL;
80 }
81
82 if (!PyArg_ParseTuple(args, "l", &n))
83 return NULL;
84
Christian Heimes593daf52008-05-26 12:51:38 +000085 v = PyBytes_FromStringAndSize((char *)NULL, n);
Jack Jansen76a05891996-02-29 16:11:32 +000086 if (v == NULL)
87 return NULL;
88
Ronald Oussoren5640ce22008-06-05 12:58:24 +000089 err = FSReadFork(self->fRefNum, fsAtMark, 0, n, PyString_AsString(v), &n2);
Jack Jansen76a05891996-02-29 16:11:32 +000090 if (err && err != eofErr) {
91 PyMac_Error(err);
92 Py_DECREF(v);
93 return NULL;
94 }
Ronald Oussoren5640ce22008-06-05 12:58:24 +000095 _PyString_Resize(&v, n2);
Jack Jansen76a05891996-02-29 16:11:32 +000096 return v;
97}
98
99
100static char rf_write__doc__[] =
101"Write to resource fork"
102;
103
104static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000105rf_write(rfobject *self, PyObject *args)
Jack Jansen76a05891996-02-29 16:11:32 +0000106{
107 char *buffer;
108 long size;
109 OSErr err;
110
111 if (self->isclosed) {
112 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
113 return NULL;
114 }
Jack Janseneeccca91997-05-07 15:46:31 +0000115 if (!PyArg_ParseTuple(args, "s#", &buffer, &size))
Jack Jansen76a05891996-02-29 16:11:32 +0000116 return NULL;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000117 err = FSWriteFork(self->fRefNum, fsAtMark, 0, size, buffer, NULL);
Jack Jansen76a05891996-02-29 16:11:32 +0000118 if (err) {
119 PyMac_Error(err);
120 return NULL;
121 }
122 Py_INCREF(Py_None);
123 return Py_None;
124}
125
126
127static char rf_seek__doc__[] =
128"Set file position"
129;
130
131static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000132rf_seek(rfobject *self, PyObject *args)
Jack Jansen76a05891996-02-29 16:11:32 +0000133{
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000134 long amount;
Jack Jansen76a05891996-02-29 16:11:32 +0000135 int whence = SEEK_SET;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000136 int mode;
Jack Jansen76a05891996-02-29 16:11:32 +0000137 OSErr err;
138
139 if (self->isclosed) {
140 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
141 return NULL;
142 }
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000143 if (!PyArg_ParseTuple(args, "l|i", &amount, &whence)) {
Jack Jansen76a05891996-02-29 16:11:32 +0000144 return NULL;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000145 }
Jack Jansen76a05891996-02-29 16:11:32 +0000146
147 switch (whence) {
148 case SEEK_CUR:
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000149 mode = fsFromMark;
Jack Jansen76a05891996-02-29 16:11:32 +0000150 break;
151 case SEEK_END:
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000152 mode = fsFromLEOF;
Jack Jansen76a05891996-02-29 16:11:32 +0000153 break;
154 case SEEK_SET:
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000155 mode = fsFromStart;
Jack Jansen76a05891996-02-29 16:11:32 +0000156 break;
157 default:
158 PyErr_BadArgument();
159 return NULL;
160 }
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000161
162 err = FSSetForkPosition(self->fRefNum, mode, amount);
163 if (err != noErr) {
Jack Jansen76a05891996-02-29 16:11:32 +0000164 PyMac_Error(err);
165 return NULL;
166 }
167 Py_INCREF(Py_None);
168 return Py_None;
169}
170
171
172static char rf_tell__doc__[] =
173"Get file position"
174;
175
176static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000177rf_tell(rfobject *self, PyObject *args)
Jack Jansen76a05891996-02-29 16:11:32 +0000178{
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000179 long long where;
Jack Jansen76a05891996-02-29 16:11:32 +0000180 OSErr err;
181
182 if (self->isclosed) {
183 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
184 return NULL;
185 }
186 if (!PyArg_ParseTuple(args, ""))
187 return NULL;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000188
189 err = FSGetForkPosition(self->fRefNum, &where);
190 if (err != noErr) {
Jack Jansen76a05891996-02-29 16:11:32 +0000191 PyMac_Error(err);
192 return NULL;
193 }
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000194 return PyLong_FromLongLong(where);
Jack Jansen76a05891996-02-29 16:11:32 +0000195}
196
197static char rf_close__doc__[] =
198"Close resource fork"
199;
200
201static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000202rf_close(rfobject *self, PyObject *args)
Jack Jansen76a05891996-02-29 16:11:32 +0000203{
Jack Jansen76a05891996-02-29 16:11:32 +0000204 if (!PyArg_ParseTuple(args, ""))
205 return NULL;
206 do_close(self);
207 Py_INCREF(Py_None);
208 return Py_None;
209}
210
211
212static struct PyMethodDef rf_methods[] = {
Jack Jansendeefbe52001-08-08 13:46:49 +0000213 {"read", (PyCFunction)rf_read, 1, rf_read__doc__},
214 {"write", (PyCFunction)rf_write, 1, rf_write__doc__},
215 {"seek", (PyCFunction)rf_seek, 1, rf_seek__doc__},
216 {"tell", (PyCFunction)rf_tell, 1, rf_tell__doc__},
217 {"close", (PyCFunction)rf_close, 1, rf_close__doc__},
Jack Jansen76a05891996-02-29 16:11:32 +0000218
219 {NULL, NULL} /* sentinel */
220};
221
222/* ---------- */
223
224
225static rfobject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000226newrfobject(void)
Jack Jansen76a05891996-02-29 16:11:32 +0000227{
228 rfobject *self;
229
230 self = PyObject_NEW(rfobject, &Rftype);
231 if (self == NULL)
232 return NULL;
233 self->isclosed = 1;
234 return self;
235}
236
237
238static void
Jack Jansendeefbe52001-08-08 13:46:49 +0000239rf_dealloc(rfobject *self)
Jack Jansen76a05891996-02-29 16:11:32 +0000240{
241 do_close(self);
Jack Jansen0e2f7982002-05-22 14:31:48 +0000242 PyObject_DEL(self);
Jack Jansen76a05891996-02-29 16:11:32 +0000243}
244
245static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000246rf_getattr(rfobject *self, char *name)
Jack Jansen76a05891996-02-29 16:11:32 +0000247{
248 return Py_FindMethod(rf_methods, (PyObject *)self, name);
249}
250
251static char Rftype__doc__[] =
252"Resource fork file object"
253;
254
255static PyTypeObject Rftype = {
256 PyObject_HEAD_INIT(&PyType_Type)
257 0, /*ob_size*/
Guido van Rossum14648392001-12-08 18:02:58 +0000258 "MacOS.ResourceFork", /*tp_name*/
Jack Jansen76a05891996-02-29 16:11:32 +0000259 sizeof(rfobject), /*tp_basicsize*/
260 0, /*tp_itemsize*/
261 /* methods */
262 (destructor)rf_dealloc, /*tp_dealloc*/
263 (printfunc)0, /*tp_print*/
264 (getattrfunc)rf_getattr, /*tp_getattr*/
265 (setattrfunc)0, /*tp_setattr*/
266 (cmpfunc)0, /*tp_compare*/
267 (reprfunc)0, /*tp_repr*/
268 0, /*tp_as_number*/
269 0, /*tp_as_sequence*/
270 0, /*tp_as_mapping*/
271 (hashfunc)0, /*tp_hash*/
272 (ternaryfunc)0, /*tp_call*/
273 (reprfunc)0, /*tp_str*/
274
275 /* Space for future expansion */
276 0L,0L,0L,0L,
277 Rftype__doc__ /* Documentation string */
278};
279
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000280
Jack Jansen76a05891996-02-29 16:11:32 +0000281/* End of code for Resource fork objects */
282/* -------------------------------------------------------- */
Guido van Rossum2d167031994-09-16 10:54:21 +0000283
284/*----------------------------------------------------------------------*/
Guido van Rossume791c2e1995-01-09 13:20:04 +0000285/* Miscellaneous File System Operations */
286
Jack Jansenfe94e972003-03-19 22:51:42 +0000287static char getcrtp_doc[] = "Get MacOS 4-char creator and type for a file";
Jack Jansen120a1051997-06-03 15:29:41 +0000288
Guido van Rossume791c2e1995-01-09 13:20:04 +0000289static PyObject *
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000290MacOS_GetCreatorAndType(PyObject *self, PyObject *args)
Guido van Rossume791c2e1995-01-09 13:20:04 +0000291{
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000292 PyObject *creator, *type, *res;
Guido van Rossume791c2e1995-01-09 13:20:04 +0000293 OSErr err;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000294 FSRef ref;
295 FSCatalogInfo cataloginfo;
296 FileInfo* finfo;
297
298 if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSRef, &ref)) {
299#ifndef __LP64__
300 /* This function is documented to take an FSSpec as well,
301 * which only works in 32-bit mode.
302 */
303 PyErr_Clear();
304 FSSpec fss;
305 FInfo info;
306
307 if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSSpec, &fss))
308 return NULL;
309
310 if ((err = FSpGetFInfo(&fss, &info)) != noErr) {
311 return PyErr_Mac(MacOS_Error, err);
312 }
313 creator = PyString_FromStringAndSize(
314 (char *)&info.fdCreator, 4);
315 type = PyString_FromStringAndSize((char *)&info.fdType, 4);
316 res = Py_BuildValue("OO", creator, type);
317 Py_DECREF(creator);
318 Py_DECREF(type);
319 return res;
320#else /* __LP64__ */
Guido van Rossume791c2e1995-01-09 13:20:04 +0000321 return NULL;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000322#endif /* __LP64__ */
323 }
324
325 err = FSGetCatalogInfo(&ref,
326 kFSCatInfoFinderInfo|kFSCatInfoNodeFlags, &cataloginfo,
327 NULL, NULL, NULL);
328 if (err != noErr) {
329 PyErr_Mac(MacOS_Error, err);
330 return NULL;
331 }
332
333 if ((cataloginfo.nodeFlags & kFSNodeIsDirectoryMask) != 0) {
334 /* Directory: doesn't have type/creator info.
335 *
336 * The specific error code is for backward compatibility with
337 * earlier versions.
338 */
339 PyErr_Mac(MacOS_Error, fnfErr);
340 return NULL;
341
342 }
343 finfo = (FileInfo*)&(cataloginfo.finderInfo);
344 creator = PyString_FromStringAndSize((char*)&(finfo->fileCreator), 4);
345 type = PyString_FromStringAndSize((char*)&(finfo->fileType), 4);
346
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000347 res = Py_BuildValue("OO", creator, type);
Guido van Rossumfffb8bb1995-01-12 12:37:24 +0000348 Py_DECREF(creator);
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000349 Py_DECREF(type);
Guido van Rossume791c2e1995-01-09 13:20:04 +0000350 return res;
351}
352
Jack Jansenfe94e972003-03-19 22:51:42 +0000353static char setcrtp_doc[] = "Set MacOS 4-char creator and type for a file";
Jack Jansen120a1051997-06-03 15:29:41 +0000354
Guido van Rossume791c2e1995-01-09 13:20:04 +0000355static PyObject *
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000356MacOS_SetCreatorAndType(PyObject *self, PyObject *args)
Guido van Rossume791c2e1995-01-09 13:20:04 +0000357{
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000358 ResType creator, type;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000359 FSRef ref;
360 FileInfo* finfo;
Guido van Rossume791c2e1995-01-09 13:20:04 +0000361 OSErr err;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000362 FSCatalogInfo cataloginfo;
363
Guido van Rossume791c2e1995-01-09 13:20:04 +0000364 if (!PyArg_ParseTuple(args, "O&O&O&",
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000365 PyMac_GetFSRef, &ref, PyMac_GetOSType, &creator, PyMac_GetOSType, &type)) {
366#ifndef __LP64__
367 /* Try to handle FSSpec arguments, for backward compatibility */
368 FSSpec fss;
369 FInfo info;
370
371 if (!PyArg_ParseTuple(args, "O&O&O&",
Jack Jansene79dc762000-06-02 21:35:07 +0000372 PyMac_GetFSSpec, &fss, PyMac_GetOSType, &creator, PyMac_GetOSType, &type))
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000373 return NULL;
374
375 if ((err = FSpGetFInfo(&fss, &info)) != noErr)
376 return PyErr_Mac(MacOS_Error, err);
377
378 info.fdCreator = creator;
379 info.fdType = type;
380
381 if ((err = FSpSetFInfo(&fss, &info)) != noErr)
382 return PyErr_Mac(MacOS_Error, err);
383 Py_INCREF(Py_None);
384 return Py_None;
385#else /* __LP64__ */
Guido van Rossume791c2e1995-01-09 13:20:04 +0000386 return NULL;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000387#endif /* __LP64__ */
388 }
389
390 err = FSGetCatalogInfo(&ref,
391 kFSCatInfoFinderInfo|kFSCatInfoNodeFlags, &cataloginfo,
392 NULL, NULL, NULL);
393 if (err != noErr) {
394 PyErr_Mac(MacOS_Error, err);
395 return NULL;
396 }
397
398 if ((cataloginfo.nodeFlags & kFSNodeIsDirectoryMask) != 0) {
399 /* Directory: doesn't have type/creator info.
400 *
401 * The specific error code is for backward compatibility with
402 * earlier versions.
403 */
404 PyErr_Mac(MacOS_Error, fnfErr);
405 return NULL;
406
407 }
408 finfo = (FileInfo*)&(cataloginfo.finderInfo);
409 finfo->fileCreator = creator;
410 finfo->fileType = type;
411
412 err = FSSetCatalogInfo(&ref, kFSCatInfoFinderInfo, &cataloginfo);
413 if (err != noErr) {
414 PyErr_Mac(MacOS_Error, fnfErr);
415 return NULL;
416 }
417
Guido van Rossume791c2e1995-01-09 13:20:04 +0000418 Py_INCREF(Py_None);
419 return Py_None;
420}
421
Jack Jansena76382a1995-02-02 14:25:56 +0000422
Jack Jansen120a1051997-06-03 15:29:41 +0000423static char geterr_doc[] = "Convert OSErr number to string";
424
Jack Jansen829f88c1995-07-17 11:36:01 +0000425static PyObject *
426MacOS_GetErrorString(PyObject *self, PyObject *args)
427{
Raymond Hettingerec6eb362004-11-05 07:02:59 +0000428 int err;
429 char buf[256];
430 Handle h;
431 char *str;
432 static int errors_loaded;
Jack Jansen829f88c1995-07-17 11:36:01 +0000433
Raymond Hettingerec6eb362004-11-05 07:02:59 +0000434 if (!PyArg_ParseTuple(args, "i", &err))
Jack Jansen829f88c1995-07-17 11:36:01 +0000435 return NULL;
Raymond Hettingerec6eb362004-11-05 07:02:59 +0000436
437 h = GetResource('Estr', err);
438 if (!h && !errors_loaded) {
439 /*
440 ** Attempt to open the resource file containing the
441 ** Estr resources. We ignore all errors. We also try
442 ** this only once.
443 */
444 PyObject *m, *rv;
445 errors_loaded = 1;
446
Christian Heimes000a0742008-01-03 22:16:32 +0000447 m = PyImport_ImportModuleNoBlock("macresource");
Raymond Hettingerec6eb362004-11-05 07:02:59 +0000448 if (!m) {
449 if (Py_VerboseFlag)
450 PyErr_Print();
451 PyErr_Clear();
452 }
453 else {
454 rv = PyObject_CallMethod(m, "open_error_resource", "");
455 if (!rv) {
456 if (Py_VerboseFlag)
457 PyErr_Print();
458 PyErr_Clear();
459 }
460 else {
461 Py_DECREF(rv);
462 /* And try again... */
463 h = GetResource('Estr', err);
464 }
Thomas Hellerdd827342006-07-11 16:42:05 +0000465 Py_DECREF(m);
Raymond Hettingerec6eb362004-11-05 07:02:59 +0000466 }
467 }
468 /*
469 ** Whether the code above succeeded or not, we won't try
470 ** again.
471 */
472 errors_loaded = 1;
473
474 if (h) {
475 HLock(h);
476 str = (char *)*h;
477 memcpy(buf, str+1, (unsigned char)str[0]);
478 buf[(unsigned char)str[0]] = '\0';
479 HUnlock(h);
480 ReleaseResource(h);
481 }
482 else {
483 PyOS_snprintf(buf, sizeof(buf), "Mac OS error code %d", err);
484 }
485
486 return Py_BuildValue("s", buf);
Jack Jansen829f88c1995-07-17 11:36:01 +0000487}
488
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000489
490#ifndef __LP64__
491
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000492static char splash_doc[] = "Open a splash-screen dialog by resource-id (0=close)";
493
494static PyObject *
495MacOS_splash(PyObject *self, PyObject *args)
496{
Jack Jansendf34cf11996-09-15 22:12:00 +0000497 int resid = -1;
Jack Jansen450ae9f1997-05-13 15:41:48 +0000498 static DialogPtr curdialog = NULL;
Jack Jansen2e871e41997-09-08 13:23:19 +0000499 DialogPtr olddialog;
Jack Jansen04df9d51996-09-23 15:49:43 +0000500 WindowRef theWindow;
501 CGrafPtr thePort;
Jack Jansene79dc762000-06-02 21:35:07 +0000502#if 0
Jack Jansen04df9d51996-09-23 15:49:43 +0000503 short xpos, ypos, width, height, swidth, sheight;
Jack Jansene79dc762000-06-02 21:35:07 +0000504#endif
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000505
Jack Jansendf34cf11996-09-15 22:12:00 +0000506 if (!PyArg_ParseTuple(args, "|i", &resid))
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000507 return NULL;
Jack Jansen2e871e41997-09-08 13:23:19 +0000508 olddialog = curdialog;
Jack Jansencbe6a531998-02-20 15:59:59 +0000509 curdialog = NULL;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000510
Jack Jansendf34cf11996-09-15 22:12:00 +0000511 if ( resid != -1 ) {
512 curdialog = GetNewDialog(resid, NULL, (WindowPtr)-1);
Jack Jansen04df9d51996-09-23 15:49:43 +0000513 if ( curdialog ) {
514 theWindow = GetDialogWindow(curdialog);
515 thePort = GetWindowPort(theWindow);
Jack Jansene79dc762000-06-02 21:35:07 +0000516#if 0
Jack Jansen04df9d51996-09-23 15:49:43 +0000517 width = thePort->portRect.right - thePort->portRect.left;
518 height = thePort->portRect.bottom - thePort->portRect.top;
519 swidth = qd.screenBits.bounds.right - qd.screenBits.bounds.left;
520 sheight = qd.screenBits.bounds.bottom - qd.screenBits.bounds.top - LMGetMBarHeight();
521 xpos = (swidth-width)/2;
522 ypos = (sheight-height)/5 + LMGetMBarHeight();
523 MoveWindow(theWindow, xpos, ypos, 0);
524 ShowWindow(theWindow);
Jack Jansene79dc762000-06-02 21:35:07 +0000525#endif
Jack Jansendf34cf11996-09-15 22:12:00 +0000526 DrawDialog(curdialog);
Jack Jansen04df9d51996-09-23 15:49:43 +0000527 }
Jack Jansendf34cf11996-09-15 22:12:00 +0000528 }
Jack Jansen2e871e41997-09-08 13:23:19 +0000529 if (olddialog)
530 DisposeDialog(olddialog);
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000531 Py_INCREF(Py_None);
532 return Py_None;
533}
534
Jack Janseneb76b841996-09-30 14:43:22 +0000535static char DebugStr_doc[] = "Switch to low-level debugger with a message";
536
537static PyObject *
538MacOS_DebugStr(PyObject *self, PyObject *args)
539{
540 Str255 message;
541 PyObject *object = 0;
542
543 if (!PyArg_ParseTuple(args, "O&|O", PyMac_GetStr255, message, &object))
544 return NULL;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000545
Jack Janseneb76b841996-09-30 14:43:22 +0000546 DebugStr(message);
547 Py_INCREF(Py_None);
548 return Py_None;
549}
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000550
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000551
Jack Jansen2e871e41997-09-08 13:23:19 +0000552static char SysBeep_doc[] = "BEEEEEP!!!";
553
554static PyObject *
555MacOS_SysBeep(PyObject *self, PyObject *args)
556{
557 int duration = 6;
558
559 if (!PyArg_ParseTuple(args, "|i", &duration))
560 return NULL;
561 SysBeep(duration);
562 Py_INCREF(Py_None);
563 return Py_None;
564}
565
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000566#endif /* __LP64__ */
567
Jack Jansend7c17232003-02-21 16:31:11 +0000568static char WMAvailable_doc[] =
569 "True if this process can interact with the display."
570 "Will foreground the application on the first call as a side-effect."
571 ;
572
573static PyObject *
574MacOS_WMAvailable(PyObject *self, PyObject *args)
575{
576 static PyObject *rv = NULL;
577
578 if (!PyArg_ParseTuple(args, ""))
579 return NULL;
580 if (!rv) {
Jack Jansend7c17232003-02-21 16:31:11 +0000581 ProcessSerialNumber psn;
582
583 /*
584 ** This is a fairly innocuous call to make if we don't have a window
585 ** manager, or if we have no permission to talk to it. It will print
586 ** a message on stderr, but at least it won't abort the process.
587 ** It appears the function caches the result itself, and it's cheap, so
588 ** no need for us to cache.
589 */
Jack Jansen43285d42004-06-02 13:44:05 +0000590#ifdef kCGNullDirectDisplay
591 /* On 10.1 CGMainDisplayID() isn't available, and
592 ** kCGNullDirectDisplay isn't defined.
593 */
Jack Jansend7c17232003-02-21 16:31:11 +0000594 if (CGMainDisplayID() == 0) {
595 rv = Py_False;
596 } else {
Jack Jansen43285d42004-06-02 13:44:05 +0000597#else
598 {
599#endif
Jack Jansend7c17232003-02-21 16:31:11 +0000600 if (GetCurrentProcess(&psn) < 0 ||
601 SetFrontProcess(&psn) < 0) {
602 rv = Py_False;
603 } else {
604 rv = Py_True;
605 }
606 }
Jack Jansend7c17232003-02-21 16:31:11 +0000607 }
608 Py_INCREF(rv);
609 return rv;
610}
611
Jack Jansen898ac1b1997-09-01 15:38:12 +0000612static char GetTicks_doc[] = "Return number of ticks since bootup";
613
614static PyObject *
615MacOS_GetTicks(PyObject *self, PyObject *args)
616{
Jack Jansene79dc762000-06-02 21:35:07 +0000617 return Py_BuildValue("i", (int)TickCount());
Jack Jansen898ac1b1997-09-01 15:38:12 +0000618}
619
Jack Jansen76a05891996-02-29 16:11:32 +0000620static char openrf_doc[] = "Open resource fork of a file";
621
622static PyObject *
623MacOS_openrf(PyObject *self, PyObject *args)
624{
625 OSErr err;
626 char *mode = "r";
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000627 FSRef ref;
628 SInt8 permission = fsRdPerm;
Jack Jansen76a05891996-02-29 16:11:32 +0000629 rfobject *fp;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000630 HFSUniStr255 name;
Jack Jansen76a05891996-02-29 16:11:32 +0000631
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000632 if (!PyArg_ParseTuple(args, "O&|s", PyMac_GetFSRef, &ref, &mode))
Jack Jansen76a05891996-02-29 16:11:32 +0000633 return NULL;
634 while (*mode) {
635 switch (*mode++) {
636 case '*': break;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000637 case 'r': permission = fsRdPerm; break;
638 case 'w': permission = fsWrPerm; break;
Jack Jansen76a05891996-02-29 16:11:32 +0000639 case 'b': break;
640 default:
641 PyErr_BadArgument();
642 return NULL;
643 }
644 }
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000645
646 err = FSGetResourceForkName(&name);
647 if (err != noErr) {
648 PyMac_Error(err);
649 return NULL;
650 }
Jack Jansen76a05891996-02-29 16:11:32 +0000651
652 if ( (fp = newrfobject()) == NULL )
653 return NULL;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000654
Jack Jansen76a05891996-02-29 16:11:32 +0000655
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000656 err = FSOpenFork(&ref, name.length, name.unicode, permission, &fp->fRefNum);
657 if (err != noErr) {
Jack Jansen76a05891996-02-29 16:11:32 +0000658 Py_DECREF(fp);
659 PyMac_Error(err);
660 return NULL;
661 }
662 fp->isclosed = 0;
663 return (PyObject *)fp;
664}
665
Jack Jansen8413b472000-10-19 22:02:16 +0000666
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000667
Guido van Rossum2d167031994-09-16 10:54:21 +0000668static PyMethodDef MacOS_Methods[] = {
Jack Jansen120a1051997-06-03 15:29:41 +0000669 {"GetCreatorAndType", MacOS_GetCreatorAndType, 1, getcrtp_doc},
670 {"SetCreatorAndType", MacOS_SetCreatorAndType, 1, setcrtp_doc},
Jack Jansen120a1051997-06-03 15:29:41 +0000671 {"GetErrorString", MacOS_GetErrorString, 1, geterr_doc},
672 {"openrf", MacOS_openrf, 1, openrf_doc},
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000673#ifndef __LP64__
Jack Jansen120a1051997-06-03 15:29:41 +0000674 {"splash", MacOS_splash, 1, splash_doc},
675 {"DebugStr", MacOS_DebugStr, 1, DebugStr_doc},
Jack Jansen2e871e41997-09-08 13:23:19 +0000676 {"SysBeep", MacOS_SysBeep, 1, SysBeep_doc},
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000677#endif /* __LP64__ */
678 {"GetTicks", MacOS_GetTicks, 1, GetTicks_doc},
Jack Jansend7c17232003-02-21 16:31:11 +0000679 {"WMAvailable", MacOS_WMAvailable, 1, WMAvailable_doc},
Guido van Rossumf74d4e21995-01-18 23:58:07 +0000680 {NULL, NULL} /* Sentinel */
Guido van Rossum2d167031994-09-16 10:54:21 +0000681};
682
683
684void
Jack Jansendeefbe52001-08-08 13:46:49 +0000685initMacOS(void)
Guido van Rossum2d167031994-09-16 10:54:21 +0000686{
687 PyObject *m, *d;
688
Benjamin Peterson23681932008-05-12 21:42:13 +0000689 if (PyErr_WarnPy3k("In 3.x, MacOS is removed.", 1))
690 return;
691
Guido van Rossum2d167031994-09-16 10:54:21 +0000692 m = Py_InitModule("MacOS", MacOS_Methods);
693 d = PyModule_GetDict(m);
694
695 /* Initialize MacOS.Error exception */
Guido van Rossumbf068b11995-01-25 23:09:20 +0000696 MacOS_Error = PyMac_GetOSErrException();
Guido van Rossume433c971994-09-29 10:02:56 +0000697 if (MacOS_Error == NULL || PyDict_SetItemString(d, "Error", MacOS_Error) != 0)
Jack Jansenfa1e27d2000-09-08 10:21:44 +0000698 return;
Jack Jansena755e681997-09-20 17:40:22 +0000699 Rftype.ob_type = &PyType_Type;
700 Py_INCREF(&Rftype);
701 if (PyDict_SetItemString(d, "ResourceForkType", (PyObject *)&Rftype) != 0)
Jack Jansenfa1e27d2000-09-08 10:21:44 +0000702 return;
Jack Jansenf73bab71997-04-03 14:51:03 +0000703 /*
704 ** This is a hack: the following constant added to the id() of a string
705 ** object gives you the address of the data. Unfortunately, it is needed for
706 ** some of the image and sound processing interfaces on the mac:-(
707 */
708 {
Gregory P. Smithdd96db62008-06-09 04:58:54 +0000709 PyStringObject *p = 0;
Jack Jansenf73bab71997-04-03 14:51:03 +0000710 long off = (long)&(p->ob_sval[0]);
711
712 if( PyDict_SetItemString(d, "string_id_to_buffer", Py_BuildValue("i", off)) != 0)
Jack Jansenfa1e27d2000-09-08 10:21:44 +0000713 return;
Jack Jansenf73bab71997-04-03 14:51:03 +0000714 }
Jack Jansenf3163302001-05-19 12:50:05 +0000715#define PY_RUNTIMEMODEL "macho"
Jack Jansen193509b2001-01-23 22:38:23 +0000716 if (PyDict_SetItemString(d, "runtimemodel",
717 Py_BuildValue("s", PY_RUNTIMEMODEL)) != 0)
718 return;
Jack Jansena53f4eb2003-11-19 16:34:04 +0000719#if defined(WITH_NEXT_FRAMEWORK)
Jack Jansen8cd9a4f2003-02-23 23:23:47 +0000720#define PY_LINKMODEL "framework"
721#elif defined(Py_ENABLE_SHARED)
722#define PY_LINKMODEL "shared"
723#else
724#define PY_LINKMODEL "static"
725#endif
726 if (PyDict_SetItemString(d, "linkmodel",
727 Py_BuildValue("s", PY_LINKMODEL)) != 0)
728 return;
729
Guido van Rossum2d167031994-09-16 10:54:21 +0000730}