Actually commit the numerous copyright-statement changes.
[dbus-python-phuang.git] / _dbus_bindings / module.c
blob480df33207b6ca48b0a265c317a8475de1b4fcad
1 /* Main module source for the _dbus_bindings extension.
2  *
3  * Copyright (C) 2006 Collabora Ltd.
4  *
5  * Licensed under the Academic Free License version 2.1
6  *
7  * This library is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License as published by
9  * the Free Software Foundation; either version 2.1 of the License, or
10  * (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  */
22 #include "config.h"
24 #include <Python.h>
25 #include <structmember.h>
27 #include "dbus_bindings-internal.h"
29 PyDoc_STRVAR(module_doc,
30 "Low-level Python bindings for libdbus. Don't use this module directly -\n"
31 "the public API is provided by the `dbus`, `dbus.service`, `dbus.mainloop`\n"
32 "and `dbus.mainloop.glib` modules, with a lower-level API provided by the\n"
33 "`dbus.lowlevel` module.\n"
36 /* Global functions - validation wrappers ===========================*/
38 PyDoc_STRVAR(validate_bus_name__doc__,
39 "validate_bus_name(name, allow_unique=True, allow_well_known=True)\n"
40 "\n"
41 "Raise ValueError if the argument is not a valid bus name.\n"
42 "\n"
43 "By default both unique and well-known names are accepted.\n"
44 "\n"
45 ":Parameters:\n"
46 "   `name` : str\n"
47 "       The name to be validated\n"
48 "   `allow_unique` : bool\n"
49 "       If False, unique names of the form :1.123 will be rejected\n"
50 "   `allow_well_known` : bool\n"
51 "       If False, well-known names of the form com.example.Foo\n"
52 "       will be rejected\n"
53 ":Since: 0.80\n"
56 static PyObject *
57 validate_bus_name(PyObject *unused UNUSED, PyObject *args, PyObject *kwargs)
59     const char *name;
60     int allow_unique = 1;
61     int allow_well_known = 1;
62     static char *argnames[] = { "name", "allow_unique", "allow_well_known",
63                                 NULL };
65     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
66                                      "s|ii:validate_bus_name", argnames,
67                                      &name, &allow_unique,
68                                      &allow_well_known)) {
69         return NULL;
70     }
71     if (!dbus_py_validate_bus_name(name, !!allow_unique, !!allow_well_known)) {
72         return NULL;
73     }
74     Py_RETURN_NONE;
77 PyDoc_STRVAR(validate_member_name__doc__,
78 "validate_member_name(name)\n"
79 "\n"
80 "Raise ValueError if the argument is not a valid member (signal or method) "
81 "name.\n"
82 "\n"
83 ":Since: 0.80\n"
86 static PyObject *
87 validate_member_name(PyObject *unused UNUSED, PyObject *args)
89     const char *name;
91     if (!PyArg_ParseTuple(args, "s:validate_member_name", &name)) {
92         return NULL;
93     }
94     if (!dbus_py_validate_member_name(name)) {
95         return NULL;
96     }
97     Py_RETURN_NONE;
100 PyDoc_STRVAR(validate_interface_name__doc__,
101 "validate_interface_name(name)\n\n"
102 "Raise ValueError if the given string is not a valid interface name.\n"
103 "\n"
104 ":Since: 0.80\n"
107 PyDoc_STRVAR(validate_error_name__doc__,
108 "validate_error_name(name)\n\n"
109 "Raise ValueError if the given string is not a valid error name.\n"
110 "\n"
111 ":Since: 0.80\n"
114 static PyObject *
115 validate_interface_name(PyObject *unused UNUSED, PyObject *args)
117     const char *name;
119     if (!PyArg_ParseTuple(args, "s:validate_interface_name", &name)) {
120         return NULL;
121     }
122     if (!dbus_py_validate_interface_name(name)) {
123         return NULL;
124     }
125     Py_RETURN_NONE;
128 PyDoc_STRVAR(validate_object_path__doc__,
129 "validate_object_path(name)\n\n"
130 "Raise ValueError if the given string is not a valid object path.\n"
131 "\n"
132 ":Since: 0.80\n"
135 static PyObject *
136 validate_object_path(PyObject *unused UNUSED, PyObject *args)
138     const char *name;
140     if (!PyArg_ParseTuple(args, "s:validate_object_path", &name)) {
141         return NULL;
142     }
143     if (!dbus_py_validate_object_path(name)) {
144         return NULL;
145     }
146     Py_RETURN_NONE;
149 /* Global functions - main loop =====================================*/
151 /* The main loop if none is passed to the constructor */
152 static PyObject *default_main_loop = NULL;
154 /* Return a new reference to the default main loop */
155 PyObject *
156 dbus_py_get_default_main_loop(void)
158     if (!default_main_loop) {
159         Py_RETURN_NONE;
160     }
161     Py_INCREF(default_main_loop);
162     return default_main_loop;
165 PyDoc_STRVAR(get_default_main_loop__doc__,
166 "get_default_main_loop() -> object\n\n"
167 "Return the global default dbus-python main loop wrapper, which is used\n"
168 "when no main loop wrapper is passed to the Connection constructor.\n"
169 "\n"
170 "If None, there is no default and you should always pass the mainloop\n"
171 "parameter to the constructor - if you don't, then asynchronous calls,\n"
172 "connecting to signals and exporting objects will raise an exception.\n"
173 "There is no default until set_default_main_loop is called.\n");
174 static PyObject *
175 get_default_main_loop(PyObject *always_null UNUSED,
176                       PyObject *no_args UNUSED)
178     return dbus_py_get_default_main_loop();
181 PyDoc_STRVAR(set_default_main_loop__doc__,
182 "set_default_main_loop(object)\n\n"
183 "Change the global default dbus-python main loop wrapper, which is used\n"
184 "when no main loop wrapper is passed to the Connection constructor.\n"
185 "\n"
186 "If None, return to the initial situation: there is no default, and you\n"
187 "must always pass the mainloop parameter to the constructor.\n"
188 "\n"
189 "Two types of main loop wrapper are planned in dbus-python.\n"
190 "Native main-loop wrappers are instances of `dbus.mainloop.NativeMainLoop`\n"
191 "supplied by extension modules like `dbus.mainloop.glib`: they have no\n"
192 "Python API, but connect themselves to ``libdbus`` using native code.\n"
194 "Python main-loop wrappers are not yet implemented. They will be objects\n"
195 "supporting the interface defined by `dbus.mainloop.MainLoop`, with an\n"
196 "API entirely based on Python methods.\n"
197 "\n"
199 static PyObject *
200 set_default_main_loop(PyObject *always_null UNUSED,
201                       PyObject *args)
203     PyObject *new_loop, *old_loop;
205     if (!PyArg_ParseTuple(args, "O", &new_loop)) {
206         return NULL;
207     }
208     if (!dbus_py_check_mainloop_sanity(new_loop)) {
209         return NULL;
210     }
211     old_loop = default_main_loop;
212     Py_INCREF(new_loop);
213     default_main_loop = new_loop;
214     Py_XDECREF(old_loop);
215     Py_RETURN_NONE;
218 static PyMethodDef module_functions[] = {
219 #define ENTRY(name,flags) {#name, (PyCFunction)name, flags, name##__doc__}
220     ENTRY(validate_interface_name, METH_VARARGS),
221     ENTRY(validate_member_name, METH_VARARGS),
222     ENTRY(validate_bus_name, METH_VARARGS|METH_KEYWORDS),
223     ENTRY(validate_object_path, METH_VARARGS),
224     ENTRY(set_default_main_loop, METH_VARARGS),
225     ENTRY(get_default_main_loop, METH_NOARGS),
226     /* validate_error_name is just implemented as validate_interface_name */
227     {"validate_error_name", validate_interface_name,
228      METH_VARARGS, validate_error_name__doc__},
229 #undef ENTRY
230     {NULL, NULL, 0, NULL}
233 PyMODINIT_FUNC
234 init_dbus_bindings(void)
236     PyObject *this_module, *c_api;
237     static const int API_count = DBUS_BINDINGS_API_COUNT;
238     static _dbus_py_func_ptr dbus_bindings_API[DBUS_BINDINGS_API_COUNT];
240     dbus_bindings_API[0] = (_dbus_py_func_ptr)&API_count;
241     dbus_bindings_API[1] = (_dbus_py_func_ptr)DBusPyConnection_BorrowDBusConnection;
242     dbus_bindings_API[2] = (_dbus_py_func_ptr)DBusPyNativeMainLoop_New4;
244     default_main_loop = NULL;
246     /* I'd rather not initialize threads if we can help it - dbus-python and
247     pygobject both release and re-obtain the GIL on a regular basis, which is
248     much simpler (basically free) before threads are initialized.
250     However, on Python < 2.4.2c1 you aren't allowed to call
251     PyGILState_Release without initializing threads first. */
252     if (strcmp(Py_GetVersion(), "2.4.2c1") < 0) {
253         PyEval_InitThreads();
254     }
256     if (!dbus_py_init_generic()) return;
257     if (!dbus_py_init_exception_types()) return;
258     if (!dbus_py_init_abstract()) return;
259     if (!dbus_py_init_signature()) return;
260     if (!dbus_py_init_int_types()) return;
261     if (!dbus_py_init_string_types()) return;
262     if (!dbus_py_init_float_types()) return;
263     if (!dbus_py_init_container_types()) return;
264     if (!dbus_py_init_byte_types()) return;
265     if (!dbus_py_init_message_types()) return;
266     if (!dbus_py_init_pending_call()) return;
267     if (!dbus_py_init_mainloop()) return;
268     if (!dbus_py_init_conn_types()) return;
269     if (!dbus_py_init_bus_types()) return;
271     this_module = Py_InitModule3("_dbus_bindings", module_functions, module_doc);
272     if (!this_module) return;
274     if (!dbus_py_insert_exception_types(this_module)) return;
275     if (!dbus_py_insert_abstract_types(this_module)) return;
276     if (!dbus_py_insert_signature(this_module)) return;
277     if (!dbus_py_insert_int_types(this_module)) return;
278     if (!dbus_py_insert_string_types(this_module)) return;
279     if (!dbus_py_insert_float_types(this_module)) return;
280     if (!dbus_py_insert_container_types(this_module)) return;
281     if (!dbus_py_insert_byte_types(this_module)) return;
282     if (!dbus_py_insert_message_types(this_module)) return;
283     if (!dbus_py_insert_pending_call(this_module)) return;
284     if (!dbus_py_insert_mainloop_types(this_module)) return;
285     if (!dbus_py_insert_conn_types(this_module)) return;
286     if (!dbus_py_insert_bus_types(this_module)) return;
288 #define ADD_CONST_VAL(x, v) \
289     if (PyModule_AddIntConstant(this_module, x, v) < 0) return;
290 #define ADD_CONST_PREFIXED(x) ADD_CONST_VAL(#x, DBUS_##x)
291 #define ADD_CONST(x) ADD_CONST_VAL(#x, x)
293     ADD_CONST(DBUS_START_REPLY_SUCCESS)
294     ADD_CONST(DBUS_START_REPLY_ALREADY_RUNNING)
296     ADD_CONST_PREFIXED(RELEASE_NAME_REPLY_RELEASED)
297     ADD_CONST_PREFIXED(RELEASE_NAME_REPLY_NON_EXISTENT)
298     ADD_CONST_PREFIXED(RELEASE_NAME_REPLY_NOT_OWNER)
300     ADD_CONST_PREFIXED(REQUEST_NAME_REPLY_PRIMARY_OWNER)
301     ADD_CONST_PREFIXED(REQUEST_NAME_REPLY_IN_QUEUE)
302     ADD_CONST_PREFIXED(REQUEST_NAME_REPLY_EXISTS)
303     ADD_CONST_PREFIXED(REQUEST_NAME_REPLY_ALREADY_OWNER)
305     ADD_CONST_PREFIXED(NAME_FLAG_ALLOW_REPLACEMENT)
306     ADD_CONST_PREFIXED(NAME_FLAG_REPLACE_EXISTING)
307     ADD_CONST_PREFIXED(NAME_FLAG_DO_NOT_QUEUE)
309     ADD_CONST_PREFIXED(BUS_SESSION)
310     ADD_CONST_PREFIXED(BUS_SYSTEM)
311     ADD_CONST_PREFIXED(BUS_STARTER)
313     ADD_CONST_PREFIXED(MESSAGE_TYPE_INVALID)
314     ADD_CONST_PREFIXED(MESSAGE_TYPE_METHOD_CALL)
315     ADD_CONST_PREFIXED(MESSAGE_TYPE_METHOD_RETURN)
316     ADD_CONST_PREFIXED(MESSAGE_TYPE_ERROR)
317     ADD_CONST_PREFIXED(MESSAGE_TYPE_SIGNAL)
319     ADD_CONST_PREFIXED(MESSAGE_TYPE_SIGNAL)
321     ADD_CONST_PREFIXED(TYPE_INVALID)
322     ADD_CONST_PREFIXED(TYPE_BYTE)
323     ADD_CONST_PREFIXED(TYPE_BOOLEAN)
324     ADD_CONST_PREFIXED(TYPE_INT16)
325     ADD_CONST_PREFIXED(TYPE_UINT16)
326     ADD_CONST_PREFIXED(TYPE_INT32)
327     ADD_CONST_PREFIXED(TYPE_UINT32)
328     ADD_CONST_PREFIXED(TYPE_INT64)
329     ADD_CONST_PREFIXED(TYPE_UINT64)
330     ADD_CONST_PREFIXED(TYPE_DOUBLE)
331     ADD_CONST_PREFIXED(TYPE_STRING)
332     ADD_CONST_PREFIXED(TYPE_OBJECT_PATH)
333     ADD_CONST_PREFIXED(TYPE_SIGNATURE)
334     ADD_CONST_PREFIXED(TYPE_ARRAY)
335     ADD_CONST_PREFIXED(TYPE_STRUCT)
336     ADD_CONST_VAL("STRUCT_BEGIN", DBUS_STRUCT_BEGIN_CHAR)
337     ADD_CONST_VAL("STRUCT_END", DBUS_STRUCT_END_CHAR)
338     ADD_CONST_PREFIXED(TYPE_VARIANT)
339     ADD_CONST_PREFIXED(TYPE_DICT_ENTRY)
340     ADD_CONST_VAL("DICT_ENTRY_BEGIN", DBUS_DICT_ENTRY_BEGIN_CHAR)
341     ADD_CONST_VAL("DICT_ENTRY_END", DBUS_DICT_ENTRY_END_CHAR)
343     ADD_CONST_PREFIXED(HANDLER_RESULT_HANDLED)
344     ADD_CONST_PREFIXED(HANDLER_RESULT_NOT_YET_HANDLED)
345     ADD_CONST_PREFIXED(HANDLER_RESULT_NEED_MEMORY)
347     ADD_CONST_PREFIXED(WATCH_READABLE)
348     ADD_CONST_PREFIXED(WATCH_WRITABLE)
349     ADD_CONST_PREFIXED(WATCH_HANGUP)
350     ADD_CONST_PREFIXED(WATCH_ERROR)
352     if (PyModule_AddStringConstant(this_module, "__docformat__",
353                                    "restructuredtext") < 0) return;
355     if (PyModule_AddStringConstant(this_module, "__version__",
356                                    PACKAGE_VERSION) < 0) return;
358     if (PyModule_AddIntConstant(this_module, "_python_version",
359                                 PY_VERSION_HEX) < 0) return;
361     c_api = PyCObject_FromVoidPtr ((void *)dbus_bindings_API, NULL);
362     if (!c_api) {
363         return;
364     }
365     PyModule_AddObject(this_module, "_C_API", c_api);
368 /* vim:set ft=c cino< sw=4 sts=4 et: */