blob: 741e985590fb40cc5f73f65c5016048de3be74fb [file] [log] [blame]
Jack Jansenf93c72a1994-12-14 14:07:50 +00001/*
2** macglue - A couple of mac-specific routines often needed.
3**
4** Jack Jansen, CWI, 1994.
Jack Jansen5f653091995-01-18 13:53:49 +00005** Some routines by Guido, moved here from macosmodule.c
6** (since they are useable by other modules as well).
Jack Jansenf93c72a1994-12-14 14:07:50 +00007*/
Jack Jansenf93c72a1994-12-14 14:07:50 +00008#ifdef HAVE_CONFIG_H
9#include "config.h"
10#endif
11
12#include "Python.h"
13#include "macglue.h"
14
15#include <OSUtils.h> /* for Set(Current)A5 */
16#include <Resources.h>
17#include <Memory.h>
18#include <Events.h>
19#include <Windows.h>
20#include <Desk.h>
21
Jack Jansen5f653091995-01-18 13:53:49 +000022/* We should include Errors.h here, but it has a name conflict
23** with the python errors.h. */
24#define fnfErr -43
25
26/* Convert C to Pascal string. Returns pointer to static buffer. */
27unsigned char *
28Pstring(char *str)
29{
30 static Str255 buf;
31 int len;
32
33 len = strlen(str);
34 buf[0] = (unsigned char)len;
35 strncpy((char *)buf+1, str, len);
36 return buf;
37}
38
Jack Jansenf93c72a1994-12-14 14:07:50 +000039/* Replace strerror with something that might work */
40char *macstrerror(int err)
41{
42 static char buf[256];
43 Handle h;
44 char *str;
45
46 h = GetResource('Estr', err);
47 if ( h ) {
48 HLock(h);
49 str = (char *)*h;
50 memcpy(buf, str+1, (unsigned char)str[0]);
51 HUnlock(h);
52 ReleaseResource(h);
53 } else {
54 sprintf(buf, "Mac OS error code %d", err);
55 }
56 return buf;
57}
58
59/* Set a MAC-specific error from errno, and return NULL; return None if no error */
60PyObject *
Guido van Rossumfffb8bb1995-01-12 12:37:24 +000061PyErr_Mac(PyObject *eobj, int err)
Jack Jansenf93c72a1994-12-14 14:07:50 +000062{
63 char *msg;
64 PyObject *v;
Jack Jansenf93c72a1994-12-14 14:07:50 +000065
Guido van Rossum8f691791995-01-18 23:57:26 +000066 if (err == 0 && !PyErr_Occurred()) {
Jack Jansenf93c72a1994-12-14 14:07:50 +000067 Py_INCREF(Py_None);
68 return Py_None;
69 }
Guido van Rossum8f691791995-01-18 23:57:26 +000070 if (err == -1 && PyErr_Occurred())
71 return NULL;
Jack Jansenf93c72a1994-12-14 14:07:50 +000072 msg = macstrerror(err);
73 v = Py_BuildValue("(is)", err, msg);
74 PyErr_SetObject(eobj, v);
75 Py_DECREF(v);
76 return NULL;
77}
78
79/*
80** Idle routine for busy-wait loops.
81** This is rather tricky: if we see an event we check whether it is
82** for somebody else (i.e. a click outside our windows) and, if so,
83** we pass the event on (so the user can switch processes). However,
84** by doing this we loose events meant for our windows. Too bad, I guess...
85*/
86int
87PyMac_Idle()
88{
89 EventRecord ev;
90 WindowPtr wp;
91
Jack Jansenf93c72a1994-12-14 14:07:50 +000092 SystemTask();
Jack Jansen5f653091995-01-18 13:53:49 +000093 if ( intrpeek() )
Jack Jansenf93c72a1994-12-14 14:07:50 +000094 return 0;
95 if ( GetNextEvent(0xffff, &ev) ) {
96 if ( ev.what == mouseDown ) {
97 if ( FindWindow(ev.where, &wp) == inSysWindow )
98 SystemClick(&ev, wp);
99 }
100 }
Jack Jansenf93c72a1994-12-14 14:07:50 +0000101 return 1;
102}
103
Jack Jansen5f653091995-01-18 13:53:49 +0000104
105/* Convert a ResType argument */
106int
Guido van Rossum8f691791995-01-18 23:57:26 +0000107PyMac_GetOSType(PyObject *v, ResType *pr)
Jack Jansen5f653091995-01-18 13:53:49 +0000108{
109 if (!PyString_Check(v) || PyString_Size(v) != 4) {
110 PyErr_SetString(PyExc_TypeError,
111 "OSType arg must be string of 4 chars");
112 return 0;
113 }
114 memcpy((char *)pr, PyString_AsString(v), 4);
115 return 1;
116}
117
118/* Convert a Str255 argument */
119int
Guido van Rossum8f691791995-01-18 23:57:26 +0000120PyMac_GetStr255(PyObject *v, Str255 pbuf)
Jack Jansen5f653091995-01-18 13:53:49 +0000121{
122 int len;
123 if (!PyString_Check(v) || (len = PyString_Size(v)) > 255) {
124 PyErr_SetString(PyExc_TypeError,
125 "Str255 arg must be string of at most 255 chars");
126 return 0;
127 }
128 pbuf[0] = len;
129 memcpy((char *)(pbuf+1), PyString_AsString(v), len);
130 return 1;
131}
132
133/*
134** Convert anything resembling an FSSpec argument
135** NOTE: This routine will fail on pre-sys7 machines.
136** The caller is responsible for not calling this routine
137** in those cases (which is fine, since everyone calling
138** this is probably sys7 dependent anyway).
139*/
140int
Guido van Rossum8f691791995-01-18 23:57:26 +0000141PyMac_GetFSSpec(PyObject *v, FSSpec *fs)
Jack Jansen5f653091995-01-18 13:53:49 +0000142{
143 Str255 path;
144 short refnum;
145 long parid;
146 OSErr err;
147
148 if ( PyString_Check(v) ) {
149 /* It's a pathname */
150 if( !PyArg_Parse(v, "O&", GetStr255, &path) )
151 return 0;
152 refnum = 0; /* XXXX Should get CurWD here... */
153 parid = 0;
154 } else {
155 PyErr_Clear();
156 if( !PyArg_Parse(v, "(hlO&); FSSpec should be fullpath or (int,int,string)",
157 &refnum, &parid, GetStr255, &path))
158 return 0;
159 }
160 err = FSMakeFSSpec(refnum, parid, path, fs);
161 if ( err && err != fnfErr ) {
162 PyErr_SetString(PyExc_TypeError,
163 "FSMakeFSSpec error");
164 return 0;
165 }
166 return 1;
167}
168
169/*
170** Return a python object that describes an FSSpec
171*/
172PyObject *
173PyMac_BuildFSSpec(FSSpec *fs)
174{
175 return Py_BuildValue("(iis#)", fs->vRefNum, fs->parID, &fs->name[1], fs->name[0]);
176}
Guido van Rossum8f691791995-01-18 23:57:26 +0000177
178/* Convert an OSType value to a 4-char string object */
179PyObject *
180PyMac_BuildOSType(OSType t)
181{
182 return PyString_FromStringAndSize((char *)&t, 4);
183}