blob: 4780f1b217b0bf0d96d67631450e34a7e10e40a1 [file] [log] [blame]
Guido van Rossum2d167031994-09-16 10:54:21 +00001/***********************************************************
Guido van Rossum99546991995-01-08 14:33:34 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The 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 Jansen97ce3611994-12-14 14:02:24 +000028#include "macglue.h"
Guido van Rossum2d167031994-09-16 10:54:21 +000029
Jack Jansenee23d6e1995-01-27 14:43:25 +000030#include <Windows.h>
Jack Jansen76a05891996-02-29 16:11:32 +000031#include <Files.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
Guido van Rossume6d9ccc1995-02-21 21:01:05 +000035#ifdef MPW
Guido van Rossum9fed1831995-02-18 15:02:02 +000036#define bufferIsSmall -607 /*error returns from Post and Accept */
37#endif
38
Jack Jansen76a05891996-02-29 16:11:32 +000039static PyObject *ErrorObject;
40
41/* ----------------------------------------------------- */
42
43/* Declarations for objects of type Resource fork */
44
45typedef struct {
46 PyObject_HEAD
47 short fRefNum;
48 int isclosed;
49} rfobject;
50
51staticforward PyTypeObject Rftype;
52
53
54
55/* ---------------------------------------------------------------- */
56
57static void
58do_close(self)
59 rfobject *self;
60{
61 if (self->isclosed ) return;
62 (void)FSClose(self->fRefNum);
63 self->isclosed = 1;
64}
65
66static char rf_read__doc__[] =
67"Read data from resource fork"
68;
69
70static PyObject *
71rf_read(self, args)
72 rfobject *self;
73 PyObject *args;
74{
75 long n;
76 PyObject *v;
77 OSErr err;
78
79 if (self->isclosed) {
80 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
81 return NULL;
82 }
83
84 if (!PyArg_ParseTuple(args, "l", &n))
85 return NULL;
86
87 v = PyString_FromStringAndSize((char *)NULL, n);
88 if (v == NULL)
89 return NULL;
90
91 err = FSRead(self->fRefNum, &n, PyString_AsString(v));
92 if (err && err != eofErr) {
93 PyMac_Error(err);
94 Py_DECREF(v);
95 return NULL;
96 }
97 _PyString_Resize(&v, n);
98 return v;
99}
100
101
102static char rf_write__doc__[] =
103"Write to resource fork"
104;
105
106static PyObject *
107rf_write(self, args)
108 rfobject *self;
109 PyObject *args;
110{
111 char *buffer;
112 long size;
113 OSErr err;
114
115 if (self->isclosed) {
116 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
117 return NULL;
118 }
119 if (!PyArg_ParseTuple(args, "s#", &buffer, &size))
120 return NULL;
121 err = FSWrite(self->fRefNum, &size, buffer);
122 if (err) {
123 PyMac_Error(err);
124 return NULL;
125 }
126 Py_INCREF(Py_None);
127 return Py_None;
128}
129
130
131static char rf_seek__doc__[] =
132"Set file position"
133;
134
135static PyObject *
136rf_seek(self, args)
137 rfobject *self;
138 PyObject *args;
139{
140 long amount, pos;
141 int whence = SEEK_SET;
142 long eof;
143 OSErr err;
144
145 if (self->isclosed) {
146 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
147 return NULL;
148 }
149 if (!PyArg_ParseTuple(args, "l|i", &amount, &whence))
150 return NULL;
151
152 if ( err = GetEOF(self->fRefNum, &eof))
153 goto ioerr;
154
155 switch (whence) {
156 case SEEK_CUR:
157 if (err = GetFPos(self->fRefNum, &pos))
158 goto ioerr;
159 break;
160 case SEEK_END:
161 pos = eof;
162 break;
163 case SEEK_SET:
164 pos = 0;
165 break;
166 default:
167 PyErr_BadArgument();
168 return NULL;
169 }
170
171 pos += amount;
172
173 /* Don't bother implementing seek past EOF */
174 if (pos > eof || pos < 0) {
175 PyErr_BadArgument();
176 return NULL;
177 }
178
179 if ( err = SetFPos(self->fRefNum, fsFromStart, pos) ) {
180ioerr:
181 PyMac_Error(err);
182 return NULL;
183 }
184 Py_INCREF(Py_None);
185 return Py_None;
186}
187
188
189static char rf_tell__doc__[] =
190"Get file position"
191;
192
193static PyObject *
194rf_tell(self, args)
195 rfobject *self;
196 PyObject *args;
197{
198 long where;
199 OSErr err;
200
201 if (self->isclosed) {
202 PyErr_SetString(PyExc_ValueError, "Operation on closed file");
203 return NULL;
204 }
205 if (!PyArg_ParseTuple(args, ""))
206 return NULL;
207 if ( err = GetFPos(self->fRefNum, &where) ) {
208 PyMac_Error(err);
209 return NULL;
210 }
211 return PyInt_FromLong(where);
212}
213
214static char rf_close__doc__[] =
215"Close resource fork"
216;
217
218static PyObject *
219rf_close(self, args)
220 rfobject *self;
221 PyObject *args;
222{
Jack Jansen76a05891996-02-29 16:11:32 +0000223 if (!PyArg_ParseTuple(args, ""))
224 return NULL;
225 do_close(self);
226 Py_INCREF(Py_None);
227 return Py_None;
228}
229
230
231static struct PyMethodDef rf_methods[] = {
232 {"read", rf_read, 1, rf_read__doc__},
233 {"write", rf_write, 1, rf_write__doc__},
234 {"seek", rf_seek, 1, rf_seek__doc__},
235 {"tell", rf_tell, 1, rf_tell__doc__},
236 {"close", rf_close, 1, rf_close__doc__},
237
238 {NULL, NULL} /* sentinel */
239};
240
241/* ---------- */
242
243
244static rfobject *
245newrfobject()
246{
247 rfobject *self;
248
249 self = PyObject_NEW(rfobject, &Rftype);
250 if (self == NULL)
251 return NULL;
252 self->isclosed = 1;
253 return self;
254}
255
256
257static void
258rf_dealloc(self)
259 rfobject *self;
260{
261 do_close(self);
262 PyMem_DEL(self);
263}
264
265static PyObject *
266rf_getattr(self, name)
267 rfobject *self;
268 char *name;
269{
270 return Py_FindMethod(rf_methods, (PyObject *)self, name);
271}
272
273static char Rftype__doc__[] =
274"Resource fork file object"
275;
276
277static PyTypeObject Rftype = {
278 PyObject_HEAD_INIT(&PyType_Type)
279 0, /*ob_size*/
280 "Resource fork", /*tp_name*/
281 sizeof(rfobject), /*tp_basicsize*/
282 0, /*tp_itemsize*/
283 /* methods */
284 (destructor)rf_dealloc, /*tp_dealloc*/
285 (printfunc)0, /*tp_print*/
286 (getattrfunc)rf_getattr, /*tp_getattr*/
287 (setattrfunc)0, /*tp_setattr*/
288 (cmpfunc)0, /*tp_compare*/
289 (reprfunc)0, /*tp_repr*/
290 0, /*tp_as_number*/
291 0, /*tp_as_sequence*/
292 0, /*tp_as_mapping*/
293 (hashfunc)0, /*tp_hash*/
294 (ternaryfunc)0, /*tp_call*/
295 (reprfunc)0, /*tp_str*/
296
297 /* Space for future expansion */
298 0L,0L,0L,0L,
299 Rftype__doc__ /* Documentation string */
300};
301
302/* End of code for Resource fork objects */
303/* -------------------------------------------------------- */
Guido van Rossum2d167031994-09-16 10:54:21 +0000304
305/*----------------------------------------------------------------------*/
Guido van Rossume791c2e1995-01-09 13:20:04 +0000306/* Miscellaneous File System Operations */
307
308static PyObject *
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000309MacOS_GetCreatorAndType(PyObject *self, PyObject *args)
Guido van Rossume791c2e1995-01-09 13:20:04 +0000310{
311 Str255 name;
312 FInfo info;
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000313 PyObject *creator, *type, *res;
Guido van Rossume791c2e1995-01-09 13:20:04 +0000314 OSErr err;
315
Guido van Rossum9aa3d131995-01-21 13:46:04 +0000316 if (!PyArg_ParseTuple(args, "O&", PyMac_GetStr255, &name))
Guido van Rossume791c2e1995-01-09 13:20:04 +0000317 return NULL;
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000318 if ((err = GetFInfo(name, 0, &info)) != noErr)
319 return PyErr_Mac(MacOS_Error, err);
Guido van Rossume791c2e1995-01-09 13:20:04 +0000320 creator = PyString_FromStringAndSize((char *)&info.fdCreator, 4);
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000321 type = PyString_FromStringAndSize((char *)&info.fdType, 4);
322 res = Py_BuildValue("OO", creator, type);
Guido van Rossumfffb8bb1995-01-12 12:37:24 +0000323 Py_DECREF(creator);
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000324 Py_DECREF(type);
Guido van Rossume791c2e1995-01-09 13:20:04 +0000325 return res;
326}
327
328static PyObject *
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000329MacOS_SetCreatorAndType(PyObject *self, PyObject *args)
Guido van Rossume791c2e1995-01-09 13:20:04 +0000330{
331 Str255 name;
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000332 ResType creator, type;
Guido van Rossume791c2e1995-01-09 13:20:04 +0000333 FInfo info;
334 OSErr err;
335
336 if (!PyArg_ParseTuple(args, "O&O&O&",
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000337 PyMac_GetStr255, &name, PyMac_GetOSType, &creator, PyMac_GetOSType, &type))
Guido van Rossume791c2e1995-01-09 13:20:04 +0000338 return NULL;
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000339 if ((err = GetFInfo(name, 0, &info)) != noErr)
340 return PyErr_Mac(MacOS_Error, err);
Guido van Rossume791c2e1995-01-09 13:20:04 +0000341 info.fdCreator = creator;
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000342 info.fdType = type;
343 if ((err = SetFInfo(name, 0, &info)) != noErr)
344 return PyErr_Mac(MacOS_Error, err);
Guido van Rossume791c2e1995-01-09 13:20:04 +0000345 Py_INCREF(Py_None);
346 return Py_None;
347}
348
349/*----------------------------------------------------------------------*/
Guido van Rossumf74d4e21995-01-18 23:58:07 +0000350/* STDWIN High Level Event interface */
351
352#include <EPPC.h>
353#include <Events.h>
354
355#ifdef USE_STDWIN
356
357extern void (*_w_high_level_event_proc)(EventRecord *);
358
359static PyObject *MacOS_HighLevelEventHandler = NULL;
360
361static void
Guido van Rossumbf068b11995-01-25 23:09:20 +0000362MacOS_HighLevelEventProc(EventRecord *e)
Guido van Rossumf74d4e21995-01-18 23:58:07 +0000363{
364 if (MacOS_HighLevelEventHandler != NULL) {
Guido van Rossumbf068b11995-01-25 23:09:20 +0000365 PyObject *args = PyMac_BuildEventRecord(e);
Guido van Rossumf74d4e21995-01-18 23:58:07 +0000366 PyObject *res;
367 if (args == NULL)
368 res = NULL;
369 else {
370 res = PyEval_CallObject(MacOS_HighLevelEventHandler, args);
371 Py_DECREF(args);
372 }
373 if (res == NULL) {
374 fprintf(stderr, "Exception in MacOS_HighLevelEventProc:\n");
375 PyErr_Print();
376 }
377 else
378 Py_DECREF(res);
379 }
380}
381
Jack Jansene8e8ae01995-01-26 16:36:45 +0000382/* XXXX Need to come here from PyMac_DoYield too... */
383
Guido van Rossumf74d4e21995-01-18 23:58:07 +0000384static PyObject *
385MacOS_SetHighLevelEventHandler(self, args)
386 PyObject *self;
387 PyObject *args;
388{
389 PyObject *previous = MacOS_HighLevelEventHandler;
390 PyObject *next = NULL;
391 if (!PyArg_ParseTuple(args, "|O", &next))
392 return NULL;
393 if (next == Py_None)
394 next = NULL;
395 Py_INCREF(next);
396 MacOS_HighLevelEventHandler = next;
397 if (next == NULL)
398 _w_high_level_event_proc = NULL;
399 else
400 _w_high_level_event_proc = MacOS_HighLevelEventProc;
401 if (previous == NULL) {
402 Py_INCREF(Py_None);
403 previous = Py_None;
404 }
405 return previous;
406}
407
408#endif /* USE_STDWIN */
409
410static PyObject *
411MacOS_AcceptHighLevelEvent(self, args)
412 PyObject *self;
413 PyObject *args;
414{
415 TargetID sender;
416 unsigned long refcon;
417 Ptr buf;
418 unsigned long len;
419 OSErr err;
420 PyObject *res;
421
422 buf = NULL;
423 len = 0;
424 err = AcceptHighLevelEvent(&sender, &refcon, buf, &len);
425 if (err == bufferIsSmall) {
426 buf = malloc(len);
427 if (buf == NULL)
428 return PyErr_NoMemory();
429 err = AcceptHighLevelEvent(&sender, &refcon, buf, &len);
430 if (err != noErr) {
431 free(buf);
432 return PyErr_Mac(MacOS_Error, (int)err);
433 }
434 }
435 else if (err != noErr)
436 return PyErr_Mac(MacOS_Error, (int)err);
437 res = Py_BuildValue("s#ls#",
438 (char *)&sender, (int)(sizeof sender), refcon, (char *)buf, (int)len);
439 free(buf);
440 return res;
441}
442
Jack Jansene8e8ae01995-01-26 16:36:45 +0000443/*
444** Set poll frequency and cpu-yield-time
445*/
446static PyObject *
447MacOS_SetScheduleTimes(PyObject *self, PyObject *args)
448{
449 long fgi, fgy, bgi, bgy;
450
451 bgi = bgy = -2;
452 if (!PyArg_ParseTuple(args, "ll|ll", &fgi, &fgy, &bgi, &bgy))
453 return NULL;
Jack Jansenb2f6a7e1995-02-20 15:46:10 +0000454 if ( bgi == -2 || bgy == -2 ) {
Jack Jansene8e8ae01995-01-26 16:36:45 +0000455 bgi = fgi;
456 bgy = fgy;
457 }
458 PyMac_SetYield(fgi, fgy, bgi, bgy);
459 Py_INCREF(Py_None);
460 return Py_None;
461}
462
Jack Jansenee23d6e1995-01-27 14:43:25 +0000463static PyObject *
464MacOS_EnableAppswitch(PyObject *self, PyObject *args)
465{
Guido van Rossume7134aa1995-02-26 10:20:53 +0000466 int old, new;
Jack Jansenee23d6e1995-01-27 14:43:25 +0000467
Guido van Rossume7134aa1995-02-26 10:20:53 +0000468 if (!PyArg_ParseTuple(args, "i", &new))
Jack Jansenee23d6e1995-01-27 14:43:25 +0000469 return NULL;
Guido van Rossume7134aa1995-02-26 10:20:53 +0000470 old = PyMac_DoYieldEnabled;
471 PyMac_DoYieldEnabled = new;
472 return Py_BuildValue("i", old);
Jack Jansenee23d6e1995-01-27 14:43:25 +0000473}
474
Jack Jansena76382a1995-02-02 14:25:56 +0000475
476static PyObject *
477MacOS_HandleEvent(PyObject *self, PyObject *args)
478{
479 EventRecord ev;
480
481 if (!PyArg_ParseTuple(args, "O&", PyMac_GetEventRecord, &ev))
482 return NULL;
483 PyMac_HandleEvent(&ev);
484 Py_INCREF(Py_None);
485 return Py_None;
486}
487
Jack Jansen829f88c1995-07-17 11:36:01 +0000488static PyObject *
489MacOS_GetErrorString(PyObject *self, PyObject *args)
490{
491 int errn;
492
493 if (!PyArg_ParseTuple(args, "i", &errn))
494 return NULL;
495 return Py_BuildValue("s", PyMac_StrError(errn));
496}
497
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000498static char splash_doc[] = "Open a splash-screen dialog by resource-id (0=close)";
499
500static PyObject *
501MacOS_splash(PyObject *self, PyObject *args)
502{
503 int resid;
504 static DialogPtr curdialog;
505
506 if (!PyArg_ParseTuple(args, "i", &resid))
507 return NULL;
508 if (curdialog)
509 DisposeDialog(curdialog);
510
511 curdialog = GetNewDialog(resid, NULL, (WindowPtr)-1);
512 Py_INCREF(Py_None);
513 return Py_None;
514}
515
516
Jack Jansen76a05891996-02-29 16:11:32 +0000517static char openrf_doc[] = "Open resource fork of a file";
518
519static PyObject *
520MacOS_openrf(PyObject *self, PyObject *args)
521{
522 OSErr err;
523 char *mode = "r";
524 FSSpec fss;
525 SignedByte permission = 1;
526 rfobject *fp;
527
528 if (!PyArg_ParseTuple(args, "O&|s", PyMac_GetFSSpec, &fss, &mode))
529 return NULL;
530 while (*mode) {
531 switch (*mode++) {
532 case '*': break;
533 case 'r': permission = 1; break;
534 case 'w': permission = 2; break;
535 case 'b': break;
536 default:
537 PyErr_BadArgument();
538 return NULL;
539 }
540 }
541
542 if ( (fp = newrfobject()) == NULL )
543 return NULL;
544
545 err = HOpenRF(fss.vRefNum, fss.parID, fss.name, permission, &fp->fRefNum);
546
547 if ( err == fnfErr ) {
548 /* In stead of doing complicated things here to get creator/type
549 ** correct we let the standard i/o library handle it
550 */
551 FILE *tfp;
552 char pathname[257];
553
554 if ( err=nfullpath(&fss, &pathname) ) {
555 PyMac_Error(err);
556 Py_DECREF(fp);
557 return NULL;
558 }
559
560 if ( (tfp = fopen(pathname, "w")) == NULL ) {
561 PyMac_Error(fnfErr); /* What else... */
562 Py_DECREF(fp);
563 return NULL;
564 }
565 fclose(tfp);
566 err = HOpenRF(fss.vRefNum, fss.parID, fss.name, permission, &fp->fRefNum);
567 }
568 if ( err ) {
569 Py_DECREF(fp);
570 PyMac_Error(err);
571 return NULL;
572 }
573 fp->isclosed = 0;
574 return (PyObject *)fp;
575}
576
Guido van Rossum2d167031994-09-16 10:54:21 +0000577static PyMethodDef MacOS_Methods[] = {
Guido van Rossumf74d4e21995-01-18 23:58:07 +0000578 {"AcceptHighLevelEvent", MacOS_AcceptHighLevelEvent, 1},
Guido van Rossumb7e79e51995-01-22 18:42:12 +0000579 {"GetCreatorAndType", MacOS_GetCreatorAndType, 1},
580 {"SetCreatorAndType", MacOS_SetCreatorAndType, 1},
Guido van Rossumf74d4e21995-01-18 23:58:07 +0000581#ifdef USE_STDWIN
582 {"SetHighLevelEventHandler", MacOS_SetHighLevelEventHandler, 1},
583#endif
Jack Jansene8e8ae01995-01-26 16:36:45 +0000584 {"SetScheduleTimes", MacOS_SetScheduleTimes, 1},
Jack Jansenee23d6e1995-01-27 14:43:25 +0000585 {"EnableAppswitch", MacOS_EnableAppswitch, 1},
Jack Jansena76382a1995-02-02 14:25:56 +0000586 {"HandleEvent", MacOS_HandleEvent, 1},
Jack Jansen829f88c1995-07-17 11:36:01 +0000587 {"GetErrorString", MacOS_GetErrorString, 1},
Jack Jansen76a05891996-02-29 16:11:32 +0000588 {"openrf", MacOS_openrf, 1, openrf_doc},
Jack Jansenab7fcdd1996-05-20 11:32:00 +0000589 {"splash", MacOS_splash, 1, splash_doc},
Guido van Rossumf74d4e21995-01-18 23:58:07 +0000590 {NULL, NULL} /* Sentinel */
Guido van Rossum2d167031994-09-16 10:54:21 +0000591};
592
593
594void
595MacOS_Init()
596{
597 PyObject *m, *d;
598
599 m = Py_InitModule("MacOS", MacOS_Methods);
600 d = PyModule_GetDict(m);
601
602 /* Initialize MacOS.Error exception */
Guido van Rossumbf068b11995-01-25 23:09:20 +0000603 MacOS_Error = PyMac_GetOSErrException();
Guido van Rossume433c971994-09-29 10:02:56 +0000604 if (MacOS_Error == NULL || PyDict_SetItemString(d, "Error", MacOS_Error) != 0)
Guido van Rossum2d167031994-09-16 10:54:21 +0000605 Py_FatalError("can't define MacOS.Error");
606}
Guido van Rossume7134aa1995-02-26 10:20:53 +0000607