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 or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
15 permission.
16 
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
20 
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
29 
30 ******************************************************************/
31 
32 #include "Python.h"
33 #include "pymactoolbox.h"
34 
35 extern int ResObj_Convert(PyObject *, Handle *); /* From Resmodule.c */
36 
37 #include <Carbon/Carbon.h>
38 
39 static PyObject *ErrorObject;
40 
41 /* ----------------------------------------------------- */
42 
43 /* Declarations for objects of type ic_instance */
44 
45 typedef struct {
46     PyObject_HEAD
47     ICInstance inst;
48 } iciobject;
49 
50 static PyTypeObject Icitype;
51 
52 
53 
54 /* ---------------------------------------------------------------- */
55 
56 
57 static char ici_ICGetSeed__doc__[] =
58 "()->int; Returns int that changes when configuration does"
59 ;
60 
61 static PyObject *
ici_ICGetSeed(iciobject * self,PyObject * args)62 ici_ICGetSeed(iciobject *self, PyObject *args)
63 {
64     OSStatus err;
65     long seed;
66 
67     if (!PyArg_ParseTuple(args, ""))
68         return NULL;
69     if ((err=ICGetSeed(self->inst, &seed)) != 0 )
70         return PyMac_Error(err);
71     return Py_BuildValue("i", (int)seed);
72 }
73 
74 
75 static char ici_ICBegin__doc__[] =
76 "(perm)->None; Lock config file for read/write"
77 ;
78 
79 static PyObject *
ici_ICBegin(iciobject * self,PyObject * args)80 ici_ICBegin(iciobject *self, PyObject *args)
81 {
82     OSStatus err;
83     int perm;
84 
85     if (!PyArg_ParseTuple(args, "i", &perm))
86         return NULL;
87     if ((err=ICBegin(self->inst, (ICPerm)perm)) != 0 )
88         return PyMac_Error(err);
89     Py_INCREF(Py_None);
90     return Py_None;
91 }
92 
93 
94 static char ici_ICFindPrefHandle__doc__[] =
95 "(key, handle)->attrs; Lookup key, store result in handle, return attributes"
96 ;
97 
98 static PyObject *
ici_ICFindPrefHandle(iciobject * self,PyObject * args)99 ici_ICFindPrefHandle(iciobject *self, PyObject *args)
100 {
101     OSStatus err;
102     Str255 key;
103     ICAttr attr;
104     Handle h;
105 
106     if (!PyArg_ParseTuple(args, "O&O&", PyMac_GetStr255, &key, ResObj_Convert, &h))
107         return NULL;
108     if ((err=ICFindPrefHandle(self->inst, key, &attr, h)) != 0 )
109         return PyMac_Error(err);
110     return Py_BuildValue("i", (int)attr);
111 }
112 
113 
114 static char ici_ICSetPref__doc__[] =
115 "(key, attr, data)->None; Set preference key to data with attributes"
116 ;
117 
118 static PyObject *
ici_ICSetPref(iciobject * self,PyObject * args)119 ici_ICSetPref(iciobject *self, PyObject *args)
120 {
121     OSStatus err;
122     Str255 key;
123     int attr;
124     char *data;
125     int datalen;
126 
127     if (!PyArg_ParseTuple(args, "O&is#", PyMac_GetStr255, &key, &attr,
128                                     &data, &datalen))
129         return NULL;
130     if ((err=ICSetPref(self->inst, key, (ICAttr)attr, (Ptr)data,
131                     (long)datalen)) != 0)
132         return PyMac_Error(err);
133     Py_INCREF(Py_None);
134     return Py_None;
135 }
136 
137 
138 static char ici_ICCountPref__doc__[] =
139 "()->int; Return number of preferences"
140 ;
141 
142 static PyObject *
ici_ICCountPref(iciobject * self,PyObject * args)143 ici_ICCountPref(iciobject *self, PyObject *args)
144 {
145     OSStatus err;
146     long count;
147 
148     if (!PyArg_ParseTuple(args, ""))
149         return NULL;
150     if ((err=ICCountPref(self->inst, &count)) != 0 )
151         return PyMac_Error(err);
152     return Py_BuildValue("i", (int)count);
153 }
154 
155 
156 static char ici_ICGetIndPref__doc__[] =
157 "(num)->key; Return key of preference with given index"
158 ;
159 
160 static PyObject *
ici_ICGetIndPref(iciobject * self,PyObject * args)161 ici_ICGetIndPref(iciobject *self, PyObject *args)
162 {
163     OSStatus err;
164     long num;
165     Str255 key;
166 
167     if (!PyArg_ParseTuple(args, "l", &num))
168         return NULL;
169     if ((err=ICGetIndPref(self->inst, num, key)) != 0 )
170         return PyMac_Error(err);
171     return Py_BuildValue("O&", PyMac_BuildStr255, key);
172 }
173 
174 
175 static char ici_ICDeletePref__doc__[] =
176 "(key)->None; Delete preference"
177 ;
178 
179 static PyObject *
ici_ICDeletePref(iciobject * self,PyObject * args)180 ici_ICDeletePref(iciobject *self, PyObject *args)
181 {
182     OSStatus err;
183     Str255 key;
184 
185     if (!PyArg_ParseTuple(args, "O&", PyMac_GetStr255, key))
186         return NULL;
187     if ((err=ICDeletePref(self->inst, key)) != 0 )
188         return PyMac_Error(err);
189     Py_INCREF(Py_None);
190     return Py_None;
191 }
192 
193 
194 static char ici_ICEnd__doc__[] =
195 "()->None; Unlock file after ICBegin call"
196 ;
197 
198 static PyObject *
ici_ICEnd(iciobject * self,PyObject * args)199 ici_ICEnd(iciobject *self, PyObject *args)
200 {
201     OSStatus err;
202 
203     if (!PyArg_ParseTuple(args, ""))
204         return NULL;
205     if ((err=ICEnd(self->inst)) != 0 )
206         return PyMac_Error(err);
207     Py_INCREF(Py_None);
208     return Py_None;
209 }
210 
211 
212 static char ici_ICEditPreferences__doc__[] =
213 "(key)->None; Ask user to edit preferences, staring with key"
214 ;
215 
216 static PyObject *
ici_ICEditPreferences(iciobject * self,PyObject * args)217 ici_ICEditPreferences(iciobject *self, PyObject *args)
218 {
219     OSStatus err;
220     Str255 key;
221 
222     if (!PyArg_ParseTuple(args, "O&", PyMac_GetStr255, key))
223         return NULL;
224     if ((err=ICEditPreferences(self->inst, key)) != 0 )
225         return PyMac_Error(err);
226     Py_INCREF(Py_None);
227     return Py_None;
228 }
229 
230 
231 static char ici_ICParseURL__doc__[] =
232 "(hint, data, selStart, selEnd, handle)->selStart, selEnd; Find a URL, return in handle"
233 ;
234 
235 static PyObject *
ici_ICParseURL(iciobject * self,PyObject * args)236 ici_ICParseURL(iciobject *self, PyObject *args)
237 {
238     OSStatus err;
239     Str255 hint;
240     char *data;
241     int datalen;
242     long selStart, selEnd;
243     Handle h;
244 
245     if (!PyArg_ParseTuple(args, "O&s#llO&", PyMac_GetStr255, hint, &data, &datalen,
246                             &selStart, &selEnd, ResObj_Convert, &h))
247         return NULL;
248     if ((err=ICParseURL(self->inst, hint, (Ptr)data, (long)datalen,
249                             &selStart, &selEnd, h)) != 0 )
250         return PyMac_Error(err);
251     return Py_BuildValue("ii", (int)selStart, (int)selEnd);
252 }
253 
254 
255 static char ici_ICLaunchURL__doc__[] =
256 "(hint, data, selStart, selEnd)->None; Find a URL and launch the correct app"
257 ;
258 
259 static PyObject *
ici_ICLaunchURL(iciobject * self,PyObject * args)260 ici_ICLaunchURL(iciobject *self, PyObject *args)
261 {
262     OSStatus err;
263     Str255 hint;
264     char *data;
265     int datalen;
266     long selStart, selEnd;
267 
268     if (!PyArg_ParseTuple(args, "O&s#ll", PyMac_GetStr255, hint, &data, &datalen,
269                             &selStart, &selEnd))
270         return NULL;
271     if ((err=ICLaunchURL(self->inst, hint, (Ptr)data, (long)datalen,
272                             &selStart, &selEnd)) != 0 )
273         return PyMac_Error(err);
274     return Py_BuildValue("ii", (int)selStart, (int)selEnd);
275 }
276 
277 
278 static char ici_ICMapFilename__doc__[] =
279 "(filename)->mapinfo; Get filemap info for given filename"
280 ;
281 
282 static PyObject *
ici_ICMapFilename(iciobject * self,PyObject * args)283 ici_ICMapFilename(iciobject *self, PyObject *args)
284 {
285     OSStatus err;
286     Str255 filename;
287     ICMapEntry entry;
288 
289     if (!PyArg_ParseTuple(args, "O&", PyMac_GetStr255, filename))
290         return NULL;
291     if ((err=ICMapFilename(self->inst, filename, &entry)) != 0 )
292         return PyMac_Error(err);
293     return Py_BuildValue("hO&O&O&lO&O&O&O&O&", entry.version,
294         PyMac_BuildOSType, entry.fileType,
295         PyMac_BuildOSType, entry.fileCreator,
296         PyMac_BuildOSType, entry.postCreator,
297         entry.flags,
298         PyMac_BuildStr255, entry.extension,
299         PyMac_BuildStr255, entry.creatorAppName,
300         PyMac_BuildStr255, entry.postAppName,
301         PyMac_BuildStr255, entry.MIMEType,
302         PyMac_BuildStr255, entry.entryName);
303 }
304 
305 
306 static char ici_ICMapTypeCreator__doc__[] =
307 "(type, creator, filename)->mapinfo; Get filemap info for given tp/cr/filename"
308 ;
309 
310 static PyObject *
ici_ICMapTypeCreator(iciobject * self,PyObject * args)311 ici_ICMapTypeCreator(iciobject *self, PyObject *args)
312 {
313     OSStatus err;
314     OSType type, creator;
315     Str255 filename;
316     ICMapEntry entry;
317 
318     if (!PyArg_ParseTuple(args, "O&O&O&",
319                     PyMac_GetOSType, &type,
320                     PyMac_GetOSType, &creator,
321                     PyMac_GetStr255, filename))
322         return NULL;
323     if ((err=ICMapTypeCreator(self->inst, type, creator, filename, &entry)) != 0 )
324         return PyMac_Error(err);
325     return Py_BuildValue("hO&O&O&lO&O&O&O&O&", entry.version,
326         PyMac_BuildOSType, entry.fileType,
327         PyMac_BuildOSType, entry.fileCreator,
328         PyMac_BuildOSType, entry.postCreator,
329         entry.flags,
330         PyMac_BuildStr255, entry.extension,
331         PyMac_BuildStr255, entry.creatorAppName,
332         PyMac_BuildStr255, entry.postAppName,
333         PyMac_BuildStr255, entry.MIMEType,
334         PyMac_BuildStr255, entry.entryName);
335 }
336 
337 
338 static struct PyMethodDef ici_methods[] = {
339  {"ICGetSeed",  (PyCFunction)ici_ICGetSeed,     METH_VARARGS,   ici_ICGetSeed__doc__},
340  {"ICBegin",    (PyCFunction)ici_ICBegin,       METH_VARARGS,   ici_ICBegin__doc__},
341  {"ICFindPrefHandle",   (PyCFunction)ici_ICFindPrefHandle,      METH_VARARGS,   ici_ICFindPrefHandle__doc__},
342  {"ICSetPref",  (PyCFunction)ici_ICSetPref,     METH_VARARGS,   ici_ICSetPref__doc__},
343  {"ICCountPref",        (PyCFunction)ici_ICCountPref,   METH_VARARGS,   ici_ICCountPref__doc__},
344  {"ICGetIndPref",       (PyCFunction)ici_ICGetIndPref,  METH_VARARGS,   ici_ICGetIndPref__doc__},
345  {"ICDeletePref",       (PyCFunction)ici_ICDeletePref,  METH_VARARGS,   ici_ICDeletePref__doc__},
346  {"ICEnd",      (PyCFunction)ici_ICEnd, METH_VARARGS,   ici_ICEnd__doc__},
347  {"ICEditPreferences",  (PyCFunction)ici_ICEditPreferences,     METH_VARARGS,   ici_ICEditPreferences__doc__},
348  {"ICParseURL", (PyCFunction)ici_ICParseURL,    METH_VARARGS,   ici_ICParseURL__doc__},
349  {"ICLaunchURL",        (PyCFunction)ici_ICLaunchURL,   METH_VARARGS,   ici_ICLaunchURL__doc__},
350  {"ICMapFilename",      (PyCFunction)ici_ICMapFilename, METH_VARARGS,   ici_ICMapFilename__doc__},
351  {"ICMapTypeCreator",   (PyCFunction)ici_ICMapTypeCreator,      METH_VARARGS,   ici_ICMapTypeCreator__doc__},
352 
353     {NULL,              NULL}           /* sentinel */
354 };
355 
356 /* ---------- */
357 
358 
359 static iciobject *
newiciobject(OSType creator)360 newiciobject(OSType creator)
361 {
362     iciobject *self;
363     OSStatus err;
364 
365     self = PyObject_NEW(iciobject, &Icitype);
366     if (self == NULL)
367         return NULL;
368     if ((err=ICStart(&self->inst, creator)) != 0 ) {
369         (void)PyMac_Error(err);
370         PyObject_DEL(self);
371         return NULL;
372     }
373     return self;
374 }
375 
376 
377 static void
ici_dealloc(iciobject * self)378 ici_dealloc(iciobject *self)
379 {
380     (void)ICStop(self->inst);
381     PyObject_DEL(self);
382 }
383 
384 static PyObject *
ici_getattr(iciobject * self,char * name)385 ici_getattr(iciobject *self, char *name)
386 {
387     return Py_FindMethod(ici_methods, (PyObject *)self, name);
388 }
389 
390 static char Icitype__doc__[] =
391 "Internet Config instance"
392 ;
393 
394 static PyTypeObject Icitype = {
395     PyObject_HEAD_INIT(&PyType_Type)
396     0,                                  /*ob_size*/
397     "icglue.ic_instance",               /*tp_name*/
398     sizeof(iciobject),                  /*tp_basicsize*/
399     0,                                  /*tp_itemsize*/
400     /* methods */
401     (destructor)ici_dealloc,            /*tp_dealloc*/
402     (printfunc)0,               /*tp_print*/
403     (getattrfunc)ici_getattr,           /*tp_getattr*/
404     (setattrfunc)0,     /*tp_setattr*/
405     (cmpfunc)0,                 /*tp_compare*/
406     (reprfunc)0,                /*tp_repr*/
407     0,                          /*tp_as_number*/
408     0,                  /*tp_as_sequence*/
409     0,                  /*tp_as_mapping*/
410     (hashfunc)0,                /*tp_hash*/
411     (ternaryfunc)0,             /*tp_call*/
412     (reprfunc)0,                /*tp_str*/
413 
414     /* Space for future expansion */
415     0L,0L,0L,0L,
416     Icitype__doc__ /* Documentation string */
417 };
418 
419 /* End of code for ic_instance objects */
420 /* -------------------------------------------------------- */
421 
422 
423 static char ic_ICStart__doc__[] =
424 "(OSType)->ic_instance; Create an Internet Config instance"
425 ;
426 
427 static PyObject *
ic_ICStart(PyObject * self,PyObject * args)428 ic_ICStart(PyObject *self, PyObject *args)
429 {
430     OSType creator;
431 
432     if (!PyArg_ParseTuple(args, "O&", PyMac_GetOSType, &creator))
433         return NULL;
434     return (PyObject *)newiciobject(creator);
435 }
436 
437 /* List of methods defined in the module */
438 
439 static struct PyMethodDef ic_methods[] = {
440     {"ICStart",         (PyCFunction)ic_ICStart,        METH_VARARGS,   ic_ICStart__doc__},
441 
442     {NULL,       (PyCFunction)NULL, 0, NULL}            /* sentinel */
443 };
444 
445 
446 /* Initialization function for the module (*must* be called initicglue) */
447 
448 static char icglue_module_documentation[] =
449 "Implements low-level Internet Config interface"
450 ;
451 
452 void
initicglue(void)453 initicglue(void)
454 {
455     PyObject *m, *d;
456 
457     if (PyErr_WarnPy3k("In 3.x, the icglue module is removed.", 1))
458         return;
459 
460     /* Create the module and add the functions */
461     m = Py_InitModule4("icglue", ic_methods,
462         icglue_module_documentation,
463         (PyObject*)NULL,PYTHON_API_VERSION);
464 
465     /* Add some symbolic constants to the module */
466     d = PyModule_GetDict(m);
467     ErrorObject = PyMac_GetOSErrException();
468     if (ErrorObject == NULL ||
469         PyDict_SetItemString(d, "error", ErrorObject) != 0)
470         return;
471 
472     /* XXXX Add constants here */
473 
474     /* Check for errors */
475     if (PyErr_Occurred())
476         Py_FatalError("can't initialize module icglue");
477 }
478 
479