|
Packit |
130fc8 |
/* Implementation of main-loop integration for dbus-python.
|
|
Packit |
130fc8 |
*
|
|
Packit |
130fc8 |
* Copyright (C) 2006 Collabora Ltd. <http://www.collabora.co.uk/>
|
|
Packit |
130fc8 |
* Copyright (C) 2008 Huang Peng <phuang@redhat.com>
|
|
Packit |
130fc8 |
*
|
|
Packit |
130fc8 |
* Permission is hereby granted, free of charge, to any person
|
|
Packit |
130fc8 |
* obtaining a copy of this software and associated documentation
|
|
Packit |
130fc8 |
* files (the "Software"), to deal in the Software without
|
|
Packit |
130fc8 |
* restriction, including without limitation the rights to use, copy,
|
|
Packit |
130fc8 |
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
Packit |
130fc8 |
* of the Software, and to permit persons to whom the Software is
|
|
Packit |
130fc8 |
* furnished to do so, subject to the following conditions:
|
|
Packit |
130fc8 |
*
|
|
Packit |
130fc8 |
* The above copyright notice and this permission notice shall be
|
|
Packit |
130fc8 |
* included in all copies or substantial portions of the Software.
|
|
Packit |
130fc8 |
*
|
|
Packit |
130fc8 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Packit |
130fc8 |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Packit |
130fc8 |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Packit |
130fc8 |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
Packit |
130fc8 |
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
Packit |
130fc8 |
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
Packit |
130fc8 |
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
Packit |
130fc8 |
* DEALINGS IN THE SOFTWARE.
|
|
Packit |
130fc8 |
*/
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
#include "dbus_bindings-internal.h"
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
/* Native mainloop wrapper ========================================= */
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
PyDoc_STRVAR(NativeMainLoop_tp_doc,
|
|
Packit |
130fc8 |
"Object representing D-Bus main loop integration done in native code.\n"
|
|
Packit |
130fc8 |
"Cannot be instantiated directly.\n"
|
|
Packit |
130fc8 |
);
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
static PyTypeObject NativeMainLoop_Type;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
DEFINE_CHECK(NativeMainLoop)
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
typedef struct {
|
|
Packit |
130fc8 |
PyObject_HEAD
|
|
Packit |
130fc8 |
/* Called with the GIL held, should set a Python exception on error */
|
|
Packit |
130fc8 |
dbus_bool_t (*set_up_connection_cb)(DBusConnection *, void *);
|
|
Packit |
130fc8 |
dbus_bool_t (*set_up_server_cb)(DBusServer *, void *);
|
|
Packit |
130fc8 |
/* Called in a destructor. Must not touch the exception state (use
|
|
Packit |
130fc8 |
* PyErr_Fetch and PyErr_Restore if necessary). */
|
|
Packit |
130fc8 |
void (*free_cb)(void *);
|
|
Packit |
130fc8 |
void *data;
|
|
Packit |
130fc8 |
} NativeMainLoop;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
static void NativeMainLoop_tp_dealloc(NativeMainLoop *self)
|
|
Packit |
130fc8 |
{
|
|
Packit |
130fc8 |
if (self->data && self->free_cb) {
|
|
Packit |
130fc8 |
(self->free_cb)(self->data);
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
PyObject_Del((PyObject *)self);
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
static PyTypeObject NativeMainLoop_Type = {
|
|
Packit |
130fc8 |
PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
|
|
Packit |
130fc8 |
"dbus.mainloop.NativeMainLoop",
|
|
Packit |
130fc8 |
sizeof(NativeMainLoop),
|
|
Packit |
130fc8 |
0,
|
|
Packit |
130fc8 |
(destructor)NativeMainLoop_tp_dealloc, /* tp_dealloc */
|
|
Packit |
130fc8 |
0, /* tp_print */
|
|
Packit |
130fc8 |
0, /* tp_getattr */
|
|
Packit |
130fc8 |
0, /* tp_setattr */
|
|
Packit |
130fc8 |
0, /* tp_compare */
|
|
Packit |
130fc8 |
0, /* tp_repr */
|
|
Packit |
130fc8 |
0, /* tp_as_number */
|
|
Packit |
130fc8 |
0, /* tp_as_sequence */
|
|
Packit |
130fc8 |
0, /* tp_as_mapping */
|
|
Packit |
130fc8 |
0, /* tp_hash */
|
|
Packit |
130fc8 |
0, /* tp_call */
|
|
Packit |
130fc8 |
0, /* tp_str */
|
|
Packit |
130fc8 |
0, /* tp_getattro */
|
|
Packit |
130fc8 |
0, /* tp_setattro */
|
|
Packit |
130fc8 |
0, /* tp_as_buffer */
|
|
Packit |
130fc8 |
Py_TPFLAGS_DEFAULT, /* tp_flags */
|
|
Packit |
130fc8 |
NativeMainLoop_tp_doc, /* tp_doc */
|
|
Packit |
130fc8 |
0, /* tp_traverse */
|
|
Packit |
130fc8 |
0, /* tp_clear */
|
|
Packit |
130fc8 |
0, /* tp_richcompare */
|
|
Packit |
130fc8 |
0, /* tp_weaklistoffset */
|
|
Packit |
130fc8 |
0, /* tp_iter */
|
|
Packit |
130fc8 |
0, /* tp_iternext */
|
|
Packit |
130fc8 |
0, /* tp_methods */
|
|
Packit |
130fc8 |
0, /* tp_members */
|
|
Packit |
130fc8 |
0, /* tp_getset */
|
|
Packit |
130fc8 |
0, /* tp_base */
|
|
Packit |
130fc8 |
0, /* tp_dict */
|
|
Packit |
130fc8 |
0, /* tp_descr_get */
|
|
Packit |
130fc8 |
0, /* tp_descr_set */
|
|
Packit |
130fc8 |
0, /* tp_dictoffset */
|
|
Packit |
130fc8 |
0, /* tp_init */
|
|
Packit |
130fc8 |
0, /* tp_alloc */
|
|
Packit |
130fc8 |
/* deliberately not callable! */
|
|
Packit |
130fc8 |
0, /* tp_new */
|
|
Packit |
130fc8 |
};
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
/* Internal C API for Connection, Bus, Server ======================= */
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
dbus_bool_t
|
|
Packit |
130fc8 |
dbus_py_check_mainloop_sanity(PyObject *mainloop)
|
|
Packit |
130fc8 |
{
|
|
Packit |
130fc8 |
if (NativeMainLoop_Check(mainloop)) {
|
|
Packit |
130fc8 |
return TRUE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
PyErr_SetString(PyExc_TypeError,
|
|
Packit |
130fc8 |
"A dbus.mainloop.NativeMainLoop instance is required");
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
dbus_bool_t
|
|
Packit |
130fc8 |
dbus_py_set_up_connection(PyObject *conn, PyObject *mainloop)
|
|
Packit |
130fc8 |
{
|
|
Packit |
130fc8 |
if (NativeMainLoop_Check(mainloop)) {
|
|
Packit |
130fc8 |
/* Native mainloops are allowed to do arbitrary strange things */
|
|
Packit |
130fc8 |
NativeMainLoop *nml = (NativeMainLoop *)mainloop;
|
|
Packit |
130fc8 |
DBusConnection *dbc = DBusPyConnection_BorrowDBusConnection(conn);
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
if (!dbc) {
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
return (nml->set_up_connection_cb)(dbc, nml->data);
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
PyErr_SetString(PyExc_TypeError,
|
|
Packit |
130fc8 |
"A dbus.mainloop.NativeMainLoop instance is required");
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
dbus_bool_t
|
|
Packit |
130fc8 |
dbus_py_set_up_server(PyObject *server, PyObject *mainloop)
|
|
Packit |
130fc8 |
{
|
|
Packit |
130fc8 |
if (NativeMainLoop_Check(mainloop)) {
|
|
Packit |
130fc8 |
/* Native mainloops are allowed to do arbitrary strange things */
|
|
Packit |
130fc8 |
NativeMainLoop *nml = (NativeMainLoop *)mainloop;
|
|
Packit |
130fc8 |
DBusServer *dbs = DBusPyServer_BorrowDBusServer(server);
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
if (!dbs) {
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
return (nml->set_up_server_cb)(dbs, nml->data);
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
PyErr_SetString(PyExc_TypeError,
|
|
Packit |
130fc8 |
"A dbus.mainloop.NativeMainLoop instance is required");
|
|
Packit |
130fc8 |
return FALSE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
/* C API ============================================================ */
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
PyObject *
|
|
Packit |
130fc8 |
DBusPyNativeMainLoop_New4(dbus_bool_t (*conn_cb)(DBusConnection *, void *),
|
|
Packit |
130fc8 |
dbus_bool_t (*server_cb)(DBusServer *, void *),
|
|
Packit |
130fc8 |
void (*free_cb)(void *),
|
|
Packit |
130fc8 |
void *data)
|
|
Packit |
130fc8 |
{
|
|
Packit |
130fc8 |
NativeMainLoop *self = PyObject_New(NativeMainLoop, &NativeMainLoop_Type);
|
|
Packit |
130fc8 |
if (self) {
|
|
Packit |
130fc8 |
self->data = data;
|
|
Packit |
130fc8 |
self->free_cb = free_cb;
|
|
Packit |
130fc8 |
self->set_up_connection_cb = conn_cb;
|
|
Packit |
130fc8 |
self->set_up_server_cb = server_cb;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
return (PyObject *)self;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
/* Null mainloop implementation ===================================== */
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
static dbus_bool_t
|
|
Packit |
130fc8 |
noop_main_loop_cb(void *conn_or_server UNUSED, void *data UNUSED)
|
|
Packit |
130fc8 |
{
|
|
Packit |
130fc8 |
return TRUE;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
#define noop_conn_cb ((dbus_bool_t (*)(DBusConnection *, void *))(noop_main_loop_cb))
|
|
Packit |
130fc8 |
#define noop_server_cb ((dbus_bool_t (*)(DBusServer *, void *))(noop_main_loop_cb))
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
/* Initialization =================================================== */
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
dbus_bool_t
|
|
Packit |
130fc8 |
dbus_py_init_mainloop(void)
|
|
Packit |
130fc8 |
{
|
|
Packit |
130fc8 |
if (PyType_Ready (&NativeMainLoop_Type) < 0) return 0;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
return 1;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
dbus_bool_t
|
|
Packit |
130fc8 |
dbus_py_insert_mainloop_types(PyObject *this_module)
|
|
Packit |
130fc8 |
{
|
|
Packit |
130fc8 |
PyObject *null_main_loop = DBusPyNativeMainLoop_New4(noop_conn_cb,
|
|
Packit |
130fc8 |
noop_server_cb,
|
|
Packit |
130fc8 |
NULL,
|
|
Packit |
130fc8 |
NULL);
|
|
Packit |
130fc8 |
if (!null_main_loop) return 0;
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
/* PyModule_AddObject steals a ref */
|
|
Packit |
130fc8 |
Py_INCREF (&NativeMainLoop_Type);
|
|
Packit |
130fc8 |
if (PyModule_AddObject (this_module, "NativeMainLoop",
|
|
Packit |
130fc8 |
(PyObject *)&NativeMainLoop_Type) < 0) return 0;
|
|
Packit |
130fc8 |
if (PyModule_AddObject (this_module, "NULL_MAIN_LOOP",
|
|
Packit |
130fc8 |
null_main_loop) < 0) return 0;
|
|
Packit |
130fc8 |
return 1;
|
|
Packit |
130fc8 |
}
|
|
Packit |
130fc8 |
|
|
Packit |
130fc8 |
/* vim:set ft=c cino< sw=4 sts=4 et: */
|