Imported Upstream version 1.2.0
[platform/upstream/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_CLEAR(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 #ifdef PY3
238 PyInit__dbus_bindings(void)
239 #else
240 init_dbus_bindings(void)
241 #endif
242 {
243     PyObject *this_module = NULL, *c_api;
244     static const int API_count = DBUS_BINDINGS_API_COUNT;
245     static _dbus_py_func_ptr dbus_bindings_API[DBUS_BINDINGS_API_COUNT];
246
247 #ifdef PY3
248     static struct PyModuleDef moduledef = {
249         PyModuleDef_HEAD_INIT,
250         "_dbus_bindings",       /* m_name */
251         module_doc,             /* m_doc */
252         -1,                     /* m_size */
253         module_functions,       /* m_methods */
254         NULL,                   /* m_reload */
255         NULL,                   /* m_traverse */
256         NULL,                   /* m_clear */
257         NULL                    /* m_free */
258     };
259 #endif
260
261     dbus_bindings_API[0] = (_dbus_py_func_ptr)&API_count;
262     dbus_bindings_API[1] = (_dbus_py_func_ptr)DBusPyConnection_BorrowDBusConnection;
263     dbus_bindings_API[2] = (_dbus_py_func_ptr)DBusPyNativeMainLoop_New4;
264
265     default_main_loop = NULL;
266
267     if (!dbus_py_init_generic()) goto init_error;
268     if (!dbus_py_init_abstract()) goto init_error;
269     if (!dbus_py_init_signature()) goto init_error;
270     if (!dbus_py_init_int_types()) goto init_error;
271     if (!dbus_py_init_unixfd_type()) goto init_error;
272     if (!dbus_py_init_string_types()) goto init_error;
273     if (!dbus_py_init_float_types()) goto init_error;
274     if (!dbus_py_init_container_types()) goto init_error;
275     if (!dbus_py_init_byte_types()) goto init_error;
276     if (!dbus_py_init_message_types()) goto init_error;
277     if (!dbus_py_init_pending_call()) goto init_error;
278     if (!dbus_py_init_mainloop()) goto init_error;
279     if (!dbus_py_init_libdbus_conn_types()) goto init_error;
280     if (!dbus_py_init_conn_types()) goto init_error;
281     if (!dbus_py_init_server_types()) goto init_error;
282
283 #ifdef PY3
284     this_module = PyModule_Create(&moduledef);
285 #else
286     this_module = Py_InitModule3("_dbus_bindings",
287                                  module_functions, module_doc);
288 #endif
289     if (!this_module) goto init_error;
290
291     if (!dbus_py_insert_abstract_types(this_module)) goto init_error;
292     if (!dbus_py_insert_signature(this_module)) goto init_error;
293     if (!dbus_py_insert_int_types(this_module)) goto init_error;
294     if (!dbus_py_insert_unixfd_type(this_module)) goto init_error;
295     if (!dbus_py_insert_string_types(this_module)) goto init_error;
296     if (!dbus_py_insert_float_types(this_module)) goto init_error;
297     if (!dbus_py_insert_container_types(this_module)) goto init_error;
298     if (!dbus_py_insert_byte_types(this_module)) goto init_error;
299     if (!dbus_py_insert_message_types(this_module)) goto init_error;
300     if (!dbus_py_insert_pending_call(this_module)) goto init_error;
301     if (!dbus_py_insert_mainloop_types(this_module)) goto init_error;
302     if (!dbus_py_insert_libdbus_conn_types(this_module)) goto init_error;
303     if (!dbus_py_insert_conn_types(this_module)) goto init_error;
304     if (!dbus_py_insert_server_types(this_module)) goto init_error;
305
306     if (PyModule_AddStringConstant(this_module, "BUS_DAEMON_NAME",
307                                    DBUS_SERVICE_DBUS) < 0) goto init_error;
308     if (PyModule_AddStringConstant(this_module, "BUS_DAEMON_PATH",
309                                    DBUS_PATH_DBUS) < 0) goto init_error;
310     if (PyModule_AddStringConstant(this_module, "BUS_DAEMON_IFACE",
311                                    DBUS_INTERFACE_DBUS) < 0) goto init_error;
312     if (PyModule_AddStringConstant(this_module, "LOCAL_PATH",
313                                    DBUS_PATH_LOCAL) < 0) goto init_error;
314     if (PyModule_AddStringConstant(this_module, "LOCAL_IFACE",
315                                    DBUS_INTERFACE_LOCAL) < 0) goto init_error;
316     if (PyModule_AddStringConstant(this_module, "INTROSPECTABLE_IFACE",
317                                    DBUS_INTERFACE_INTROSPECTABLE) < 0)
318         goto init_error;
319     if (PyModule_AddStringConstant(this_module, "PEER_IFACE",
320                                    DBUS_INTERFACE_PEER) < 0) goto init_error;
321     if (PyModule_AddStringConstant(this_module, "PROPERTIES_IFACE",
322                                    DBUS_INTERFACE_PROPERTIES) < 0)
323         goto init_error;
324     if (PyModule_AddStringConstant(this_module,
325                 "DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER",
326                 DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER) < 0)
327         goto init_error;
328     if (PyModule_AddStringConstant(this_module,
329                 "DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER",
330                 DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER) < 0)
331         goto init_error;
332     if (PyModule_AddStringConstant(this_module,
333                 "DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE",
334                 DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE) < 0)
335         goto init_error;
336
337 #define ADD_CONST_VAL(x, v) \
338     if (PyModule_AddIntConstant(this_module, x, v) < 0) goto init_error;
339 #define ADD_CONST_PREFIXED(x) ADD_CONST_VAL(#x, DBUS_##x)
340 #define ADD_CONST(x) ADD_CONST_VAL(#x, x)
341
342     ADD_CONST(DBUS_START_REPLY_SUCCESS)
343     ADD_CONST(DBUS_START_REPLY_ALREADY_RUNNING)
344
345     ADD_CONST_PREFIXED(RELEASE_NAME_REPLY_RELEASED)
346     ADD_CONST_PREFIXED(RELEASE_NAME_REPLY_NON_EXISTENT)
347     ADD_CONST_PREFIXED(RELEASE_NAME_REPLY_NOT_OWNER)
348
349     ADD_CONST_PREFIXED(REQUEST_NAME_REPLY_PRIMARY_OWNER)
350     ADD_CONST_PREFIXED(REQUEST_NAME_REPLY_IN_QUEUE)
351     ADD_CONST_PREFIXED(REQUEST_NAME_REPLY_EXISTS)
352     ADD_CONST_PREFIXED(REQUEST_NAME_REPLY_ALREADY_OWNER)
353
354     ADD_CONST_PREFIXED(NAME_FLAG_ALLOW_REPLACEMENT)
355     ADD_CONST_PREFIXED(NAME_FLAG_REPLACE_EXISTING)
356     ADD_CONST_PREFIXED(NAME_FLAG_DO_NOT_QUEUE)
357
358     ADD_CONST_PREFIXED(BUS_SESSION)
359     ADD_CONST_PREFIXED(BUS_SYSTEM)
360     ADD_CONST_PREFIXED(BUS_STARTER)
361
362     ADD_CONST_PREFIXED(MESSAGE_TYPE_INVALID)
363     ADD_CONST_PREFIXED(MESSAGE_TYPE_METHOD_CALL)
364     ADD_CONST_PREFIXED(MESSAGE_TYPE_METHOD_RETURN)
365     ADD_CONST_PREFIXED(MESSAGE_TYPE_ERROR)
366     ADD_CONST_PREFIXED(MESSAGE_TYPE_SIGNAL)
367
368     ADD_CONST_PREFIXED(TYPE_INVALID)
369     ADD_CONST_PREFIXED(TYPE_BYTE)
370     ADD_CONST_PREFIXED(TYPE_BOOLEAN)
371     ADD_CONST_PREFIXED(TYPE_INT16)
372     ADD_CONST_PREFIXED(TYPE_UINT16)
373     ADD_CONST_PREFIXED(TYPE_INT32)
374 #ifdef DBUS_TYPE_UNIX_FD
375     ADD_CONST_PREFIXED(TYPE_UNIX_FD)
376 #endif
377     ADD_CONST_PREFIXED(TYPE_UINT32)
378     ADD_CONST_PREFIXED(TYPE_INT64)
379     ADD_CONST_PREFIXED(TYPE_UINT64)
380     ADD_CONST_PREFIXED(TYPE_DOUBLE)
381     ADD_CONST_PREFIXED(TYPE_STRING)
382     ADD_CONST_PREFIXED(TYPE_OBJECT_PATH)
383     ADD_CONST_PREFIXED(TYPE_SIGNATURE)
384     ADD_CONST_PREFIXED(TYPE_ARRAY)
385     ADD_CONST_PREFIXED(TYPE_STRUCT)
386     ADD_CONST_VAL("STRUCT_BEGIN", DBUS_STRUCT_BEGIN_CHAR)
387     ADD_CONST_VAL("STRUCT_END", DBUS_STRUCT_END_CHAR)
388     ADD_CONST_PREFIXED(TYPE_VARIANT)
389     ADD_CONST_PREFIXED(TYPE_DICT_ENTRY)
390     ADD_CONST_VAL("DICT_ENTRY_BEGIN", DBUS_DICT_ENTRY_BEGIN_CHAR)
391     ADD_CONST_VAL("DICT_ENTRY_END", DBUS_DICT_ENTRY_END_CHAR)
392
393     ADD_CONST_PREFIXED(HANDLER_RESULT_HANDLED)
394     ADD_CONST_PREFIXED(HANDLER_RESULT_NOT_YET_HANDLED)
395     ADD_CONST_PREFIXED(HANDLER_RESULT_NEED_MEMORY)
396
397     ADD_CONST_PREFIXED(WATCH_READABLE)
398     ADD_CONST_PREFIXED(WATCH_WRITABLE)
399     ADD_CONST_PREFIXED(WATCH_HANGUP)
400     ADD_CONST_PREFIXED(WATCH_ERROR)
401
402     if (PyModule_AddStringConstant(this_module, "__docformat__",
403                                    "restructuredtext") < 0) goto init_error;
404
405     if (PyModule_AddStringConstant(this_module, "__version__",
406                                    PACKAGE_VERSION) < 0) goto init_error;
407
408     if (PyModule_AddIntConstant(this_module, "_python_version",
409                                 PY_VERSION_HEX) < 0) goto init_error;
410
411 #ifdef PY3
412     c_api = PyCapsule_New((void *)dbus_bindings_API,
413                           PYDBUS_CAPSULE_NAME, NULL);
414 #else
415     c_api = PyCObject_FromVoidPtr ((void *)dbus_bindings_API, NULL);
416 #endif
417     if (!c_api) {
418         goto init_error;
419     }
420     PyModule_AddObject(this_module, "_C_API", c_api);
421
422 #ifdef PY3
423     return this_module;
424   init_error:
425     Py_CLEAR(this_module);
426     return NULL;
427 #else
428   init_error:
429     return;
430 #endif
431 }
432
433 /* vim:set ft=c cino< sw=4 sts=4 et: */