Add a test case for the various options to get_args_list.
[dbus-python-phuang.git] / _dbus_bindings / bus-impl.h
blob28647930856924146a30cbd210a8225fe4cd6be9
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 PyDoc_STRVAR(Bus_tp_doc,
26 "Bus([address: str or int])\n\n"
27 "If the address is an int it must be one of the constants BUS_SESSION,\n"
28 "BUS_SYSTEM, BUS_STARTER. The default is BUS_SESSION.\n"
31 /* Bus definition =================================================== */
33 static PyTypeObject BusType;
35 #define Bus_Check(ob) PyObject_TypeCheck(ob, &BusType)
37 /* Bus methods ====================================================== */
39 static PyObject *
40 Bus_tp_new (PyTypeObject *cls, PyObject *args, PyObject *kwargs)
42 PyObject *first = NULL;
43 DBusConnection *conn;
44 DBusError error;
45 Connection *self;
46 dbus_bool_t ret;
47 long type;
48 static char *argnames[] = {"address_or_type", NULL};
50 if (!PyArg_ParseTupleAndKeywords (args, kwargs, "|O", argnames, &first)) {
51 return NULL;
54 dbus_error_init (&error);
56 if (first && PyString_Check(first)) {
57 /* It's a custom address. First connect to it, then register. */
59 self = (Connection *)Connection_tp_new(cls, args, kwargs);
60 if (!self) return NULL;
62 Py_BEGIN_ALLOW_THREADS
63 ret = dbus_bus_register (self->conn, &error);
64 Py_END_ALLOW_THREADS
65 if (!ret) {
66 DBusException_ConsumeError(&error);
67 Py_DECREF(self);
68 return NULL;
72 /* If the first argument isn't a string, it must be an integer
73 representing one of the well-known bus types. */
75 if (first && !PyInt_Check (first)) {
76 PyErr_SetString(PyExc_TypeError, "A string address or an integer "
77 "bus type is required");
78 return NULL;
80 if (first) {
81 type = PyInt_AsLong (first);
83 else {
84 type = DBUS_BUS_SESSION;
87 if (type != DBUS_BUS_SESSION && type != DBUS_BUS_SYSTEM
88 && type != DBUS_BUS_STARTER) {
89 PyErr_Format(PyExc_ValueError, "Unknown bus type %d", (int)type);
90 return NULL;
93 Py_BEGIN_ALLOW_THREADS
94 conn = dbus_bus_get_private (type, &error);
95 Py_END_ALLOW_THREADS
97 if (!conn) {
98 DBusException_ConsumeError (&error);
99 return NULL;
101 return Connection_NewConsumingDBusConnection(cls, conn);
104 PyDoc_STRVAR(Bus_get_unique_name__doc__,
105 "get_unique_name() -> str\n\n"
106 "Return this application's unique name on this bus.\n");
107 static PyObject *
108 Bus_get_unique_name (Connection *self, PyObject *args)
110 const char *name;
112 Py_BEGIN_ALLOW_THREADS
113 name = dbus_bus_get_unique_name (self->conn);
114 Py_END_ALLOW_THREADS
115 if (!name) {
116 /* shouldn't happen, but C subtypes could have done something stupid */
117 PyErr_SetString (DBusException, "Unable to retrieve unique name");
118 return NULL;
120 return PyString_FromString (name);
123 PyDoc_STRVAR(Bus_get_unix_user__doc__,
124 "get_unix_user(bus_name: str) -> int\n"
125 "\n"
126 "Get the numeric uid of the process which owns the given bus name\n"
127 "on the connected bus daemon.\n"
128 "\n"
129 ":Parameters:\n"
130 " `bus_name` : str\n"
131 " A bus name (may be either a unique name or a well-known name)\n"
133 static PyObject *
134 Bus_get_unix_user (Connection *self, PyObject *args)
136 DBusError error;
137 unsigned long uid;
138 const char *bus_name;
140 if (!PyArg_ParseTuple(args, "s:get_unix_user", &bus_name)) {
141 return NULL;
144 dbus_error_init (&error);
145 Py_BEGIN_ALLOW_THREADS
146 uid = dbus_bus_get_unix_user (self->conn, bus_name, &error);
147 Py_END_ALLOW_THREADS
148 if (uid == (unsigned long)(-1)) return DBusException_ConsumeError (&error);
149 return PyLong_FromUnsignedLong (uid);
152 PyDoc_STRVAR(Bus_start_service_by_name__doc__,
153 "start_service_by_name(bus_name: str) -> (True, int)\n\
155 Start a service which will implement the given bus name on this\n\
156 Bus.\n\
158 :Parameters:\n\
159 `bus_name` : str\n\
160 The well-known bus name for which an implementation is required\n\
162 :Returns: A tuple of 2 elements. The first is always True, the second is\n\
163 either START_REPLY_SUCCESS or START_REPLY_ALREADY_RUNNING.\n\
165 :Raises DBusException: if the service could not be started.\n\
167 FIXME: Fix return signature?\n\
169 static PyObject *
170 Bus_start_service_by_name (Connection *self, PyObject *args)
172 DBusError error;
173 const char *bus_name;
174 dbus_uint32_t ret;
175 dbus_bool_t success;
177 if (!PyArg_ParseTuple(args, "s:start_service_by_name", &bus_name)) {
178 return NULL;
180 dbus_error_init (&error);
181 Py_BEGIN_ALLOW_THREADS
182 success = dbus_bus_start_service_by_name (self->conn, bus_name,
183 0 /* flags */, &ret, &error);
184 Py_END_ALLOW_THREADS
185 if (!success) {
186 return DBusException_ConsumeError (&error);
188 return Py_BuildValue ("(Ol)", Py_True, (long)ret);
191 /* FIXME: signal IN_QUEUE, EXISTS by exception? */
192 PyDoc_STRVAR(Bus_request_name__doc__, "");
193 static PyObject *
194 Bus_request_name (Connection *self, PyObject *args)
196 unsigned int flags = 0;
197 const char *bus_name;
198 int ret;
199 DBusError error;
201 if (!PyArg_ParseTuple(args, "s|I:request_name", &bus_name, &flags)) {
202 return NULL;
204 if (!_validate_bus_name(bus_name, 0, 1)) return NULL;
206 dbus_error_init (&error);
207 Py_BEGIN_ALLOW_THREADS
208 ret = dbus_bus_request_name(self->conn, bus_name, flags, &error);
209 Py_END_ALLOW_THREADS
210 if (ret == -1) return DBusException_ConsumeError (&error);
212 return PyInt_FromLong(ret);
215 PyDoc_STRVAR(Bus_release_name__doc__, "");
216 static PyObject *
217 Bus_release_name (Connection *self, PyObject *args)
219 const char *bus_name;
220 int ret;
221 DBusError error;
223 if (!PyArg_ParseTuple(args, "s:release_name", &bus_name)) return NULL;
225 dbus_error_init (&error);
226 Py_BEGIN_ALLOW_THREADS
227 ret = dbus_bus_release_name(self->conn, bus_name, &error);
228 Py_END_ALLOW_THREADS
229 if (ret == -1) return DBusException_ConsumeError (&error);
231 return PyInt_FromLong(ret);
234 PyDoc_STRVAR (Bus_name_has_owner__doc__,
235 "name_has_owner(bus_name: str) -> bool\n\n"
236 "Return True if and only if the given bus name has an owner on this bus.\n");
237 static PyObject *
238 Bus_name_has_owner (Connection *self, PyObject *args)
240 const char *bus_name;
241 int ret;
242 DBusError error;
244 if (!PyArg_ParseTuple(args, "s:name_has_owner", &bus_name)) return NULL;
245 dbus_error_init (&error);
246 Py_BEGIN_ALLOW_THREADS
247 ret = dbus_bus_name_has_owner(self->conn, bus_name, &error);
248 Py_END_ALLOW_THREADS
249 if (dbus_error_is_set (&error)) {
250 return DBusException_ConsumeError (&error);
252 return PyBool_FromLong(ret);
255 PyDoc_STRVAR (Bus_add_match_string__doc__,
256 "add_match_string(rule: str)\n\n"
257 "Arrange for this application to receive messages on the bus that match\n"
258 "the given rule. This version will block and raises DBusException on error.\n");
259 static PyObject *
260 Bus_add_match_string (Connection *self, PyObject *args)
262 const char *rule;
263 DBusError error;
265 if (!PyArg_ParseTuple(args, "s:add_match", &rule)) return NULL;
266 dbus_error_init (&error);
267 Py_BEGIN_ALLOW_THREADS
268 dbus_bus_add_match (self->conn, rule, &error);
269 Py_END_ALLOW_THREADS
270 if (dbus_error_is_set (&error)) {
271 return DBusException_ConsumeError (&error);
273 Py_RETURN_NONE;
276 PyDoc_STRVAR (Bus_add_match_string_non_blocking__doc__,
277 "add_match_string_non_blocking(rule: str)\n\n"
278 "Arrange for this application to receive messages on the bus that match\n"
279 "the given rule. This version does not block, but any errors will be\n"
280 "ignored.\n");
281 static PyObject *
282 Bus_add_match_string_non_blocking (Connection *self, PyObject *args)
284 const char *rule;
286 if (!PyArg_ParseTuple(args, "s:add_match", &rule)) return NULL;
287 Py_BEGIN_ALLOW_THREADS
288 dbus_bus_add_match (self->conn, rule, NULL);
289 Py_END_ALLOW_THREADS
290 Py_RETURN_NONE;
293 PyDoc_STRVAR (Bus_remove_match_string__doc__,
294 "remove_match_string_non_blocking(rule: str)\n\n"
295 "Remove the given match rule; if it has been added more than once,\n"
296 "remove one of the identical copies, leaving the others active.\n"
297 "This version blocks, and raises DBusException on error.\n");
298 static PyObject *
299 Bus_remove_match_string (Connection *self, PyObject *args)
301 const char *rule;
302 DBusError error;
304 if (!PyArg_ParseTuple(args, "s:remove_match", &rule)) return NULL;
305 dbus_error_init (&error);
306 Py_BEGIN_ALLOW_THREADS
307 dbus_bus_remove_match (self->conn, rule, &error);
308 Py_END_ALLOW_THREADS
309 if (dbus_error_is_set (&error)) {
310 return DBusException_ConsumeError (&error);
312 Py_RETURN_NONE;
315 PyDoc_STRVAR (Bus_remove_match_string_non_blocking__doc__,
316 "remove_match_string_non_blocking(rule: str)\n\n"
317 "Remove the given match rule; if it has been added more than once,\n"
318 "remove one of the identical copies, leaving the others active.\n"
319 "This version does not block, but causes any errors to be ignored.\n");
320 static PyObject *
321 Bus_remove_match_string_non_blocking (Connection *self, PyObject *args)
323 const char *rule;
325 if (!PyArg_ParseTuple(args, "s:remove_match", &rule)) return NULL;
326 Py_BEGIN_ALLOW_THREADS
327 dbus_bus_remove_match (self->conn, rule, NULL);
328 Py_END_ALLOW_THREADS
329 Py_RETURN_NONE;
332 /* Bus type object ================================================== */
334 static struct PyMethodDef Bus_tp_methods[] = {
335 #define ENTRY(name, flags) {#name, (PyCFunction)Bus_##name, flags, Bus_##name##__doc__},
336 ENTRY(get_unique_name, METH_NOARGS)
337 ENTRY(get_unix_user, METH_VARARGS)
338 ENTRY(start_service_by_name, METH_VARARGS)
339 ENTRY(request_name, METH_VARARGS)
340 ENTRY(release_name, METH_VARARGS)
341 ENTRY(name_has_owner, METH_VARARGS)
342 ENTRY(name_has_owner, METH_VARARGS)
343 ENTRY(add_match_string, METH_VARARGS)
344 ENTRY(add_match_string_non_blocking, METH_VARARGS)
345 ENTRY(remove_match_string, METH_VARARGS)
346 ENTRY(remove_match_string_non_blocking, METH_VARARGS)
347 #undef ENTRY
348 {NULL},
351 /* TODO: Call this dbus.Bus rather than _dbus_bindings._Bus if it ever gets
352 * all the functionality of the current dbus._dbus.Bus (mainly creation of
353 * proxies).
355 static PyTypeObject BusType = {
356 PyObject_HEAD_INIT(NULL)
357 0, /*ob_size*/
358 "_dbus_bindings._Bus", /*tp_name*/
359 0, /*tp_basicsize*/
360 0, /*tp_itemsize*/
361 /* methods */
362 (destructor)Connection_tp_dealloc, /*tp_dealloc*/
363 0, /*tp_print*/
364 0, /*tp_getattr*/
365 0, /*tp_setattr*/
366 0, /*tp_compare*/
367 0, /*tp_repr*/
368 0, /*tp_as_number*/
369 0, /*tp_as_sequence*/
370 0, /*tp_as_mapping*/
371 0, /*tp_hash*/
372 0, /*tp_call*/
373 0, /*tp_str*/
374 0, /*tp_getattro*/
375 0, /*tp_setattro*/
376 0, /*tp_as_buffer*/
377 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
378 Bus_tp_doc, /*tp_doc*/
379 0, /*tp_traverse*/
380 0, /*tp_clear*/
381 0, /*tp_richcompare*/
382 0, /*tp_weaklistoffset*/
383 0, /*tp_iter*/
384 0, /*tp_iternext*/
385 Bus_tp_methods, /*tp_methods*/
386 0, /*tp_members*/
387 0, /*tp_getset*/
388 &ConnectionType, /*tp_base*/
389 0, /*tp_dict*/
390 0, /*tp_descr_get*/
391 0, /*tp_descr_set*/
392 0, /*tp_dictoffset*/
393 0, /*tp_init*/
394 0, /*tp_alloc*/
395 Bus_tp_new, /*tp_new*/
396 0, /*tp_free*/
397 0, /*tp_is_gc*/
400 static inline int
401 init_bus_types (void)
403 if (PyType_Ready (&BusType) < 0) return 0;
404 return 1;
407 static inline int
408 insert_bus_types (PyObject *this_module)
410 if (PyModule_AddObject (this_module, "_Bus",
411 (PyObject *)&BusType) < 0) return 0;
412 return 1;
415 /* vim:set ft=c cino< sw=4 sts=4 et: */