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 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program 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 General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "dbus_bindings-internal.h"
24 #include "conn-internal.h"
26 PyDoc_STRVAR(Bus_tp_doc
,
27 "If the address is an int it must be one of the constants BUS_SESSION,\n"
28 "BUS_SYSTEM, BUS_STARTER; if a string, it must be a D-Bus address.\n"
29 "The default is BUS_SESSION.\n"
33 " BusImplementation([address: str or int])\n"
36 /* Bus definition =================================================== */
38 static PyTypeObject BusType
;
40 #define Bus_Check(ob) PyObject_TypeCheck(ob, &BusType)
42 /* Bus methods ====================================================== */
45 Bus_tp_new(PyTypeObject
*cls
, PyObject
*args
, PyObject
*kwargs
)
47 PyObject
*first
= NULL
, *mainloop
= NULL
;
53 static char *argnames
[] = {"address_or_type", "mainloop", NULL
};
55 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OO", argnames
,
60 dbus_error_init(&error
);
62 if (first
&& PyString_Check(first
)) {
63 /* It's a custom address. First connect to it, then register. */
65 self
= (Connection
*)(DBusPyConnection_Type
.tp_new
)(cls
, args
, kwargs
);
66 if (!self
) return NULL
;
69 Py_BEGIN_ALLOW_THREADS
70 ret
= dbus_bus_register(self
->conn
, &error
);
73 DBusPyException_ConsumeError(&error
);
78 return (PyObject
*)self
;
81 /* If the first argument isn't a string, it must be an integer
82 representing one of the well-known bus types. */
84 if (first
&& !PyInt_Check(first
)) {
85 PyErr_SetString(PyExc_TypeError
, "A string address or an integer "
86 "bus type is required");
90 type
= PyInt_AsLong(first
);
93 type
= DBUS_BUS_SESSION
;
96 if (type
!= DBUS_BUS_SESSION
&& type
!= DBUS_BUS_SYSTEM
97 && type
!= DBUS_BUS_STARTER
) {
98 PyErr_Format(PyExc_ValueError
, "Unknown bus type %d", (int)type
);
102 Py_BEGIN_ALLOW_THREADS
103 conn
= dbus_bus_get_private(type
, &error
);
107 DBusPyException_ConsumeError(&error
);
110 return DBusPyConnection_NewConsumingDBusConnection(cls
, conn
, mainloop
);
113 PyDoc_STRVAR(Bus_get_unique_name__doc__
,
114 "get_unique_name() -> str\n\n"
115 "Return this application's unique name on this bus.\n");
117 Bus_get_unique_name(Connection
*self
, PyObject
*args UNUSED
)
122 DBUS_PY_RAISE_VIA_NULL_IF_FAIL(self
->conn
);
123 Py_BEGIN_ALLOW_THREADS
124 name
= dbus_bus_get_unique_name(self
->conn
);
127 /* shouldn't happen, but C subtypes could have done something stupid */
128 PyErr_SetString(DBusPyException
, "Unable to retrieve unique name");
131 return PyString_FromString(name
);
134 PyDoc_STRVAR(Bus_get_unix_user__doc__
,
135 "get_unix_user(bus_name) -> int\n"
137 "Get the numeric uid of the process which owns the given bus name\n"
138 "on the connected bus daemon.\n"
141 " `bus_name` : str\n"
142 " A bus name (may be either a unique name or a well-known name)\n"
145 Bus_get_unix_user(Connection
*self
, PyObject
*args
)
149 const char *bus_name
;
152 DBUS_PY_RAISE_VIA_NULL_IF_FAIL(self
->conn
);
153 if (!PyArg_ParseTuple(args
, "s:get_unix_user", &bus_name
)) {
157 dbus_error_init(&error
);
158 Py_BEGIN_ALLOW_THREADS
159 uid
= dbus_bus_get_unix_user(self
->conn
, bus_name
, &error
);
161 if (uid
== (unsigned long)(-1)) return DBusPyException_ConsumeError(&error
);
162 return PyLong_FromUnsignedLong(uid
);
165 PyDoc_STRVAR(Bus_start_service_by_name__doc__
,
166 "start_service_by_name(bus_name)\n\
168 Start a service which will implement the given bus name on this\n\
173 The well-known bus name for which an implementation is required\n\
175 :Returns: A tuple of 2 elements. The first is always True, the second is\n\
176 either START_REPLY_SUCCESS or START_REPLY_ALREADY_RUNNING.\n\
178 :Raises DBusException: if the service could not be started.\n\
180 FIXME: Fix return signature?\n\
183 Bus_start_service_by_name(Connection
*self
, PyObject
*args
)
186 const char *bus_name
;
191 DBUS_PY_RAISE_VIA_NULL_IF_FAIL(self
->conn
);
192 if (!PyArg_ParseTuple(args
, "s:start_service_by_name", &bus_name
)) {
195 dbus_error_init(&error
);
196 Py_BEGIN_ALLOW_THREADS
197 success
= dbus_bus_start_service_by_name(self
->conn
, bus_name
,
198 0 /* flags */, &ret
, &error
);
201 return DBusPyException_ConsumeError(&error
);
203 return Py_BuildValue("(Ol)", Py_True
, (long)ret
);
206 /* FIXME: signal IN_QUEUE, EXISTS by exception? */
207 PyDoc_STRVAR(Bus_request_name__doc__
, "");
209 Bus_request_name(Connection
*self
, PyObject
*args
)
211 unsigned int flags
= 0;
212 const char *bus_name
;
217 DBUS_PY_RAISE_VIA_NULL_IF_FAIL(self
->conn
);
218 if (!PyArg_ParseTuple(args
, "s|I:request_name", &bus_name
, &flags
)) {
221 if (!dbus_py_validate_bus_name(bus_name
, 0, 1)) return NULL
;
223 dbus_error_init(&error
);
224 Py_BEGIN_ALLOW_THREADS
225 ret
= dbus_bus_request_name(self
->conn
, bus_name
, flags
, &error
);
227 if (ret
== -1) return DBusPyException_ConsumeError(&error
);
229 return PyInt_FromLong(ret
);
232 PyDoc_STRVAR(Bus_release_name__doc__
, "");
234 Bus_release_name(Connection
*self
, PyObject
*args
)
236 const char *bus_name
;
241 DBUS_PY_RAISE_VIA_NULL_IF_FAIL(self
->conn
);
242 if (!PyArg_ParseTuple(args
, "s:release_name", &bus_name
)) return NULL
;
244 dbus_error_init(&error
);
245 Py_BEGIN_ALLOW_THREADS
246 ret
= dbus_bus_release_name(self
->conn
, bus_name
, &error
);
248 if (ret
== -1) return DBusPyException_ConsumeError(&error
);
250 return PyInt_FromLong(ret
);
253 PyDoc_STRVAR(Bus_name_has_owner__doc__
,
254 "name_has_owner(bus_name) -> bool\n\n"
255 "Return True if and only if the given bus name has an owner on this bus.\n");
257 Bus_name_has_owner(Connection
*self
, PyObject
*args
)
259 const char *bus_name
;
264 DBUS_PY_RAISE_VIA_NULL_IF_FAIL(self
->conn
);
265 if (!PyArg_ParseTuple(args
, "s:name_has_owner", &bus_name
)) return NULL
;
266 dbus_error_init(&error
);
267 Py_BEGIN_ALLOW_THREADS
268 ret
= dbus_bus_name_has_owner(self
->conn
, bus_name
, &error
);
270 if (dbus_error_is_set(&error
)) {
271 return DBusPyException_ConsumeError(&error
);
273 return PyBool_FromLong(ret
);
276 PyDoc_STRVAR(Bus_add_match_string__doc__
,
277 "add_match_string(rule)\n\n"
278 "Arrange for this application to receive messages on the bus that match\n"
279 "the given rule. This version will block and raises DBusException on error.\n");
281 Bus_add_match_string(Connection
*self
, PyObject
*args
)
287 DBUS_PY_RAISE_VIA_NULL_IF_FAIL(self
->conn
);
288 if (!PyArg_ParseTuple(args
, "s:add_match", &rule
)) return NULL
;
289 dbus_error_init(&error
);
290 Py_BEGIN_ALLOW_THREADS
291 dbus_bus_add_match(self
->conn
, rule
, &error
);
293 if (dbus_error_is_set(&error
)) {
294 return DBusPyException_ConsumeError(&error
);
299 PyDoc_STRVAR(Bus_add_match_string_non_blocking__doc__
,
300 "add_match_string_non_blocking(rule)\n\n"
301 "Arrange for this application to receive messages on the bus that match\n"
302 "the given rule. This version does not block, but any errors will be\n"
305 Bus_add_match_string_non_blocking(Connection
*self
, PyObject
*args
)
309 DBUS_PY_RAISE_VIA_NULL_IF_FAIL(self
->conn
);
310 if (!PyArg_ParseTuple(args
, "s:add_match", &rule
)) return NULL
;
311 Py_BEGIN_ALLOW_THREADS
312 dbus_bus_add_match(self
->conn
, rule
, NULL
);
317 PyDoc_STRVAR(Bus_remove_match_string__doc__
,
318 "remove_match_string(rule)\n\n"
319 "Remove the given match rule; if it has been added more than once,\n"
320 "remove one of the identical copies, leaving the others active.\n"
321 "This version blocks, and raises DBusException on error.\n");
323 Bus_remove_match_string(Connection
*self
, PyObject
*args
)
329 DBUS_PY_RAISE_VIA_NULL_IF_FAIL(self
->conn
);
330 if (!PyArg_ParseTuple(args
, "s:remove_match", &rule
)) return NULL
;
331 dbus_error_init(&error
);
332 Py_BEGIN_ALLOW_THREADS
333 dbus_bus_remove_match(self
->conn
, rule
, &error
);
335 if (dbus_error_is_set(&error
)) {
336 return DBusPyException_ConsumeError(&error
);
341 PyDoc_STRVAR(Bus_remove_match_string_non_blocking__doc__
,
342 "remove_match_string_non_blocking(rule)\n\n"
343 "Remove the given match rule; if it has been added more than once,\n"
344 "remove one of the identical copies, leaving the others active.\n"
345 "This version does not block, but causes any errors to be ignored.\n");
347 Bus_remove_match_string_non_blocking(Connection
*self
, PyObject
*args
)
352 DBUS_PY_RAISE_VIA_NULL_IF_FAIL(self
->conn
);
353 if (!PyArg_ParseTuple(args
, "s:remove_match", &rule
)) return NULL
;
354 Py_BEGIN_ALLOW_THREADS
355 dbus_bus_remove_match(self
->conn
, rule
, NULL
);
360 /* Bus type object ================================================== */
362 static struct PyMethodDef Bus_tp_methods
[] = {
363 #define ENTRY(name, flags) {#name, (PyCFunction)Bus_##name, flags, Bus_##name##__doc__},
364 ENTRY(get_unique_name
, METH_NOARGS
)
365 ENTRY(get_unix_user
, METH_VARARGS
)
366 ENTRY(start_service_by_name
, METH_VARARGS
)
367 ENTRY(request_name
, METH_VARARGS
)
368 ENTRY(release_name
, METH_VARARGS
)
369 ENTRY(name_has_owner
, METH_VARARGS
)
370 ENTRY(add_match_string
, METH_VARARGS
)
371 ENTRY(add_match_string_non_blocking
, METH_VARARGS
)
372 ENTRY(remove_match_string
, METH_VARARGS
)
373 ENTRY(remove_match_string_non_blocking
, METH_VARARGS
)
378 static PyTypeObject BusType
= {
379 PyObject_HEAD_INIT(NULL
)
381 "_dbus_bindings.BusImplementation", /*tp_name*/
392 0, /*tp_as_sequence*/
400 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
, /*tp_flags*/
401 Bus_tp_doc
, /*tp_doc*/
404 0, /*tp_richcompare*/
405 0, /*tp_weaklistoffset*/
408 Bus_tp_methods
, /*tp_methods*/
411 DEFERRED_ADDRESS(&ConnectionType
), /*tp_base*/
418 Bus_tp_new
, /*tp_new*/
424 dbus_py_init_bus_types(void)
426 BusType
.tp_base
= &DBusPyConnection_Type
;
427 if (PyType_Ready(&BusType
) < 0) return 0;
432 dbus_py_insert_bus_types(PyObject
*this_module
)
434 if (PyModule_AddObject(this_module
, "BusImplementation",
435 (PyObject
*)&BusType
) < 0) return 0;
439 /* vim:set ft=c cino< sw=4 sts=4 et: */