blob: 99e531b21f36499c02234ed69ae700fe94d06b8d [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 Oussoren5640ce22008-06-05 12:58:24 +000033
Guido van Rossum2d167031994-09-16 10:54:21 +000034static PyObject *MacOS_Error; /* Exception MacOS.Error */
35
Jack Jansen697842f2001-09-10 22:00:39 +000036#define PATHNAMELEN 1024
Jack Jansen697842f2001-09-10 22:00:39 +000037
Jack Jansen76a05891996-02-29 16:11:32 +000038/* ----------------------------------------------------- */
39
40/* Declarations for objects of type Resource fork */
41
42typedef struct {
43 PyObject_HEAD
Ronald Oussoren5640ce22008-06-05 12:58:24 +000044 FSIORefNum fRefNum;
Jack Jansen76a05891996-02-29 16:11:32 +000045 int isclosed;
46} rfobject;
47
Jeremy Hylton938ace62002-07-17 16:30:39 +000048static PyTypeObject Rftype;
Jack Jansen76a05891996-02-29 16:11:32 +000049
50
51
52/* ---------------------------------------------------------------- */
53
54static void
Jack Jansendeefbe52001-08-08 13:46:49 +000055do_close(rfobject *self)
Jack Jansen76a05891996-02-29 16:11:32 +000056{
57 if (self->isclosed ) return;
Ronald Oussoren5640ce22008-06-05 12:58:24 +000058 (void)FSCloseFork(self->fRefNum);
Jack Jansen76a05891996-02-29 16:11:32 +000059 self->isclosed = 1;
60}
61
62static char rf_read__doc__[] =
63"Read data from resource fork"
64;
65
66static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +000067rf_read(rfobject *self, PyObject *args)
Jack Jansen76a05891996-02-29 16:11:32 +000068{
69 long n;
70 PyObject *v;
71 OSErr err;
Ronald Oussoren5640ce22008-06-05 12:58:24 +000072 ByteCount n2;
Jack Jansen76a05891996-02-29 16:11:32 +000073
74 if (self->isclosed) {
75 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
76 return NULL;
77 }
78
79 if (!PyArg_ParseTuple(args, "l", &n))
80 return NULL;
81
Christian Heimes593daf52008-05-26 12:51:38 +000082 v = PyBytes_FromStringAndSize((char *)NULL, n);
Jack Jansen76a05891996-02-29 16:11:32 +000083 if (v == NULL)
84 return NULL;
85
Ronald Oussoren5640ce22008-06-05 12:58:24 +000086 err = FSReadFork(self->fRefNum, fsAtMark, 0, n, PyString_AsString(v), &n2);
Jack Jansen76a05891996-02-29 16:11:32 +000087 if (err && err != eofErr) {
88 PyMac_Error(err);
89 Py_DECREF(v);
90 return NULL;
91 }
Ronald Oussoren5640ce22008-06-05 12:58:24 +000092 _PyString_Resize(&v, n2);
Jack Jansen76a05891996-02-29 16:11:32 +000093 return v;
94}
95
96
97static char rf_write__doc__[] =
98"Write to resource fork"
99;
100
101static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000102rf_write(rfobject *self, PyObject *args)
Jack Jansen76a05891996-02-29 16:11:32 +0000103{
104 char *buffer;
105 long size;
106 OSErr err;
107
108 if (self->isclosed) {
109 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
110 return NULL;
111 }
Jack Janseneeccca91997-05-07 15:46:31 +0000112 if (!PyArg_ParseTuple(args, "s#", &buffer, &size))
Jack Jansen76a05891996-02-29 16:11:32 +0000113 return NULL;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000114 err = FSWriteFork(self->fRefNum, fsAtMark, 0, size, buffer, NULL);
Jack Jansen76a05891996-02-29 16:11:32 +0000115 if (err) {
116 PyMac_Error(err);
117 return NULL;
118 }
119 Py_INCREF(Py_None);
120 return Py_None;
121}
122
123
124static char rf_seek__doc__[] =
125"Set file position"
126;
127
128static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000129rf_seek(rfobject *self, PyObject *args)
Jack Jansen76a05891996-02-29 16:11:32 +0000130{
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000131 long amount;
Jack Jansen76a05891996-02-29 16:11:32 +0000132 int whence = SEEK_SET;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000133 int mode;
Jack Jansen76a05891996-02-29 16:11:32 +0000134 OSErr err;
135
136 if (self->isclosed) {
137 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
138 return NULL;
139 }
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000140 if (!PyArg_ParseTuple(args, "l|i", &amount, &whence)) {
Jack Jansen76a05891996-02-29 16:11:32 +0000141 return NULL;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000142 }
Jack Jansen76a05891996-02-29 16:11:32 +0000143
144 switch (whence) {
145 case SEEK_CUR:
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000146 mode = fsFromMark;
Jack Jansen76a05891996-02-29 16:11:32 +0000147 break;
148 case SEEK_END:
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000149 mode = fsFromLEOF;
Jack Jansen76a05891996-02-29 16:11:32 +0000150 break;
151 case SEEK_SET:
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000152 mode = fsFromStart;
Jack Jansen76a05891996-02-29 16:11:32 +0000153 break;
154 default:
155 PyErr_BadArgument();
156 return NULL;
157 }
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000158
159 err = FSSetForkPosition(self->fRefNum, mode, amount);
160 if (err != noErr) {
Jack Jansen76a05891996-02-29 16:11:32 +0000161 PyMac_Error(err);
162 return NULL;
163 }
164 Py_INCREF(Py_None);
165 return Py_None;
166}
167
168
169static char rf_tell__doc__[] =
170"Get file position"
171;
172
173static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000174rf_tell(rfobject *self, PyObject *args)
Jack Jansen76a05891996-02-29 16:11:32 +0000175{
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000176 long long where;
Jack Jansen76a05891996-02-29 16:11:32 +0000177 OSErr err;
178
179 if (self->isclosed) {
180 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
181 return NULL;
182 }
183 if (!PyArg_ParseTuple(args, ""))
184 return NULL;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000185
186 err = FSGetForkPosition(self->fRefNum, &where);
187 if (err != noErr) {
Jack Jansen76a05891996-02-29 16:11:32 +0000188 PyMac_Error(err);
189 return NULL;
190 }
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000191 return PyLong_FromLongLong(where);
Jack Jansen76a05891996-02-29 16:11:32 +0000192}
193
194static char rf_close__doc__[] =
195"Close resource fork"
196;
197
198static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000199rf_close(rfobject *self, PyObject *args)
Jack Jansen76a05891996-02-29 16:11:32 +0000200{
Jack Jansen76a05891996-02-29 16:11:32 +0000201 if (!PyArg_ParseTuple(args, ""))
202 return NULL;
203 do_close(self);
204 Py_INCREF(Py_None);
205 return Py_None;
206}
207
208
209static struct PyMethodDef rf_methods[] = {
Jack Jansendeefbe52001-08-08 13:46:49 +0000210 {"read", (PyCFunction)rf_read, 1, rf_read__doc__},
211 {"write", (PyCFunction)rf_write, 1, rf_write__doc__},
212 {"seek", (PyCFunction)rf_seek, 1, rf_seek__doc__},
213 {"tell", (PyCFunction)rf_tell, 1, rf_tell__doc__},
214 {"close", (PyCFunction)rf_close, 1, rf_close__doc__},
Jack Jansen76a05891996-02-29 16:11:32 +0000215
216 {NULL, NULL} /* sentinel */
217};
218
219/* ---------- */
220
221
222static rfobject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000223newrfobject(void)
Jack Jansen76a05891996-02-29 16:11:32 +0000224{
225 rfobject *self;
226
227 self = PyObject_NEW(rfobject, &Rftype);
228 if (self == NULL)
229 return NULL;
230 self->isclosed = 1;
231 return self;
232}
233
234
235static void
Jack Jansendeefbe52001-08-08 13:46:49 +0000236rf_dealloc(rfobject *self)
Jack Jansen76a05891996-02-29 16:11:32 +0000237{
238 do_close(self);
Jack Jansen0e2f7982002-05-22 14:31:48 +0000239 PyObject_DEL(self);
Jack Jansen76a05891996-02-29 16:11:32 +0000240}
241
242static PyObject *
Jack Jansendeefbe52001-08-08 13:46:49 +0000243rf_getattr(rfobject *self, char *name)
Jack Jansen76a05891996-02-29 16:11:32 +0000244{
245 return Py_FindMethod(rf_methods, (PyObject *)self, name);
246}
247
248static char Rftype__doc__[] =
249"Resource fork file object"
250;
251
252static PyTypeObject Rftype = {
253 PyObject_HEAD_INIT(&PyType_Type)
254 0, /*ob_size*/
Guido van Rossum14648392001-12-08 18:02:58 +0000255 "MacOS.ResourceFork", /*tp_name*/
Jack Jansen76a05891996-02-29 16:11:32 +0000256 sizeof(rfobject), /*tp_basicsize*/
257 0, /*tp_itemsize*/
258 /* methods */
259 (destructor)rf_dealloc, /*tp_dealloc*/
260 (printfunc)0, /*tp_print*/
261 (getattrfunc)rf_getattr, /*tp_getattr*/
262 (setattrfunc)0, /*tp_setattr*/
263 (cmpfunc)0, /*tp_compare*/
264 (reprfunc)0, /*tp_repr*/
265 0, /*tp_as_number*/
266 0, /*tp_as_sequence*/
267 0, /*tp_as_mapping*/
268 (hashfunc)0, /*tp_hash*/
269 (ternaryfunc)0, /*tp_call*/
270 (reprfunc)0, /*tp_str*/
271
272 /* Space for future expansion */
273 0L,0L,0L,0L,
274 Rftype__doc__ /* Documentation string */
275};
276
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000277
Jack Jansen76a05891996-02-29 16:11:32 +0000278/* End of code for Resource fork objects */
279/* -------------------------------------------------------- */
Guido van Rossum2d167031994-09-16 10:54:21 +0000280
281/*----------------------------------------------------------------------*/
Guido van Rossume791c2e1995-01-09 13:20:04 +0000282/* Miscellaneous File System Operations */
283
Jack Jansenfe94e972003-03-19 22:51:42 +0000284static char getcrtp_doc[] = "Get MacOS 4-char creator and type for a file";
Jack Jansen120a1051997-06-03 15:29:41 +0000285
Guido van Rossume791c2e1995-01-09 13:20:04 +0000286static PyObject *
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000287MacOS_GetCreatorAndType(PyObject *self, PyObject *args)
Guido van Rossume791c2e1995-01-09 13:20:04 +0000288{
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000289 PyObject *creator, *type, *res;
Guido van Rossume791c2e1995-01-09 13:20:04 +0000290 OSErr err;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000291 FSRef ref;
292 FSCatalogInfo cataloginfo;
293 FileInfo* finfo;
294
295 if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSRef, &ref)) {
296#ifndef __LP64__
297 /* This function is documented to take an FSSpec as well,
298 * which only works in 32-bit mode.
299 */
300 PyErr_Clear();
301 FSSpec fss;
302 FInfo info;
303
304 if (!PyArg_ParseTuple(args, "O&", PyMac_GetFSSpec, &fss))
305 return NULL;
306
307 if ((err = FSpGetFInfo(&fss, &info)) != noErr) {
308 return PyErr_Mac(MacOS_Error, err);
309 }
310 creator = PyString_FromStringAndSize(
311 (char *)&info.fdCreator, 4);
312 type = PyString_FromStringAndSize((char *)&info.fdType, 4);
313 res = Py_BuildValue("OO", creator, type);
314 Py_DECREF(creator);
315 Py_DECREF(type);
316 return res;
317#else /* __LP64__ */
Guido van Rossume791c2e1995-01-09 13:20:04 +0000318 return NULL;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000319#endif /* __LP64__ */
320 }
321
322 err = FSGetCatalogInfo(&ref,
323 kFSCatInfoFinderInfo|kFSCatInfoNodeFlags, &cataloginfo,
324 NULL, NULL, NULL);
325 if (err != noErr) {
326 PyErr_Mac(MacOS_Error, err);
327 return NULL;
328 }
329
330 if ((cataloginfo.nodeFlags & kFSNodeIsDirectoryMask) != 0) {
331 /* Directory: doesn't have type/creator info.
332 *
333 * The specific error code is for backward compatibility with
334 * earlier versions.
335 */
336 PyErr_Mac(MacOS_Error, fnfErr);
337 return NULL;
338
339 }
340 finfo = (FileInfo*)&(cataloginfo.finderInfo);
341 creator = PyString_FromStringAndSize((char*)&(finfo->fileCreator), 4);
342 type = PyString_FromStringAndSize((char*)&(finfo->fileType), 4);
343
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000344 res = Py_BuildValue("OO", creator, type);
Guido van Rossumfffb8bb1995-01-12 12:37:24 +0000345 Py_DECREF(creator);
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000346 Py_DECREF(type);
Guido van Rossume791c2e1995-01-09 13:20:04 +0000347 return res;
348}
349
Jack Jansenfe94e972003-03-19 22:51:42 +0000350static char setcrtp_doc[] = "Set MacOS 4-char creator and type for a file";
Jack Jansen120a1051997-06-03 15:29:41 +0000351
Guido van Rossume791c2e1995-01-09 13:20:04 +0000352static PyObject *
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000353MacOS_SetCreatorAndType(PyObject *self, PyObject *args)
Guido van Rossume791c2e1995-01-09 13:20:04 +0000354{
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000355 ResType creator, type;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000356 FSRef ref;
357 FileInfo* finfo;
Guido van Rossume791c2e1995-01-09 13:20:04 +0000358 OSErr err;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000359 FSCatalogInfo cataloginfo;
360
Guido van Rossume791c2e1995-01-09 13:20:04 +0000361 if (!PyArg_ParseTuple(args, "O&O&O&",
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000362 PyMac_GetFSRef, &ref, PyMac_GetOSType, &creator, PyMac_GetOSType, &type)) {
363#ifndef __LP64__
364 /* Try to handle FSSpec arguments, for backward compatibility */
365 FSSpec fss;
366 FInfo info;
367
368 if (!PyArg_ParseTuple(args, "O&O&O&",
Jack Jansene79dc762000-06-02 21:35:07 +0000369 PyMac_GetFSSpec, &fss, PyMac_GetOSType, &creator, PyMac_GetOSType, &type))
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000370 return NULL;
371
372 if ((err = FSpGetFInfo(&fss, &info)) != noErr)
373 return PyErr_Mac(MacOS_Error, err);
374
375 info.fdCreator = creator;
376 info.fdType = type;
377
378 if ((err = FSpSetFInfo(&fss, &info)) != noErr)
379 return PyErr_Mac(MacOS_Error, err);
380 Py_INCREF(Py_None);
381 return Py_None;
382#else /* __LP64__ */
Guido van Rossume791c2e1995-01-09 13:20:04 +0000383 return NULL;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000384#endif /* __LP64__ */
385 }
386
387 err = FSGetCatalogInfo(&ref,
388 kFSCatInfoFinderInfo|kFSCatInfoNodeFlags, &cataloginfo,
389 NULL, NULL, NULL);
390 if (err != noErr) {
391 PyErr_Mac(MacOS_Error, err);
392 return NULL;
393 }
394
395 if ((cataloginfo.nodeFlags & kFSNodeIsDirectoryMask) != 0) {
396 /* Directory: doesn't have type/creator info.
397 *
398 * The specific error code is for backward compatibility with
399 * earlier versions.
400 */
401 PyErr_Mac(MacOS_Error, fnfErr);
402 return NULL;
403
404 }
405 finfo = (FileInfo*)&(cataloginfo.finderInfo);
406 finfo->fileCreator = creator;
407 finfo->fileType = type;
408
409 err = FSSetCatalogInfo(&ref, kFSCatInfoFinderInfo, &cataloginfo);
410 if (err != noErr) {
411 PyErr_Mac(MacOS_Error, fnfErr);
412 return NULL;
413 }
414
Guido van Rossume791c2e1995-01-09 13:20:04 +0000415 Py_INCREF(Py_None);
416 return Py_None;
417}
418
Jack Jansena76382a1995-02-02 14:25:56 +0000419
Jack Jansen120a1051997-06-03 15:29:41 +0000420static char geterr_doc[] = "Convert OSErr number to string";
421
Jack Jansen829f88c1995-07-17 11:36:01 +0000422static PyObject *
423MacOS_GetErrorString(PyObject *self, PyObject *args)
424{
Raymond Hettingerec6eb362004-11-05 07:02:59 +0000425 int err;
426 char buf[256];
427 Handle h;
428 char *str;
429 static int errors_loaded;
Jack Jansen829f88c1995-07-17 11:36:01 +0000430
Raymond Hettingerec6eb362004-11-05 07:02:59 +0000431 if (!PyArg_ParseTuple(args, "i", &err))
Jack Jansen829f88c1995-07-17 11:36:01 +0000432 return NULL;
Raymond Hettingerec6eb362004-11-05 07:02:59 +0000433
434 h = GetResource('Estr', err);
435 if (!h && !errors_loaded) {
436 /*
437 ** Attempt to open the resource file containing the
438 ** Estr resources. We ignore all errors. We also try
439 ** this only once.
440 */
441 PyObject *m, *rv;
442 errors_loaded = 1;
443
Christian Heimes000a0742008-01-03 22:16:32 +0000444 m = PyImport_ImportModuleNoBlock("macresource");
Raymond Hettingerec6eb362004-11-05 07:02:59 +0000445 if (!m) {
446 if (Py_VerboseFlag)
447 PyErr_Print();
448 PyErr_Clear();
449 }
450 else {
451 rv = PyObject_CallMethod(m, "open_error_resource", "");
452 if (!rv) {
453 if (Py_VerboseFlag)
454 PyErr_Print();
455 PyErr_Clear();
456 }
457 else {
458 Py_DECREF(rv);
459 /* And try again... */
460 h = GetResource('Estr', err);
461 }
Thomas Hellerdd827342006-07-11 16:42:05 +0000462 Py_DECREF(m);
Raymond Hettingerec6eb362004-11-05 07:02:59 +0000463 }
464 }
465 /*
466 ** Whether the code above succeeded or not, we won't try
467 ** again.
468 */
469 errors_loaded = 1;
470
471 if (h) {
472 HLock(h);
473 str = (char *)*h;
474 memcpy(buf, str+1, (unsigned char)str[0]);
475 buf[(unsigned char)str[0]] = '\0';
476 HUnlock(h);
477 ReleaseResource(h);
478 }
479 else {
480 PyOS_snprintf(buf, sizeof(buf), "Mac OS error code %d", err);
481 }
482
483 return Py_BuildValue("s", buf);
Jack Jansen829f88c1995-07-17 11:36:01 +0000484}
485
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000486
487#ifndef __LP64__
488
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000489static char splash_doc[] = "Open a splash-screen dialog by resource-id (0=close)";
490
491static PyObject *
492MacOS_splash(PyObject *self, PyObject *args)
493{
Jack Jansendf34cf11996-09-15 22:12:00 +0000494 int resid = -1;
Jack Jansen450ae9f1997-05-13 15:41:48 +0000495 static DialogPtr curdialog = NULL;
Jack Jansen2e871e41997-09-08 13:23:19 +0000496 DialogPtr olddialog;
Jack Jansen04df9d51996-09-23 15:49:43 +0000497 WindowRef theWindow;
498 CGrafPtr thePort;
Jack Jansene79dc762000-06-02 21:35:07 +0000499#if 0
Jack Jansen04df9d51996-09-23 15:49:43 +0000500 short xpos, ypos, width, height, swidth, sheight;
Jack Jansene79dc762000-06-02 21:35:07 +0000501#endif
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000502
Jack Jansendf34cf11996-09-15 22:12:00 +0000503 if (!PyArg_ParseTuple(args, "|i", &resid))
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000504 return NULL;
Jack Jansen2e871e41997-09-08 13:23:19 +0000505 olddialog = curdialog;
Jack Jansencbe6a531998-02-20 15:59:59 +0000506 curdialog = NULL;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000507
Jack Jansendf34cf11996-09-15 22:12:00 +0000508 if ( resid != -1 ) {
509 curdialog = GetNewDialog(resid, NULL, (WindowPtr)-1);
Jack Jansen04df9d51996-09-23 15:49:43 +0000510 if ( curdialog ) {
511 theWindow = GetDialogWindow(curdialog);
512 thePort = GetWindowPort(theWindow);
Jack Jansene79dc762000-06-02 21:35:07 +0000513#if 0
Jack Jansen04df9d51996-09-23 15:49:43 +0000514 width = thePort->portRect.right - thePort->portRect.left;
515 height = thePort->portRect.bottom - thePort->portRect.top;
516 swidth = qd.screenBits.bounds.right - qd.screenBits.bounds.left;
517 sheight = qd.screenBits.bounds.bottom - qd.screenBits.bounds.top - LMGetMBarHeight();
518 xpos = (swidth-width)/2;
519 ypos = (sheight-height)/5 + LMGetMBarHeight();
520 MoveWindow(theWindow, xpos, ypos, 0);
521 ShowWindow(theWindow);
Jack Jansene79dc762000-06-02 21:35:07 +0000522#endif
Jack Jansendf34cf11996-09-15 22:12:00 +0000523 DrawDialog(curdialog);
Jack Jansen04df9d51996-09-23 15:49:43 +0000524 }
Jack Jansendf34cf11996-09-15 22:12:00 +0000525 }
Jack Jansen2e871e41997-09-08 13:23:19 +0000526 if (olddialog)
527 DisposeDialog(olddialog);
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000528 Py_INCREF(Py_None);
529 return Py_None;
530}
531
Jack Janseneb76b841996-09-30 14:43:22 +0000532static char DebugStr_doc[] = "Switch to low-level debugger with a message";
533
534static PyObject *
535MacOS_DebugStr(PyObject *self, PyObject *args)
536{
537 Str255 message;
538 PyObject *object = 0;
539
540 if (!PyArg_ParseTuple(args, "O&|O", PyMac_GetStr255, message, &object))
541 return NULL;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000542
Jack Janseneb76b841996-09-30 14:43:22 +0000543 DebugStr(message);
544 Py_INCREF(Py_None);
545 return Py_None;
546}
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000547
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000548
Jack Jansen2e871e41997-09-08 13:23:19 +0000549static char SysBeep_doc[] = "BEEEEEP!!!";
550
551static PyObject *
552MacOS_SysBeep(PyObject *self, PyObject *args)
553{
554 int duration = 6;
555
556 if (!PyArg_ParseTuple(args, "|i", &duration))
557 return NULL;
558 SysBeep(duration);
559 Py_INCREF(Py_None);
560 return Py_None;
561}
562
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000563#endif /* __LP64__ */
564
Jack Jansend7c17232003-02-21 16:31:11 +0000565static char WMAvailable_doc[] =
566 "True if this process can interact with the display."
567 "Will foreground the application on the first call as a side-effect."
568 ;
569
570static PyObject *
571MacOS_WMAvailable(PyObject *self, PyObject *args)
572{
573 static PyObject *rv = NULL;
574
575 if (!PyArg_ParseTuple(args, ""))
576 return NULL;
577 if (!rv) {
Jack Jansend7c17232003-02-21 16:31:11 +0000578 ProcessSerialNumber psn;
579
580 /*
581 ** This is a fairly innocuous call to make if we don't have a window
582 ** manager, or if we have no permission to talk to it. It will print
583 ** a message on stderr, but at least it won't abort the process.
584 ** It appears the function caches the result itself, and it's cheap, so
585 ** no need for us to cache.
586 */
Jack Jansen43285d42004-06-02 13:44:05 +0000587#ifdef kCGNullDirectDisplay
588 /* On 10.1 CGMainDisplayID() isn't available, and
589 ** kCGNullDirectDisplay isn't defined.
590 */
Jack Jansend7c17232003-02-21 16:31:11 +0000591 if (CGMainDisplayID() == 0) {
592 rv = Py_False;
593 } else {
Jack Jansen43285d42004-06-02 13:44:05 +0000594#else
595 {
596#endif
Jack Jansend7c17232003-02-21 16:31:11 +0000597 if (GetCurrentProcess(&psn) < 0 ||
598 SetFrontProcess(&psn) < 0) {
599 rv = Py_False;
600 } else {
601 rv = Py_True;
602 }
603 }
Jack Jansend7c17232003-02-21 16:31:11 +0000604 }
605 Py_INCREF(rv);
606 return rv;
607}
608
Jack Jansen898ac1b1997-09-01 15:38:12 +0000609static char GetTicks_doc[] = "Return number of ticks since bootup";
610
611static PyObject *
612MacOS_GetTicks(PyObject *self, PyObject *args)
613{
Jack Jansene79dc762000-06-02 21:35:07 +0000614 return Py_BuildValue("i", (int)TickCount());
Jack Jansen898ac1b1997-09-01 15:38:12 +0000615}
616
Jack Jansen76a05891996-02-29 16:11:32 +0000617static char openrf_doc[] = "Open resource fork of a file";
618
619static PyObject *
620MacOS_openrf(PyObject *self, PyObject *args)
621{
622 OSErr err;
623 char *mode = "r";
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000624 FSRef ref;
625 SInt8 permission = fsRdPerm;
Jack Jansen76a05891996-02-29 16:11:32 +0000626 rfobject *fp;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000627 HFSUniStr255 name;
Jack Jansen76a05891996-02-29 16:11:32 +0000628
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000629 if (!PyArg_ParseTuple(args, "O&|s", PyMac_GetFSRef, &ref, &mode))
Jack Jansen76a05891996-02-29 16:11:32 +0000630 return NULL;
631 while (*mode) {
632 switch (*mode++) {
633 case '*': break;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000634 case 'r': permission = fsRdPerm; break;
635 case 'w': permission = fsWrPerm; break;
Jack Jansen76a05891996-02-29 16:11:32 +0000636 case 'b': break;
637 default:
638 PyErr_BadArgument();
639 return NULL;
640 }
641 }
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000642
643 err = FSGetResourceForkName(&name);
644 if (err != noErr) {
645 PyMac_Error(err);
646 return NULL;
647 }
Jack Jansen76a05891996-02-29 16:11:32 +0000648
649 if ( (fp = newrfobject()) == NULL )
650 return NULL;
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000651
Jack Jansen76a05891996-02-29 16:11:32 +0000652
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000653 err = FSOpenFork(&ref, name.length, name.unicode, permission, &fp->fRefNum);
654 if (err != noErr) {
Jack Jansen76a05891996-02-29 16:11:32 +0000655 Py_DECREF(fp);
656 PyMac_Error(err);
657 return NULL;
658 }
659 fp->isclosed = 0;
660 return (PyObject *)fp;
661}
662
Jack Jansen8413b472000-10-19 22:02:16 +0000663
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000664
Guido van Rossum2d167031994-09-16 10:54:21 +0000665static PyMethodDef MacOS_Methods[] = {
Jack Jansen120a1051997-06-03 15:29:41 +0000666 {"GetCreatorAndType", MacOS_GetCreatorAndType, 1, getcrtp_doc},
667 {"SetCreatorAndType", MacOS_SetCreatorAndType, 1, setcrtp_doc},
Jack Jansen120a1051997-06-03 15:29:41 +0000668 {"GetErrorString", MacOS_GetErrorString, 1, geterr_doc},
669 {"openrf", MacOS_openrf, 1, openrf_doc},
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000670#ifndef __LP64__
Jack Jansen120a1051997-06-03 15:29:41 +0000671 {"splash", MacOS_splash, 1, splash_doc},
672 {"DebugStr", MacOS_DebugStr, 1, DebugStr_doc},
Jack Jansen2e871e41997-09-08 13:23:19 +0000673 {"SysBeep", MacOS_SysBeep, 1, SysBeep_doc},
Ronald Oussoren5640ce22008-06-05 12:58:24 +0000674#endif /* __LP64__ */
675 {"GetTicks", MacOS_GetTicks, 1, GetTicks_doc},
Jack Jansend7c17232003-02-21 16:31:11 +0000676 {"WMAvailable", MacOS_WMAvailable, 1, WMAvailable_doc},
Guido van Rossumf74d4e21995-01-18 23:58:07 +0000677 {NULL, NULL} /* Sentinel */
Guido van Rossum2d167031994-09-16 10:54:21 +0000678};
679
680
681void
Jack Jansendeefbe52001-08-08 13:46:49 +0000682initMacOS(void)
Guido van Rossum2d167031994-09-16 10:54:21 +0000683{
684 PyObject *m, *d;
685
Benjamin Peterson23681932008-05-12 21:42:13 +0000686 if (PyErr_WarnPy3k("In 3.x, MacOS is removed.", 1))
687 return;
688
Guido van Rossum2d167031994-09-16 10:54:21 +0000689 m = Py_InitModule("MacOS", MacOS_Methods);
690 d = PyModule_GetDict(m);
691
692 /* Initialize MacOS.Error exception */
Guido van Rossumbf068b11995-01-25 23:09:20 +0000693 MacOS_Error = PyMac_GetOSErrException();
Guido van Rossume433c971994-09-29 10:02:56 +0000694 if (MacOS_Error == NULL || PyDict_SetItemString(d, "Error", MacOS_Error) != 0)
Jack Jansenfa1e27d2000-09-08 10:21:44 +0000695 return;
Jack Jansena755e681997-09-20 17:40:22 +0000696 Rftype.ob_type = &PyType_Type;
697 Py_INCREF(&Rftype);
698 if (PyDict_SetItemString(d, "ResourceForkType", (PyObject *)&Rftype) != 0)
Jack Jansenfa1e27d2000-09-08 10:21:44 +0000699 return;
Jack Jansenf73bab71997-04-03 14:51:03 +0000700 /*
701 ** This is a hack: the following constant added to the id() of a string
702 ** object gives you the address of the data. Unfortunately, it is needed for
703 ** some of the image and sound processing interfaces on the mac:-(
704 */
705 {
Christian Heimes593daf52008-05-26 12:51:38 +0000706 PyBytesObject *p = 0;
Jack Jansenf73bab71997-04-03 14:51:03 +0000707 long off = (long)&(p->ob_sval[0]);
708
709 if( PyDict_SetItemString(d, "string_id_to_buffer", Py_BuildValue("i", off)) != 0)
Jack Jansenfa1e27d2000-09-08 10:21:44 +0000710 return;
Jack Jansenf73bab71997-04-03 14:51:03 +0000711 }
Jack Jansenf3163302001-05-19 12:50:05 +0000712#define PY_RUNTIMEMODEL "macho"
Jack Jansen193509b2001-01-23 22:38:23 +0000713 if (PyDict_SetItemString(d, "runtimemodel",
714 Py_BuildValue("s", PY_RUNTIMEMODEL)) != 0)
715 return;
Jack Jansena53f4eb2003-11-19 16:34:04 +0000716#if defined(WITH_NEXT_FRAMEWORK)
Jack Jansen8cd9a4f2003-02-23 23:23:47 +0000717#define PY_LINKMODEL "framework"
718#elif defined(Py_ENABLE_SHARED)
719#define PY_LINKMODEL "shared"
720#else
721#define PY_LINKMODEL "static"
722#endif
723 if (PyDict_SetItemString(d, "linkmodel",
724 Py_BuildValue("s", PY_LINKMODEL)) != 0)
725 return;
726
Guido van Rossum2d167031994-09-16 10:54:21 +0000727}