TIVI-320: Add dbus-python to repos to support connman-test
[profile/ivi/dbus-python.git] / _dbus_bindings / module.c
1 /* Main module source for the _dbus_bindings extension.
2  *
3  * Copyright (C) 2006 Collabora Ltd. <http://www.collabora.co.uk/>
4  *
5  * Permission is hereby granted, free of charge, to any person
6  * obtaining a copy of this software and associated documentation
7  * files (the "Software"), to deal in the Software without
8  * restriction, including without limitation the rights to use, copy,
9  * modify, merge, publish, distribute, sublicense, and/or sell copies
10  * of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be
14  * included in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23  * DEALINGS IN THE SOFTWARE.
24  */
25 #include "config.h"
26
27 #include <Python.h>
28 #include <structmember.h>
29
30 #include "dbus_bindings-internal.h"
31
32 PyDoc_STRVAR(module_doc,
33 "Low-level Python bindings for libdbus. Don't use this module directly -\n"
34 "the public API is provided by the `dbus`, `dbus.service`, `dbus.mainloop`\n"
35 "and `dbus.mainloop.glib` modules, with a lower-level API provided by the\n"
36 "`dbus.lowlevel` module.\n"
37 );
38
39 /* Global functions - validation wrappers ===========================*/
40
41 PyDoc_STRVAR(validate_bus_name__doc__,
42 "validate_bus_name(name, allow_unique=True, allow_well_known=True)\n"
43 "\n"
44 "Raise ValueError if the argument is not a valid bus name.\n"
45 "\n"
46 "By default both unique and well-known names are accepted.\n"
47 "\n"
48 ":Parameters:\n"
49 "   `name` : str\n"
50 "       The name to be validated\n"
51 "   `allow_unique` : bool\n"
52 "       If False, unique names of the form :1.123 will be rejected\n"
53 "   `allow_well_known` : bool\n"
54 "       If False, well-known names of the form com.example.Foo\n"
55 "       will be rejected\n"
56 ":Since: 0.80\n"
57 );
58
59 static PyObject *
60 validate_bus_name(PyObject *unused UNUSED, PyObject *args, PyObject *kwargs)
61 {
62     const char *name;
63     int allow_unique = 1;
64     int allow_well_known = 1;
65     static char *argnames[] = { "name", "allow_unique", "allow_well_known",
66                                 NULL };
67
68     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
69                                      "s|ii:validate_bus_name", argnames,
70                                      &name, &allow_unique,
71                                      &allow_well_known)) {
72         return NULL;
73     }
74     if (!dbus_py_validate_bus_name(name, !!allow_unique, !!allow_well_known)) {
75         return NULL;
76     }
77     Py_RETURN_NONE;
78 }
79
80 PyDoc_STRVAR(validate_member_name__doc__,
81 "validate_member_name(name)\n"
82 "\n"
83 "Raise ValueError if the argument is not a valid member (signal or method) "
84 "name.\n"
85 "\n"
86 ":Since: 0.80\n"
87 );
88
89 static PyObject *
90 validate_member_name(PyObject *unused UNUSED, PyObject *args)
91 {
92     const char *name;
93
94     if (!PyArg_ParseTuple(args, "s:validate_member_name", &name)) {
95         return NULL;
96     }
97     if (!dbus_py_validate_member_name(name)) {
98         return NULL;
99     }
100     Py_RETURN_NONE;
101 }
102
103 PyDoc_STRVAR(validate_interface_name__doc__,
104 "validate_interface_name(name)\n\n"
105 "Raise ValueError if the given string is not a valid interface name.\n"
106 "\n"
107 ":Since: 0.80\n"
108 );
109
110 PyDoc_STRVAR(validate_error_name__doc__,
111 "validate_error_name(name)\n\n"
112 "Raise ValueError if the given string is not a valid error name.\n"
113 "\n"
114 ":Since: 0.80\n"
115 );
116
117 static PyObject *
118 validate_interface_name(PyObject *unused UNUSED, PyObject *args)
119 {
120     const char *name;
121
122     if (!PyArg_ParseTuple(args, "s:validate_interface_name", &name)) {
123         return NULL;
124     }
125     if (!dbus_py_validate_interface_name(name)) {
126         return NULL;
127     }
128     Py_RETURN_NONE;
129 }
130
131 PyDoc_STRVAR(validate_object_path__doc__,
132 "validate_object_path(name)\n\n"
133 "Raise ValueError if the given string is not a valid object path.\n"
134 "\n"
135 ":Since: 0.80\n"
136 );
137
138 static PyObject *
139 validate_object_path(PyObject *unused UNUSED, PyObject *args)
140 {
141     const char *name;
142
143     if (!PyArg_ParseTuple(args, "s:validate_object_path", &name)) {
144         return NULL;
145     }
146     if (!dbus_py_validate_object_path(name)) {
147         return NULL;
148     }
149     Py_RETURN_NONE;
150 }
151
152 /* Global functions - main loop =====================================*/
153
154 /* The main loop if none is passed to the constructor */
155 static PyObject *default_main_loop = NULL;
156
157 /* Return a new reference to the default main loop */
158 PyObject *
159 dbus_py_get_default_main_loop(void)
160 {
161     if (!default_main_loop) {
162         Py_RETURN_NONE;
163     }
164     Py_INCREF(default_main_loop);
165     return default_main_loop;
166 }
167
168 PyDoc_STRVAR(get_default_main_loop__doc__,
169 "get_default_main_loop() -> object\n\n"
170 "Return the global default dbus-python main loop wrapper, which is used\n"
171 "when no main loop wrapper is passed to the Connection constructor.\n"
172 "\n"
173 "If None, there is no default and you should always pass the mainloop\n"
174 "parameter to the constructor - if you don't, then asynchronous calls,\n"
175 "connecting to signals and exporting objects will raise an exception.\n"
176 "There is no default until set_default_main_loop is called.\n");
177 static PyObject *
178 get_default_main_loop(PyObject *always_null UNUSED,
179                       PyObject *no_args UNUSED)
180 {
181     return dbus_py_get_default_main_loop();
182 }
183
184 PyDoc_STRVAR(set_default_main_loop__doc__,
185 "set_default_main_loop(object)\n\n"
186 "Change the global default dbus-python main loop wrapper, which is used\n"
187 "when no main loop wrapper is passed to the Connection constructor.\n"
188 "\n"
189 "If None, return to the initial situation: there is no default, and you\n"
190 "must always pass the mainloop parameter to the constructor.\n"
191 "\n"
192 "Two types of main loop wrapper are planned in dbus-python.\n"
193 "Native main-loop wrappers are instances of `dbus.mainloop.NativeMainLoop`\n"
194 "supplied by extension modules like `dbus.mainloop.glib`: they have no\n"
195 "Python API, but connect themselves to ``libdbus`` using native code.\n"
196
197 "Python main-loop wrappers are not yet implemented. They will be objects\n"
198 "supporting the interface defined by `dbus.mainloop.MainLoop`, with an\n"
199 "API entirely based on Python methods.\n"
200 "\n"
201 );
202 static PyObject *
203 set_default_main_loop(PyObject *always_null UNUSED,
204                       PyObject *args)
205 {
206     PyObject *new_loop, *old_loop;
207
208     if (!PyArg_ParseTuple(args, "O", &new_loop)) {
209         return NULL;
210     }
211     if (!dbus_py_check_mainloop_sanity(new_loop)) {
212         return NULL;
213     }
214     old_loop = default_main_loop;
215     Py_INCREF(new_loop);
216     default_main_loop = new_loop;
217     Py_XDECREF(old_loop);
218     Py_RETURN_NONE;
219 }
220
221 static PyMethodDef module_functions[] = {
222 #define ENTRY(name,flags) {#name, (PyCFunction)name, flags, name##__doc__}
223     ENTRY(validate_interface_name, METH_VARARGS),
224     ENTRY(validate_member_name, METH_VARARGS),
225     ENTRY(validate_bus_name, METH_VARARGS|METH_KEYWORDS),
226     ENTRY(validate_object_path, METH_VARARGS),
227     ENTRY(set_default_main_loop, METH_VARARGS),
228     ENTRY(get_default_main_loop, METH_NOARGS),
229     /* validate_error_name is just implemented as validate_interface_name */
230     {"validate_error_name", validate_interface_name,
231      METH_VARARGS, validate_error_name__doc__},
232 #undef ENTRY
233     {NULL, NULL, 0, NULL}
234 };
235
236 PyMODINIT_FUNC
237 init_dbus_bindings(void)
238 {
239     PyObject *this_module, *c_api;
240     static const int API_count = DBUS_BINDINGS_API_COUNT;
241     static _dbus_py_func_ptr dbus_bindings_API[DBUS_BINDINGS_API_COUNT];
242
243     dbus_bindings_API[0] = (_dbus_py_func_ptr)&API_count;
244     dbus_bindings_API[1] = (_dbus_py_func_ptr)DBusPyConnection_BorrowDBusConnection;
245     dbus_bindings_API[2] = (_dbus_py_func_ptr)DBusPyNativeMainLoop_New4;
246
247     default_main_loop = NULL;
248
249     /* I'd rather not initialize threads if we can help it - dbus-python and
250     pygobject both release and re-obtain the GIL on a regular basis, which is
251     much simpler (basically free) before threads are initialized.
252
253     However, on Python < 2.4.2c1 you aren't allowed to call
254     PyGILState_Release without initializing threads first. */
255     if (strcmp(Py_GetVersion(), "2.4.2c1") < 0) {
256         PyEval_InitThreads();
257     }
258
259     if (!dbus_py_init_generic()) return;
260     if (!dbus_py_init_abstract()) return;
261     if (!dbus_py_init_signature()) return;
262     if (!dbus_py_init_int_types()) return;
263     if (!dbus_py_init_string_types()) return;
264     if (!dbus_py_init_float_types()) return;
265     if (!dbus_py_init_container_types()) return;
266     if (!dbus_py_init_byte_types()) return;
267     if (!dbus_py_init_message_types()) return;
268     if (!dbus_py_init_pending_call()) return;
269     if (!dbus_py_init_mainloop()) return;
270     if (!dbus_py_init_libdbus_conn_types()) return;
271     if (!dbus_py_init_conn_types()) return;
272     if (!dbus_py_init_server_types()) return;
273
274     this_module = Py_InitModule3("_dbus_bindings", module_functions, module_doc);
275     if (!this_module) return;
276
277     if (!dbus_py_insert_abstract_types(this_module)) return;
278     if (!dbus_py_insert_signature(this_module)) return;
279     if (!dbus_py_insert_int_types(this_module)) return;
280     if (!dbus_py_insert_string_types(this_module)) return;
281     if (!dbus_py_insert_float_types(this_module)) return;
282     if (!dbus_py_insert_container_types(this_module)) return;
283     if (!dbus_py_insert_byte_types(this_module)) return;
284     if (!dbus_py_insert_message_types(this_module)) return;
285     if (!dbus_py_insert_pending_call(this_module)) return;
286     if (!dbus_py_insert_mainloop_types(this_module)) return;
287     if (!dbus_py_insert_libdbus_conn_types(this_module)) return;
288     if (!dbus_py_insert_conn_types(this_module)) return;
289     if (!dbus_py_insert_server_types(this_module)) return;
290
291     if (PyModule_AddStringConstant(this_module, "BUS_DAEMON_NAME",
292                                    DBUS_SERVICE_DBUS) < 0) return;
293     if (PyModule_AddStringConstant(this_module, "BUS_DAEMON_PATH",
294                                    DBUS_PATH_DBUS) < 0) return;
295     if (PyModule_AddStringConstant(this_module, "BUS_DAEMON_IFACE",
296                                    DBUS_INTERFACE_DBUS) < 0) return;
297     if (PyModule_AddStringConstant(this_module, "LOCAL_PATH",
298                                    DBUS_PATH_LOCAL) < 0) return;
299     if (PyModule_AddStringConstant(this_module, "LOCAL_IFACE",
300                                    DBUS_INTERFACE_LOCAL) < 0) return;
301     if (PyModule_AddStringConstant(this_module, "INTROSPECTABLE_IFACE",
302                                    DBUS_INTERFACE_INTROSPECTABLE) < 0) return;
303     if (PyModule_AddStringConstant(this_module, "PEER_IFACE",
304                                    DBUS_INTERFACE_PEER) < 0) return;
305     if (PyModule_AddStringConstant(this_module, "PROPERTIES_IFACE",
306                                    DBUS_INTERFACE_PROPERTIES) < 0) return;
307     if (PyModule_AddStringConstant(this_module,
308                 "DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER",
309                 DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER) < 0) return;
310     if (PyModule_AddStringConstant(this_module,
311                 "DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER",
312                 DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER) < 0) return;
313     if (PyModule_AddStringConstant(this_module,
314                 "DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE",
315                 DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE) < 0) return;
316
317 #define ADD_CONST_VAL(x, v) \
318     if (PyModule_AddIntConstant(this_module, x, v) < 0) return;
319 #define ADD_CONST_PREFIXED(x) ADD_CONST_VAL(#x, DBUS_##x)
320 #define ADD_CONST(x) ADD_CONST_VAL(#x, x)
321
322     ADD_CONST(DBUS_START_REPLY_SUCCESS)
323     ADD_CONST(DBUS_START_REPLY_ALREADY_RUNNING)
324
325     ADD_CONST_PREFIXED(RELEASE_NAME_REPLY_RELEASED)
326     ADD_CONST_PREFIXED(RELEASE_NAME_REPLY_NON_EXISTENT)
327     ADD_CONST_PREFIXED(RELEASE_NAME_REPLY_NOT_OWNER)
328
329     ADD_CONST_PREFIXED(REQUEST_NAME_REPLY_PRIMARY_OWNER)
330     ADD_CONST_PREFIXED(REQUEST_NAME_REPLY_IN_QUEUE)
331     ADD_CONST_PREFIXED(REQUEST_NAME_REPLY_EXISTS)
332     ADD_CONST_PREFIXED(REQUEST_NAME_REPLY_ALREADY_OWNER)
333
334     ADD_CONST_PREFIXED(NAME_FLAG_ALLOW_REPLACEMENT)
335     ADD_CONST_PREFIXED(NAME_FLAG_REPLACE_EXISTING)
336     ADD_CONST_PREFIXED(NAME_FLAG_DO_NOT_QUEUE)
337
338     ADD_CONST_PREFIXED(BUS_SESSION)
339     ADD_CONST_PREFIXED(BUS_SYSTEM)
340     ADD_CONST_PREFIXED(BUS_STARTER)
341
342     ADD_CONST_PREFIXED(MESSAGE_TYPE_INVALID)
343     ADD_CONST_PREFIXED(MESSAGE_TYPE_METHOD_CALL)
344     ADD_CONST_PREFIXED(MESSAGE_TYPE_METHOD_RETURN)
345     ADD_CONST_PREFIXED(MESSAGE_TYPE_ERROR)
346     ADD_CONST_PREFIXED(MESSAGE_TYPE_SIGNAL)
347
348     ADD_CONST_PREFIXED(TYPE_INVALID)
349     ADD_CONST_PREFIXED(TYPE_BYTE)
350     ADD_CONST_PREFIXED(TYPE_BOOLEAN)
351     ADD_CONST_PREFIXED(TYPE_INT16)
352     ADD_CONST_PREFIXED(TYPE_UINT16)
353     ADD_CONST_PREFIXED(TYPE_INT32)
354     ADD_CONST_PREFIXED(TYPE_UINT32)
355     ADD_CONST_PREFIXED(TYPE_INT64)
356     ADD_CONST_PREFIXED(TYPE_UINT64)
357     ADD_CONST_PREFIXED(TYPE_DOUBLE)
358     ADD_CONST_PREFIXED(TYPE_STRING)
359     ADD_CONST_PREFIXED(TYPE_OBJECT_PATH)
360     ADD_CONST_PREFIXED(TYPE_SIGNATURE)
361     ADD_CONST_PREFIXED(TYPE_ARRAY)
362     ADD_CONST_PREFIXED(TYPE_STRUCT)
363     ADD_CONST_VAL("STRUCT_BEGIN", DBUS_STRUCT_BEGIN_CHAR)
364     ADD_CONST_VAL("STRUCT_END", DBUS_STRUCT_END_CHAR)
365     ADD_CONST_PREFIXED(TYPE_VARIANT)
366     ADD_CONST_PREFIXED(TYPE_DICT_ENTRY)
367     ADD_CONST_VAL("DICT_ENTRY_BEGIN", DBUS_DICT_ENTRY_BEGIN_CHAR)
368     ADD_CONST_VAL("DICT_ENTRY_END", DBUS_DICT_ENTRY_END_CHAR)
369
370     ADD_CONST_PREFIXED(HANDLER_RESULT_HANDLED)
371     ADD_CONST_PREFIXED(HANDLER_RESULT_NOT_YET_HANDLED)
372     ADD_CONST_PREFIXED(HANDLER_RESULT_NEED_MEMORY)
373
374     ADD_CONST_PREFIXED(WATCH_READABLE)
375     ADD_CONST_PREFIXED(WATCH_WRITABLE)
376     ADD_CONST_PREFIXED(WATCH_HANGUP)
377     ADD_CONST_PREFIXED(WATCH_ERROR)
378
379     if (PyModule_AddStringConstant(this_module, "__docformat__",
380                                    "restructuredtext") < 0) return;
381
382     if (PyModule_AddStringConstant(this_module, "__version__",
383                                    PACKAGE_VERSION) < 0) return;
384
385     if (PyModule_AddIntConstant(this_module, "_python_version",
386                                 PY_VERSION_HEX) < 0) return;
387
388     c_api = PyCObject_FromVoidPtr ((void *)dbus_bindings_API, NULL);
389     if (!c_api) {
390         return;
391     }
392     PyModule_AddObject(this_module, "_C_API", c_api);
393 }
394
395 /* vim:set ft=c cino< sw=4 sts=4 et: */