Relicense Collabora code under the MIT/X11 license proposed for dbus core, removing...
[dbus-python-phuang.git] / _dbus_bindings / module.c
blobddeb1f0e5f816202a7ba3050d2b54a3bfc80682e
1 /* Main module source for the _dbus_bindings extension.
3 * Copyright (C) 2006 Collabora Ltd. <http://www.collabora.co.uk/>
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:
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
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.
25 #include "config.h"
27 #include <Python.h>
28 #include <structmember.h>
30 #include "dbus_bindings-internal.h"
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"
39 /* Global functions - validation wrappers ===========================*/
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"
59 static PyObject *
60 validate_bus_name(PyObject *unused UNUSED, PyObject *args, PyObject *kwargs)
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 };
68 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
69 "s|ii:validate_bus_name", argnames,
70 &name, &allow_unique,
71 &allow_well_known)) {
72 return NULL;
74 if (!dbus_py_validate_bus_name(name, !!allow_unique, !!allow_well_known)) {
75 return NULL;
77 Py_RETURN_NONE;
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"
89 static PyObject *
90 validate_member_name(PyObject *unused UNUSED, PyObject *args)
92 const char *name;
94 if (!PyArg_ParseTuple(args, "s:validate_member_name", &name)) {
95 return NULL;
97 if (!dbus_py_validate_member_name(name)) {
98 return NULL;
100 Py_RETURN_NONE;
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"
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"
117 static PyObject *
118 validate_interface_name(PyObject *unused UNUSED, PyObject *args)
120 const char *name;
122 if (!PyArg_ParseTuple(args, "s:validate_interface_name", &name)) {
123 return NULL;
125 if (!dbus_py_validate_interface_name(name)) {
126 return NULL;
128 Py_RETURN_NONE;
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"
138 static PyObject *
139 validate_object_path(PyObject *unused UNUSED, PyObject *args)
141 const char *name;
143 if (!PyArg_ParseTuple(args, "s:validate_object_path", &name)) {
144 return NULL;
146 if (!dbus_py_validate_object_path(name)) {
147 return NULL;
149 Py_RETURN_NONE;
152 /* Global functions - main loop =====================================*/
154 /* The main loop if none is passed to the constructor */
155 static PyObject *default_main_loop = NULL;
157 /* Return a new reference to the default main loop */
158 PyObject *
159 dbus_py_get_default_main_loop(void)
161 if (!default_main_loop) {
162 Py_RETURN_NONE;
164 Py_INCREF(default_main_loop);
165 return default_main_loop;
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)
181 return dbus_py_get_default_main_loop();
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"
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"
202 static PyObject *
203 set_default_main_loop(PyObject *always_null UNUSED,
204 PyObject *args)
206 PyObject *new_loop, *old_loop;
208 if (!PyArg_ParseTuple(args, "O", &new_loop)) {
209 return NULL;
211 if (!dbus_py_check_mainloop_sanity(new_loop)) {
212 return NULL;
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;
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}
236 PyMODINIT_FUNC
237 init_dbus_bindings(void)
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];
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;
247 default_main_loop = NULL;
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.
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();
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_conn_types()) return;
272 this_module = Py_InitModule3("_dbus_bindings", module_functions, module_doc);
273 if (!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;
287 if (PyModule_AddStringConstant(this_module, "BUS_DAEMON_NAME",
288 DBUS_SERVICE_DBUS) < 0) return;
289 if (PyModule_AddStringConstant(this_module, "BUS_DAEMON_PATH",
290 DBUS_PATH_DBUS) < 0) return;
291 if (PyModule_AddStringConstant(this_module, "BUS_DAEMON_IFACE",
292 DBUS_INTERFACE_DBUS) < 0) return;
293 if (PyModule_AddStringConstant(this_module, "LOCAL_PATH",
294 DBUS_PATH_LOCAL) < 0) return;
295 if (PyModule_AddStringConstant(this_module, "LOCAL_IFACE",
296 DBUS_INTERFACE_LOCAL) < 0) return;
297 if (PyModule_AddStringConstant(this_module, "INTROSPECTABLE_IFACE",
298 DBUS_INTERFACE_INTROSPECTABLE) < 0) return;
299 if (PyModule_AddStringConstant(this_module, "PEER_IFACE",
300 DBUS_INTERFACE_PEER) < 0) return;
301 if (PyModule_AddStringConstant(this_module, "PROPERTIES_IFACE",
302 DBUS_INTERFACE_PROPERTIES) < 0) return;
303 if (PyModule_AddStringConstant(this_module,
304 "DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER",
305 DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER) < 0) return;
306 if (PyModule_AddStringConstant(this_module,
307 "DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER",
308 DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER) < 0) return;
309 if (PyModule_AddStringConstant(this_module,
310 "DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE",
311 DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE) < 0) return;
313 #define ADD_CONST_VAL(x, v) \
314 if (PyModule_AddIntConstant(this_module, x, v) < 0) return;
315 #define ADD_CONST_PREFIXED(x) ADD_CONST_VAL(#x, DBUS_##x)
316 #define ADD_CONST(x) ADD_CONST_VAL(#x, x)
318 ADD_CONST(DBUS_START_REPLY_SUCCESS)
319 ADD_CONST(DBUS_START_REPLY_ALREADY_RUNNING)
321 ADD_CONST_PREFIXED(RELEASE_NAME_REPLY_RELEASED)
322 ADD_CONST_PREFIXED(RELEASE_NAME_REPLY_NON_EXISTENT)
323 ADD_CONST_PREFIXED(RELEASE_NAME_REPLY_NOT_OWNER)
325 ADD_CONST_PREFIXED(REQUEST_NAME_REPLY_PRIMARY_OWNER)
326 ADD_CONST_PREFIXED(REQUEST_NAME_REPLY_IN_QUEUE)
327 ADD_CONST_PREFIXED(REQUEST_NAME_REPLY_EXISTS)
328 ADD_CONST_PREFIXED(REQUEST_NAME_REPLY_ALREADY_OWNER)
330 ADD_CONST_PREFIXED(NAME_FLAG_ALLOW_REPLACEMENT)
331 ADD_CONST_PREFIXED(NAME_FLAG_REPLACE_EXISTING)
332 ADD_CONST_PREFIXED(NAME_FLAG_DO_NOT_QUEUE)
334 ADD_CONST_PREFIXED(BUS_SESSION)
335 ADD_CONST_PREFIXED(BUS_SYSTEM)
336 ADD_CONST_PREFIXED(BUS_STARTER)
338 ADD_CONST_PREFIXED(MESSAGE_TYPE_INVALID)
339 ADD_CONST_PREFIXED(MESSAGE_TYPE_METHOD_CALL)
340 ADD_CONST_PREFIXED(MESSAGE_TYPE_METHOD_RETURN)
341 ADD_CONST_PREFIXED(MESSAGE_TYPE_ERROR)
342 ADD_CONST_PREFIXED(MESSAGE_TYPE_SIGNAL)
344 ADD_CONST_PREFIXED(MESSAGE_TYPE_SIGNAL)
346 ADD_CONST_PREFIXED(TYPE_INVALID)
347 ADD_CONST_PREFIXED(TYPE_BYTE)
348 ADD_CONST_PREFIXED(TYPE_BOOLEAN)
349 ADD_CONST_PREFIXED(TYPE_INT16)
350 ADD_CONST_PREFIXED(TYPE_UINT16)
351 ADD_CONST_PREFIXED(TYPE_INT32)
352 ADD_CONST_PREFIXED(TYPE_UINT32)
353 ADD_CONST_PREFIXED(TYPE_INT64)
354 ADD_CONST_PREFIXED(TYPE_UINT64)
355 ADD_CONST_PREFIXED(TYPE_DOUBLE)
356 ADD_CONST_PREFIXED(TYPE_STRING)
357 ADD_CONST_PREFIXED(TYPE_OBJECT_PATH)
358 ADD_CONST_PREFIXED(TYPE_SIGNATURE)
359 ADD_CONST_PREFIXED(TYPE_ARRAY)
360 ADD_CONST_PREFIXED(TYPE_STRUCT)
361 ADD_CONST_VAL("STRUCT_BEGIN", DBUS_STRUCT_BEGIN_CHAR)
362 ADD_CONST_VAL("STRUCT_END", DBUS_STRUCT_END_CHAR)
363 ADD_CONST_PREFIXED(TYPE_VARIANT)
364 ADD_CONST_PREFIXED(TYPE_DICT_ENTRY)
365 ADD_CONST_VAL("DICT_ENTRY_BEGIN", DBUS_DICT_ENTRY_BEGIN_CHAR)
366 ADD_CONST_VAL("DICT_ENTRY_END", DBUS_DICT_ENTRY_END_CHAR)
368 ADD_CONST_PREFIXED(HANDLER_RESULT_HANDLED)
369 ADD_CONST_PREFIXED(HANDLER_RESULT_NOT_YET_HANDLED)
370 ADD_CONST_PREFIXED(HANDLER_RESULT_NEED_MEMORY)
372 ADD_CONST_PREFIXED(WATCH_READABLE)
373 ADD_CONST_PREFIXED(WATCH_WRITABLE)
374 ADD_CONST_PREFIXED(WATCH_HANGUP)
375 ADD_CONST_PREFIXED(WATCH_ERROR)
377 if (PyModule_AddStringConstant(this_module, "__docformat__",
378 "restructuredtext") < 0) return;
380 if (PyModule_AddStringConstant(this_module, "__version__",
381 PACKAGE_VERSION) < 0) return;
383 if (PyModule_AddIntConstant(this_module, "_python_version",
384 PY_VERSION_HEX) < 0) return;
386 c_api = PyCObject_FromVoidPtr ((void *)dbus_bindings_API, NULL);
387 if (!c_api) {
388 return;
390 PyModule_AddObject(this_module, "_C_API", c_api);
393 /* vim:set ft=c cino< sw=4 sts=4 et: */