1/***********************************************************
2Copyright 1991-1997 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
4
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 or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
16
17While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
29
30******************************************************************/
31
32#include "Python.h"
33#include "pymactoolbox.h"
34
35extern int ResObj_Convert(PyObject *, Handle *); /* From Resmodule.c */
36
37#include <Carbon/Carbon.h>
38
39static PyObject *ErrorObject;
40
41/* ----------------------------------------------------- */
42
43/* Declarations for objects of type ic_instance */
44
45typedef struct {
46    PyObject_HEAD
47    ICInstance inst;
48} iciobject;
49
50static PyTypeObject Icitype;
51
52
53
54/* ---------------------------------------------------------------- */
55
56
57static char ici_ICGetSeed__doc__[] =
58"()->int; Returns int that changes when configuration does"
59;
60
61static PyObject *
62ici_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
75static char ici_ICBegin__doc__[] =
76"(perm)->None; Lock config file for read/write"
77;
78
79static PyObject *
80ici_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
94static char ici_ICFindPrefHandle__doc__[] =
95"(key, handle)->attrs; Lookup key, store result in handle, return attributes"
96;
97
98static PyObject *
99ici_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
114static char ici_ICSetPref__doc__[] =
115"(key, attr, data)->None; Set preference key to data with attributes"
116;
117
118static PyObject *
119ici_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
138static char ici_ICCountPref__doc__[] =
139"()->int; Return number of preferences"
140;
141
142static PyObject *
143ici_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
156static char ici_ICGetIndPref__doc__[] =
157"(num)->key; Return key of preference with given index"
158;
159
160static PyObject *
161ici_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
175static char ici_ICDeletePref__doc__[] =
176"(key)->None; Delete preference"
177;
178
179static PyObject *
180ici_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
194static char ici_ICEnd__doc__[] =
195"()->None; Unlock file after ICBegin call"
196;
197
198static PyObject *
199ici_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
212static char ici_ICEditPreferences__doc__[] =
213"(key)->None; Ask user to edit preferences, staring with key"
214;
215
216static PyObject *
217ici_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
231static char ici_ICParseURL__doc__[] =
232"(hint, data, selStart, selEnd, handle)->selStart, selEnd; Find a URL, return in handle"
233;
234
235static PyObject *
236ici_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
255static char ici_ICLaunchURL__doc__[] =
256"(hint, data, selStart, selEnd)->None; Find a URL and launch the correct app"
257;
258
259static PyObject *
260ici_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
278static char ici_ICMapFilename__doc__[] =
279"(filename)->mapinfo; Get filemap info for given filename"
280;
281
282static PyObject *
283ici_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
306static char ici_ICMapTypeCreator__doc__[] =
307"(type, creator, filename)->mapinfo; Get filemap info for given tp/cr/filename"
308;
309
310static PyObject *
311ici_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
338static 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
359static iciobject *
360newiciobject(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
377static void
378ici_dealloc(iciobject *self)
379{
380    (void)ICStop(self->inst);
381    PyObject_DEL(self);
382}
383
384static PyObject *
385ici_getattr(iciobject *self, char *name)
386{
387    return Py_FindMethod(ici_methods, (PyObject *)self, name);
388}
389
390static char Icitype__doc__[] =
391"Internet Config instance"
392;
393
394static 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
423static char ic_ICStart__doc__[] =
424"(OSType)->ic_instance; Create an Internet Config instance"
425;
426
427static PyObject *
428ic_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
439static 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
448static char icglue_module_documentation[] =
449"Implements low-level Internet Config interface"
450;
451
452void
453initicglue(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