|
1 /*********************************************************** |
|
2 Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam, |
|
3 The Netherlands. |
|
4 |
|
5 All Rights Reserved |
|
6 |
|
7 Permission to use, copy, modify, and distribute this software and its |
|
8 documentation for any purpose and without fee is hereby granted, |
|
9 provided that the above copyright notice appear in all copies and that |
|
10 both that copyright notice and this permission notice appear in |
|
11 supporting documentation, and that the names of Stichting Mathematisch |
|
12 Centrum or CWI not be used in advertising or publicity pertaining to |
|
13 distribution of the software without specific, written prior permission. |
|
14 |
|
15 STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO |
|
16 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND |
|
17 FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE |
|
18 FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT |
|
21 OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
22 |
|
23 ******************************************************************/ |
|
24 |
|
25 /* Macintosh OS-specific interface */ |
|
26 |
|
27 #include "Python.h" |
|
28 #include "pymactoolbox.h" |
|
29 |
|
30 #include <Carbon/Carbon.h> |
|
31 #include <ApplicationServices/ApplicationServices.h> |
|
32 |
|
33 #ifndef HAVE_OSX105_SDK |
|
34 typedef SInt16 FSIORefNum; |
|
35 #endif |
|
36 |
|
37 static PyObject *MacOS_Error; /* Exception MacOS.Error */ |
|
38 |
|
39 #define PATHNAMELEN 1024 |
|
40 |
|
41 /* ----------------------------------------------------- */ |
|
42 |
|
43 /* Declarations for objects of type Resource fork */ |
|
44 |
|
45 typedef struct { |
|
46 PyObject_HEAD |
|
47 FSIORefNum fRefNum; |
|
48 int isclosed; |
|
49 } rfobject; |
|
50 |
|
51 static PyTypeObject Rftype; |
|
52 |
|
53 |
|
54 |
|
55 /* ---------------------------------------------------------------- */ |
|
56 |
|
57 static void |
|
58 do_close(rfobject *self) |
|
59 { |
|
60 if (self->isclosed ) return; |
|
61 (void)FSCloseFork(self->fRefNum); |
|
62 self->isclosed = 1; |
|
63 } |
|
64 |
|
65 static char rf_read__doc__[] = |
|
66 "Read data from resource fork" |
|
67 ; |
|
68 |
|
69 static PyObject * |
|
70 rf_read(rfobject *self, PyObject *args) |
|
71 { |
|
72 long n; |
|
73 PyObject *v; |
|
74 OSErr err; |
|
75 ByteCount n2; |
|
76 |
|
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 |
|
85 v = PyBytes_FromStringAndSize((char *)NULL, n); |
|
86 if (v == NULL) |
|
87 return NULL; |
|
88 |
|
89 err = FSReadFork(self->fRefNum, fsAtMark, 0, n, PyString_AsString(v), &n2); |
|
90 if (err && err != eofErr) { |
|
91 PyMac_Error(err); |
|
92 Py_DECREF(v); |
|
93 return NULL; |
|
94 } |
|
95 _PyString_Resize(&v, n2); |
|
96 return v; |
|
97 } |
|
98 |
|
99 |
|
100 static char rf_write__doc__[] = |
|
101 "Write to resource fork" |
|
102 ; |
|
103 |
|
104 static PyObject * |
|
105 rf_write(rfobject *self, PyObject *args) |
|
106 { |
|
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 } |
|
115 if (!PyArg_ParseTuple(args, "s#", &buffer, &size)) |
|
116 return NULL; |
|
117 err = FSWriteFork(self->fRefNum, fsAtMark, 0, size, buffer, NULL); |
|
118 if (err) { |
|
119 PyMac_Error(err); |
|
120 return NULL; |
|
121 } |
|
122 Py_INCREF(Py_None); |
|
123 return Py_None; |
|
124 } |
|
125 |
|
126 |
|
127 static char rf_seek__doc__[] = |
|
128 "Set file position" |
|
129 ; |
|
130 |
|
131 static PyObject * |
|
132 rf_seek(rfobject *self, PyObject *args) |
|
133 { |
|
134 long amount; |
|
135 int whence = SEEK_SET; |
|
136 int mode; |
|
137 OSErr err; |
|
138 |
|
139 if (self->isclosed) { |
|
140 PyErr_SetString(PyExc_ValueError, "Operation on closed file"); |
|
141 return NULL; |
|
142 } |
|
143 if (!PyArg_ParseTuple(args, "l|i", &amount, &whence)) { |
|
144 return NULL; |
|
145 } |
|
146 |
|
147 switch (whence) { |
|
148 case SEEK_CUR: |
|
149 mode = fsFromMark; |
|
150 break; |
|
151 case SEEK_END: |
|
152 mode = fsFromLEOF; |
|
153 break; |
|
154 case SEEK_SET: |
|
155 mode = fsFromStart; |
|
156 break; |
|
157 default: |
|
158 PyErr_BadArgument(); |
|
159 return NULL; |
|
160 } |
|
161 |
|
162 err = FSSetForkPosition(self->fRefNum, mode, amount); |
|
163 if (err != noErr) { |
|
164 PyMac_Error(err); |
|
165 return NULL; |
|
166 } |
|
167 Py_INCREF(Py_None); |
|
168 return Py_None; |
|
169 } |
|
170 |
|
171 |
|
172 static char rf_tell__doc__[] = |
|
173 "Get file position" |
|
174 ; |
|
175 |
|
176 static PyObject * |
|
177 rf_tell(rfobject *self, PyObject *args) |
|
178 { |
|
179 long long where; |
|
180 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; |
|
188 |
|
189 err = FSGetForkPosition(self->fRefNum, &where); |
|
190 if (err != noErr) { |
|
191 PyMac_Error(err); |
|
192 return NULL; |
|
193 } |
|
194 return PyLong_FromLongLong(where); |
|
195 } |
|
196 |
|
197 static char rf_close__doc__[] = |
|
198 "Close resource fork" |
|
199 ; |
|
200 |
|
201 static PyObject * |
|
202 rf_close(rfobject *self, PyObject *args) |
|
203 { |
|
204 if (!PyArg_ParseTuple(args, "")) |
|
205 return NULL; |
|
206 do_close(self); |
|
207 Py_INCREF(Py_None); |
|
208 return Py_None; |
|
209 } |
|
210 |
|
211 |
|
212 static struct PyMethodDef rf_methods[] = { |
|
213 {"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__}, |
|
218 |
|
219 {NULL, NULL} /* sentinel */ |
|
220 }; |
|
221 |
|
222 /* ---------- */ |
|
223 |
|
224 |
|
225 static rfobject * |
|
226 newrfobject(void) |
|
227 { |
|
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 |
|
238 static void |
|
239 rf_dealloc(rfobject *self) |
|
240 { |
|
241 do_close(self); |
|
242 PyObject_DEL(self); |
|
243 } |
|
244 |
|
245 static PyObject * |
|
246 rf_getattr(rfobject *self, char *name) |
|
247 { |
|
248 return Py_FindMethod(rf_methods, (PyObject *)self, name); |
|
249 } |
|
250 |
|
251 static char Rftype__doc__[] = |
|
252 "Resource fork file object" |
|
253 ; |
|
254 |
|
255 static PyTypeObject Rftype = { |
|
256 PyObject_HEAD_INIT(&PyType_Type) |
|
257 0, /*ob_size*/ |
|
258 "MacOS.ResourceFork", /*tp_name*/ |
|
259 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 |
|
280 |
|
281 /* End of code for Resource fork objects */ |
|
282 /* -------------------------------------------------------- */ |
|
283 |
|
284 /*----------------------------------------------------------------------*/ |
|
285 /* Miscellaneous File System Operations */ |
|
286 |
|
287 static char getcrtp_doc[] = "Get MacOS 4-char creator and type for a file"; |
|
288 |
|
289 static PyObject * |
|
290 MacOS_GetCreatorAndType(PyObject *self, PyObject *args) |
|
291 { |
|
292 PyObject *creator, *type, *res; |
|
293 OSErr err; |
|
294 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__ */ |
|
321 return NULL; |
|
322 #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 |
|
347 res = Py_BuildValue("OO", creator, type); |
|
348 Py_DECREF(creator); |
|
349 Py_DECREF(type); |
|
350 return res; |
|
351 } |
|
352 |
|
353 static char setcrtp_doc[] = "Set MacOS 4-char creator and type for a file"; |
|
354 |
|
355 static PyObject * |
|
356 MacOS_SetCreatorAndType(PyObject *self, PyObject *args) |
|
357 { |
|
358 ResType creator, type; |
|
359 FSRef ref; |
|
360 FileInfo* finfo; |
|
361 OSErr err; |
|
362 FSCatalogInfo cataloginfo; |
|
363 |
|
364 if (!PyArg_ParseTuple(args, "O&O&O&", |
|
365 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&", |
|
372 PyMac_GetFSSpec, &fss, PyMac_GetOSType, &creator, PyMac_GetOSType, &type)) |
|
373 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__ */ |
|
386 return NULL; |
|
387 #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 |
|
418 Py_INCREF(Py_None); |
|
419 return Py_None; |
|
420 } |
|
421 |
|
422 |
|
423 static char geterr_doc[] = "Convert OSErr number to string"; |
|
424 |
|
425 static PyObject * |
|
426 MacOS_GetErrorString(PyObject *self, PyObject *args) |
|
427 { |
|
428 int err; |
|
429 char buf[256]; |
|
430 Handle h; |
|
431 char *str; |
|
432 static int errors_loaded; |
|
433 |
|
434 if (!PyArg_ParseTuple(args, "i", &err)) |
|
435 return NULL; |
|
436 |
|
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 |
|
447 m = PyImport_ImportModuleNoBlock("macresource"); |
|
448 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 } |
|
465 Py_DECREF(m); |
|
466 } |
|
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); |
|
487 } |
|
488 |
|
489 |
|
490 #ifndef __LP64__ |
|
491 |
|
492 static char splash_doc[] = "Open a splash-screen dialog by resource-id (0=close)"; |
|
493 |
|
494 static PyObject * |
|
495 MacOS_splash(PyObject *self, PyObject *args) |
|
496 { |
|
497 int resid = -1; |
|
498 static DialogPtr curdialog = NULL; |
|
499 DialogPtr olddialog; |
|
500 WindowRef theWindow; |
|
501 CGrafPtr thePort; |
|
502 #if 0 |
|
503 short xpos, ypos, width, height, swidth, sheight; |
|
504 #endif |
|
505 |
|
506 if (!PyArg_ParseTuple(args, "|i", &resid)) |
|
507 return NULL; |
|
508 olddialog = curdialog; |
|
509 curdialog = NULL; |
|
510 |
|
511 if ( resid != -1 ) { |
|
512 curdialog = GetNewDialog(resid, NULL, (WindowPtr)-1); |
|
513 if ( curdialog ) { |
|
514 theWindow = GetDialogWindow(curdialog); |
|
515 thePort = GetWindowPort(theWindow); |
|
516 #if 0 |
|
517 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); |
|
525 #endif |
|
526 DrawDialog(curdialog); |
|
527 } |
|
528 } |
|
529 if (olddialog) |
|
530 DisposeDialog(olddialog); |
|
531 Py_INCREF(Py_None); |
|
532 return Py_None; |
|
533 } |
|
534 |
|
535 static char DebugStr_doc[] = "Switch to low-level debugger with a message"; |
|
536 |
|
537 static PyObject * |
|
538 MacOS_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; |
|
545 |
|
546 DebugStr(message); |
|
547 Py_INCREF(Py_None); |
|
548 return Py_None; |
|
549 } |
|
550 |
|
551 |
|
552 static char SysBeep_doc[] = "BEEEEEP!!!"; |
|
553 |
|
554 static PyObject * |
|
555 MacOS_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 |
|
566 #endif /* __LP64__ */ |
|
567 |
|
568 static 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 |
|
573 static PyObject * |
|
574 MacOS_WMAvailable(PyObject *self, PyObject *args) |
|
575 { |
|
576 static PyObject *rv = NULL; |
|
577 |
|
578 if (!PyArg_ParseTuple(args, "")) |
|
579 return NULL; |
|
580 if (!rv) { |
|
581 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 */ |
|
590 #ifdef kCGNullDirectDisplay |
|
591 /* On 10.1 CGMainDisplayID() isn't available, and |
|
592 ** kCGNullDirectDisplay isn't defined. |
|
593 */ |
|
594 if (CGMainDisplayID() == 0) { |
|
595 rv = Py_False; |
|
596 } else { |
|
597 #else |
|
598 { |
|
599 #endif |
|
600 if (GetCurrentProcess(&psn) < 0 || |
|
601 SetFrontProcess(&psn) < 0) { |
|
602 rv = Py_False; |
|
603 } else { |
|
604 rv = Py_True; |
|
605 } |
|
606 } |
|
607 } |
|
608 Py_INCREF(rv); |
|
609 return rv; |
|
610 } |
|
611 |
|
612 static char GetTicks_doc[] = "Return number of ticks since bootup"; |
|
613 |
|
614 static PyObject * |
|
615 MacOS_GetTicks(PyObject *self, PyObject *args) |
|
616 { |
|
617 return Py_BuildValue("i", (int)TickCount()); |
|
618 } |
|
619 |
|
620 static char openrf_doc[] = "Open resource fork of a file"; |
|
621 |
|
622 static PyObject * |
|
623 MacOS_openrf(PyObject *self, PyObject *args) |
|
624 { |
|
625 OSErr err; |
|
626 char *mode = "r"; |
|
627 FSRef ref; |
|
628 SInt8 permission = fsRdPerm; |
|
629 rfobject *fp; |
|
630 HFSUniStr255 name; |
|
631 |
|
632 if (!PyArg_ParseTuple(args, "O&|s", PyMac_GetFSRef, &ref, &mode)) |
|
633 return NULL; |
|
634 while (*mode) { |
|
635 switch (*mode++) { |
|
636 case '*': break; |
|
637 case 'r': permission = fsRdPerm; break; |
|
638 case 'w': permission = fsWrPerm; break; |
|
639 case 'b': break; |
|
640 default: |
|
641 PyErr_BadArgument(); |
|
642 return NULL; |
|
643 } |
|
644 } |
|
645 |
|
646 err = FSGetResourceForkName(&name); |
|
647 if (err != noErr) { |
|
648 PyMac_Error(err); |
|
649 return NULL; |
|
650 } |
|
651 |
|
652 if ( (fp = newrfobject()) == NULL ) |
|
653 return NULL; |
|
654 |
|
655 |
|
656 err = FSOpenFork(&ref, name.length, name.unicode, permission, &fp->fRefNum); |
|
657 if (err != noErr) { |
|
658 Py_DECREF(fp); |
|
659 PyMac_Error(err); |
|
660 return NULL; |
|
661 } |
|
662 fp->isclosed = 0; |
|
663 return (PyObject *)fp; |
|
664 } |
|
665 |
|
666 |
|
667 |
|
668 static PyMethodDef MacOS_Methods[] = { |
|
669 {"GetCreatorAndType", MacOS_GetCreatorAndType, 1, getcrtp_doc}, |
|
670 {"SetCreatorAndType", MacOS_SetCreatorAndType, 1, setcrtp_doc}, |
|
671 {"GetErrorString", MacOS_GetErrorString, 1, geterr_doc}, |
|
672 {"openrf", MacOS_openrf, 1, openrf_doc}, |
|
673 #ifndef __LP64__ |
|
674 {"splash", MacOS_splash, 1, splash_doc}, |
|
675 {"DebugStr", MacOS_DebugStr, 1, DebugStr_doc}, |
|
676 {"SysBeep", MacOS_SysBeep, 1, SysBeep_doc}, |
|
677 #endif /* __LP64__ */ |
|
678 {"GetTicks", MacOS_GetTicks, 1, GetTicks_doc}, |
|
679 {"WMAvailable", MacOS_WMAvailable, 1, WMAvailable_doc}, |
|
680 {NULL, NULL} /* Sentinel */ |
|
681 }; |
|
682 |
|
683 |
|
684 void |
|
685 initMacOS(void) |
|
686 { |
|
687 PyObject *m, *d; |
|
688 |
|
689 if (PyErr_WarnPy3k("In 3.x, MacOS is removed.", 1)) |
|
690 return; |
|
691 |
|
692 m = Py_InitModule("MacOS", MacOS_Methods); |
|
693 d = PyModule_GetDict(m); |
|
694 |
|
695 /* Initialize MacOS.Error exception */ |
|
696 MacOS_Error = PyMac_GetOSErrException(); |
|
697 if (MacOS_Error == NULL || PyDict_SetItemString(d, "Error", MacOS_Error) != 0) |
|
698 return; |
|
699 Rftype.ob_type = &PyType_Type; |
|
700 Py_INCREF(&Rftype); |
|
701 if (PyDict_SetItemString(d, "ResourceForkType", (PyObject *)&Rftype) != 0) |
|
702 return; |
|
703 /* |
|
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 { |
|
709 PyStringObject *p = 0; |
|
710 long off = (long)&(p->ob_sval[0]); |
|
711 |
|
712 if( PyDict_SetItemString(d, "string_id_to_buffer", Py_BuildValue("i", off)) != 0) |
|
713 return; |
|
714 } |
|
715 #define PY_RUNTIMEMODEL "macho" |
|
716 if (PyDict_SetItemString(d, "runtimemodel", |
|
717 Py_BuildValue("s", PY_RUNTIMEMODEL)) != 0) |
|
718 return; |
|
719 #if defined(WITH_NEXT_FRAMEWORK) |
|
720 #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 |
|
730 } |