Add Makefile target maintainer-update-website to update d.fd.o/doc/dbus-python
[dbus-python-phuang.git] / _dbus_bindings / bus.c
blobbc20b2de27897037dca41d112703ad0172c31508
1 /* Implementation of Bus, a subtype of Connection.
3 * Copyright (C) 2006 Collabora Ltd.
5 * Licensed under the Academic Free License version 2.1
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "dbus_bindings-internal.h"
26 #include "conn-internal.h"
28 PyDoc_STRVAR(Bus_tp_doc,
29 "If the address is an int it must be one of the constants BUS_SESSION,\n"
30 "BUS_SYSTEM, BUS_STARTER; if a string, it must be a D-Bus address.\n"
31 "The default is BUS_SESSION.\n"
32 "\n"
33 "Constructor::\n"
34 "\n"
35 " BusImplementation([address: str or int])\n"
38 /* Bus definition =================================================== */
40 static PyTypeObject BusType;
42 #define Bus_Check(ob) PyObject_TypeCheck(ob, &BusType)
44 /* Bus methods ====================================================== */
46 static PyObject *
47 Bus_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
49 PyObject *first = NULL, *mainloop = NULL;
50 DBusConnection *conn;
51 DBusError error;
52 Connection *self;
53 dbus_bool_t ret;
54 long type;
55 static char *argnames[] = {"address_or_type", "mainloop", NULL};
57 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO", argnames,
58 &first, &mainloop)) {
59 return NULL;
62 dbus_error_init(&error);
64 if (first && PyString_Check(first)) {
65 /* It's a custom address. First connect to it, then register. */
67 self = (Connection *)(DBusPyConnection_Type.tp_new)(cls, args, kwargs);
68 if (!self) return NULL;
69 TRACE(self);
71 Py_BEGIN_ALLOW_THREADS
72 ret = dbus_bus_register(self->conn, &error);
73 Py_END_ALLOW_THREADS
74 if (!ret) {
75 DBusPyException_ConsumeError(&error);
76 Py_DECREF(self);
77 return NULL;
80 return (PyObject *)self;
83 /* If the first argument isn't a string, it must be an integer
84 representing one of the well-known bus types. */
86 if (first && !PyInt_Check(first)) {
87 PyErr_SetString(PyExc_TypeError, "A string address or an integer "
88 "bus type is required");
89 return NULL;
91 if (first) {
92 type = PyInt_AsLong(first);
94 else {
95 type = DBUS_BUS_SESSION;
98 if (type != DBUS_BUS_SESSION && type != DBUS_BUS_SYSTEM
99 && type != DBUS_BUS_STARTER) {
100 PyErr_Format(PyExc_ValueError, "Unknown bus type %d", (int)type);
101 return NULL;
104 Py_BEGIN_ALLOW_THREADS
105 conn = dbus_bus_get_private(type, &error);
106 Py_END_ALLOW_THREADS
108 if (!conn) {
109 DBusPyException_ConsumeError(&error);
110 return NULL;
112 return DBusPyConnection_NewConsumingDBusConnection(cls, conn, mainloop);
115 PyDoc_STRVAR(Bus_get_unique_name__doc__,
116 "get_unique_name() -> str\n\n"
117 "Return this application's unique name on this bus.\n");
118 static PyObject *
119 Bus_get_unique_name(Connection *self, PyObject *args UNUSED)
121 const char *name;
123 TRACE(self);
124 DBUS_PY_RAISE_VIA_NULL_IF_FAIL(self->conn);
125 Py_BEGIN_ALLOW_THREADS
126 name = dbus_bus_get_unique_name(self->conn);
127 Py_END_ALLOW_THREADS
128 if (!name) {
129 /* shouldn't happen, but C subtypes could have done something stupid */
130 PyErr_SetString(DBusPyException, "Unable to retrieve unique name");
131 return NULL;
133 return PyString_FromString(name);
136 PyDoc_STRVAR(Bus_get_unix_user__doc__,
137 "get_unix_user(bus_name) -> int\n"
138 "\n"
139 "Get the numeric uid of the process which owns the given bus name\n"
140 "on the connected bus daemon.\n"
141 "\n"
142 ":Parameters:\n"
143 " `bus_name` : str\n"
144 " A bus name (may be either a unique name or a well-known name)\n"
146 static PyObject *
147 Bus_get_unix_user(Connection *self, PyObject *args)
149 DBusError error;
150 unsigned long uid;
151 const char *bus_name;
153 TRACE(self);
154 DBUS_PY_RAISE_VIA_NULL_IF_FAIL(self->conn);
155 if (!PyArg_ParseTuple(args, "s:get_unix_user", &bus_name)) {
156 return NULL;
159 dbus_error_init(&error);
160 Py_BEGIN_ALLOW_THREADS
161 uid = dbus_bus_get_unix_user(self->conn, bus_name, &error);
162 Py_END_ALLOW_THREADS
163 if (uid == (unsigned long)(-1)) return DBusPyException_ConsumeError(&error);
164 return PyLong_FromUnsignedLong(uid);
167 PyDoc_STRVAR(Bus_start_service_by_name__doc__,
168 "start_service_by_name(bus_name)\n\
170 Start a service which will implement the given bus name on this\n\
171 Bus.\n\
173 :Parameters:\n\
174 `bus_name` : str\n\
175 The well-known bus name for which an implementation is required\n\
177 :Returns: A tuple of 2 elements. The first is always True, the second is\n\
178 either START_REPLY_SUCCESS or START_REPLY_ALREADY_RUNNING.\n\
180 :Raises DBusException: if the service could not be started.\n\
182 FIXME: Fix return signature?\n\
184 static PyObject *
185 Bus_start_service_by_name(Connection *self, PyObject *args)
187 DBusError error;
188 const char *bus_name;
189 dbus_uint32_t ret;
190 dbus_bool_t success;
192 TRACE(self);
193 DBUS_PY_RAISE_VIA_NULL_IF_FAIL(self->conn);
194 if (!PyArg_ParseTuple(args, "s:start_service_by_name", &bus_name)) {
195 return NULL;
197 dbus_error_init(&error);
198 Py_BEGIN_ALLOW_THREADS
199 success = dbus_bus_start_service_by_name(self->conn, bus_name,
200 0 /* flags */, &ret, &error);
201 Py_END_ALLOW_THREADS
202 if (!success) {
203 return DBusPyException_ConsumeError(&error);
205 return Py_BuildValue("(Ol)", Py_True, (long)ret);
208 /* FIXME: signal IN_QUEUE, EXISTS by exception? */
209 PyDoc_STRVAR(Bus_request_name__doc__, "");
210 static PyObject *
211 Bus_request_name(Connection *self, PyObject *args)
213 unsigned int flags = 0;
214 const char *bus_name;
215 int ret;
216 DBusError error;
218 TRACE(self);
219 DBUS_PY_RAISE_VIA_NULL_IF_FAIL(self->conn);
220 if (!PyArg_ParseTuple(args, "s|I:request_name", &bus_name, &flags)) {
221 return NULL;
223 if (!dbus_py_validate_bus_name(bus_name, 0, 1)) return NULL;
225 dbus_error_init(&error);
226 Py_BEGIN_ALLOW_THREADS
227 ret = dbus_bus_request_name(self->conn, bus_name, flags, &error);
228 Py_END_ALLOW_THREADS
229 if (ret == -1) return DBusPyException_ConsumeError(&error);
231 return PyInt_FromLong(ret);
234 PyDoc_STRVAR(Bus_release_name__doc__, "");
235 static PyObject *
236 Bus_release_name(Connection *self, PyObject *args)
238 const char *bus_name;
239 int ret;
240 DBusError error;
242 TRACE(self);
243 DBUS_PY_RAISE_VIA_NULL_IF_FAIL(self->conn);
244 if (!PyArg_ParseTuple(args, "s:release_name", &bus_name)) return NULL;
246 dbus_error_init(&error);
247 Py_BEGIN_ALLOW_THREADS
248 ret = dbus_bus_release_name(self->conn, bus_name, &error);
249 Py_END_ALLOW_THREADS
250 if (ret == -1) return DBusPyException_ConsumeError(&error);
252 return PyInt_FromLong(ret);
255 PyDoc_STRVAR(Bus_name_has_owner__doc__,
256 "name_has_owner(bus_name) -> bool\n\n"
257 "Return True if and only if the given bus name has an owner on this bus.\n");
258 static PyObject *
259 Bus_name_has_owner(Connection *self, PyObject *args)
261 const char *bus_name;
262 int ret;
263 DBusError error;
265 TRACE(self);
266 DBUS_PY_RAISE_VIA_NULL_IF_FAIL(self->conn);
267 if (!PyArg_ParseTuple(args, "s:name_has_owner", &bus_name)) return NULL;
268 dbus_error_init(&error);
269 Py_BEGIN_ALLOW_THREADS
270 ret = dbus_bus_name_has_owner(self->conn, bus_name, &error);
271 Py_END_ALLOW_THREADS
272 if (dbus_error_is_set(&error)) {
273 return DBusPyException_ConsumeError(&error);
275 return PyBool_FromLong(ret);
278 PyDoc_STRVAR(Bus_add_match_string__doc__,
279 "add_match_string(rule)\n\n"
280 "Arrange for this application to receive messages on the bus that match\n"
281 "the given rule. This version will block and raises DBusException on error.\n");
282 static PyObject *
283 Bus_add_match_string(Connection *self, PyObject *args)
285 const char *rule;
286 DBusError error;
288 TRACE(self);
289 DBUS_PY_RAISE_VIA_NULL_IF_FAIL(self->conn);
290 if (!PyArg_ParseTuple(args, "s:add_match", &rule)) return NULL;
291 dbus_error_init(&error);
292 Py_BEGIN_ALLOW_THREADS
293 dbus_bus_add_match(self->conn, rule, &error);
294 Py_END_ALLOW_THREADS
295 if (dbus_error_is_set(&error)) {
296 return DBusPyException_ConsumeError(&error);
298 Py_RETURN_NONE;
301 PyDoc_STRVAR(Bus_add_match_string_non_blocking__doc__,
302 "add_match_string_non_blocking(rule)\n\n"
303 "Arrange for this application to receive messages on the bus that match\n"
304 "the given rule. This version does not block, but any errors will be\n"
305 "ignored.\n");
306 static PyObject *
307 Bus_add_match_string_non_blocking(Connection *self, PyObject *args)
309 const char *rule;
311 DBUS_PY_RAISE_VIA_NULL_IF_FAIL(self->conn);
312 if (!PyArg_ParseTuple(args, "s:add_match", &rule)) return NULL;
313 Py_BEGIN_ALLOW_THREADS
314 dbus_bus_add_match(self->conn, rule, NULL);
315 Py_END_ALLOW_THREADS
316 Py_RETURN_NONE;
319 PyDoc_STRVAR(Bus_remove_match_string__doc__,
320 "remove_match_string(rule)\n\n"
321 "Remove the given match rule; if it has been added more than once,\n"
322 "remove one of the identical copies, leaving the others active.\n"
323 "This version blocks, and raises DBusException on error.\n");
324 static PyObject *
325 Bus_remove_match_string(Connection *self, PyObject *args)
327 const char *rule;
328 DBusError error;
330 TRACE(self);
331 DBUS_PY_RAISE_VIA_NULL_IF_FAIL(self->conn);
332 if (!PyArg_ParseTuple(args, "s:remove_match", &rule)) return NULL;
333 dbus_error_init(&error);
334 Py_BEGIN_ALLOW_THREADS
335 dbus_bus_remove_match(self->conn, rule, &error);
336 Py_END_ALLOW_THREADS
337 if (dbus_error_is_set(&error)) {
338 return DBusPyException_ConsumeError(&error);
340 Py_RETURN_NONE;
343 PyDoc_STRVAR(Bus_remove_match_string_non_blocking__doc__,
344 "remove_match_string_non_blocking(rule)\n\n"
345 "Remove the given match rule; if it has been added more than once,\n"
346 "remove one of the identical copies, leaving the others active.\n"
347 "This version does not block, but causes any errors to be ignored.\n");
348 static PyObject *
349 Bus_remove_match_string_non_blocking(Connection *self, PyObject *args)
351 const char *rule;
353 TRACE(self);
354 DBUS_PY_RAISE_VIA_NULL_IF_FAIL(self->conn);
355 if (!PyArg_ParseTuple(args, "s:remove_match", &rule)) return NULL;
356 Py_BEGIN_ALLOW_THREADS
357 dbus_bus_remove_match(self->conn, rule, NULL);
358 Py_END_ALLOW_THREADS
359 Py_RETURN_NONE;
362 /* Bus type object ================================================== */
364 static struct PyMethodDef Bus_tp_methods[] = {
365 #define ENTRY(name, flags) {#name, (PyCFunction)Bus_##name, flags, Bus_##name##__doc__},
366 ENTRY(get_unique_name, METH_NOARGS)
367 ENTRY(get_unix_user, METH_VARARGS)
368 ENTRY(start_service_by_name, METH_VARARGS)
369 ENTRY(request_name, METH_VARARGS)
370 ENTRY(release_name, METH_VARARGS)
371 ENTRY(name_has_owner, METH_VARARGS)
372 ENTRY(add_match_string, METH_VARARGS)
373 ENTRY(add_match_string_non_blocking, METH_VARARGS)
374 ENTRY(remove_match_string, METH_VARARGS)
375 ENTRY(remove_match_string_non_blocking, METH_VARARGS)
376 #undef ENTRY
377 {NULL},
380 static PyTypeObject BusType = {
381 PyObject_HEAD_INIT(NULL)
382 0, /*ob_size*/
383 "_dbus_bindings.BusImplementation", /*tp_name*/
384 0, /*tp_basicsize*/
385 0, /*tp_itemsize*/
386 /* methods */
387 0, /*tp_dealloc*/
388 0, /*tp_print*/
389 0, /*tp_getattr*/
390 0, /*tp_setattr*/
391 0, /*tp_compare*/
392 0, /*tp_repr*/
393 0, /*tp_as_number*/
394 0, /*tp_as_sequence*/
395 0, /*tp_as_mapping*/
396 0, /*tp_hash*/
397 0, /*tp_call*/
398 0, /*tp_str*/
399 0, /*tp_getattro*/
400 0, /*tp_setattro*/
401 0, /*tp_as_buffer*/
402 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
403 Bus_tp_doc, /*tp_doc*/
404 0, /*tp_traverse*/
405 0, /*tp_clear*/
406 0, /*tp_richcompare*/
407 0, /*tp_weaklistoffset*/
408 0, /*tp_iter*/
409 0, /*tp_iternext*/
410 Bus_tp_methods, /*tp_methods*/
411 0, /*tp_members*/
412 0, /*tp_getset*/
413 DEFERRED_ADDRESS(&ConnectionType), /*tp_base*/
414 0, /*tp_dict*/
415 0, /*tp_descr_get*/
416 0, /*tp_descr_set*/
417 0, /*tp_dictoffset*/
418 0, /*tp_init*/
419 0, /*tp_alloc*/
420 Bus_tp_new, /*tp_new*/
421 0, /*tp_free*/
422 0, /*tp_is_gc*/
425 dbus_bool_t
426 dbus_py_init_bus_types(void)
428 BusType.tp_base = &DBusPyConnection_Type;
429 if (PyType_Ready(&BusType) < 0) return 0;
430 return 1;
433 dbus_bool_t
434 dbus_py_insert_bus_types(PyObject *this_module)
436 if (PyModule_AddObject(this_module, "BusImplementation",
437 (PyObject *)&BusType) < 0) return 0;
438 return 1;
441 /* vim:set ft=c cino< sw=4 sts=4 et: */