From c531a709f3b0f05c0a95aa932045d6e2209ae7b9 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Mon, 16 Dec 2002 00:26:05 +0000 Subject: 2002-12-16 Anders Carlsson * Makefile.am: * configure.in: Add GLib checks and fixup .pc files * glib/Makefile.am: * glib/dbus-glib.h: * glib/dbus-gmain.c: (gdbus_connection_prepare), (gdbus_connection_check), (gdbus_connection_dispatch), (gdbus_add_connection_watch), (gdbus_remove_connection_watch), (dbus_connection_gsource_new): * glib/dbus-gthread.c: (dbus_gmutex_new), (dbus_gmutex_free), (dbus_gmutex_lock), (dbus_gmutex_unlock), (dbus_gthread_init): * glib/test-dbus-glib.c: (message_handler), (main): Add GLib support. --- glib/dbus-gmain.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 glib/dbus-gmain.c (limited to 'glib/dbus-gmain.c') diff --git a/glib/dbus-gmain.c b/glib/dbus-gmain.c new file mode 100644 index 00000000..0b9ac9f1 --- /dev/null +++ b/glib/dbus-gmain.c @@ -0,0 +1,194 @@ +/* -*- mode: C; c-file-style: "gnu" -*- */ +/* dbus-gmain.c GLib main loop integration + * + * Copyright (C) 2002 CodeFactory AB + * + * Licensed under the Academic Free License version 1.2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "dbus-glib.h" +#include + +typedef struct _DBusGSource DBusGSource; + +struct _DBusGSource +{ + GSource source; + + DBusConnection *connection; + + GList *poll_fds; + GHashTable *watches; +}; + +static gboolean gdbus_connection_prepare (GSource *source, + gint *timeout); +static gboolean gdbus_connection_check (GSource *source); +static gboolean gdbus_connection_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data); + +static GSourceFuncs dbus_funcs = { + gdbus_connection_prepare, + gdbus_connection_check, + gdbus_connection_dispatch, + NULL +}; + +static gboolean +gdbus_connection_prepare (GSource *source, + gint *timeout) +{ + DBusConnection *connection = ((DBusGSource *)source)->connection; + + *timeout = -1; + + return (dbus_connection_peek_message (connection) != NULL); +} + +static gboolean +gdbus_connection_check (GSource *source) +{ + DBusGSource *dbus_source = (DBusGSource *)source; + GList *list; + + list = dbus_source->poll_fds; + + while (list) + { + GPollFD *poll_fd = list->data; + + if (poll_fd->revents != 0) + return TRUE; + + list = list->next; + } + + return FALSE; +} + +static gboolean +gdbus_connection_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + DBusGSource *dbus_source = (DBusGSource *)source; + DBusMessageHandler handler = (DBusMessageHandler)callback; + DBusMessage *message; + + GList *list; + + list = dbus_source->poll_fds; + + while (list) + { + GPollFD *poll_fd = list->data; + + g_print ("poll_fd is: %p\n", poll_fd); + if (poll_fd->revents != 0) + { + DBusWatch *watch = g_hash_table_lookup (dbus_source->watches, poll_fd); + guint condition = 0; + + if (poll_fd->revents & G_IO_IN) + condition |= DBUS_WATCH_READABLE; + if (poll_fd->revents & G_IO_OUT) + condition |= DBUS_WATCH_WRITABLE; + if (poll_fd->revents & G_IO_ERR) + condition |= DBUS_WATCH_ERROR; + if (poll_fd->revents & G_IO_HUP) + condition |= DBUS_WATCH_HANGUP; + + dbus_connection_handle_watch (dbus_source->connection, watch, condition); + } + + list = list->next; + } + + while ((message = dbus_connection_pop_message (dbus_source->connection))) + { + handler (dbus_source->connection, message, user_data); + + dbus_message_unref (message); + } + + return TRUE; +} + +static void +gdbus_add_connection_watch (DBusWatch *watch, + DBusGSource *source) +{ + GPollFD *poll_fd; + guint flags; + + poll_fd = g_new (GPollFD, 1); + poll_fd->fd = dbus_watch_get_fd (watch); + + poll_fd->events = 0; + flags = dbus_watch_get_flags (watch); + dbus_watch_set_data (watch, poll_fd, NULL); + + if (flags & DBUS_WATCH_READABLE) + poll_fd->events |= G_IO_IN; + + if (flags & DBUS_WATCH_WRITABLE) + poll_fd->events |= G_IO_OUT; + + g_source_add_poll ((GSource *)source, poll_fd); + + g_print ("Add connection watch: %p!\n", watch); + + source->poll_fds = g_list_prepend (source->poll_fds, poll_fd); + g_hash_table_insert (source->watches, poll_fd, watch); +} + +static void +gdbus_remove_connection_watch (DBusWatch *watch, + DBusGSource *source) +{ + GPollFD *poll_fd; + + poll_fd = dbus_watch_get_data (watch); + + source->poll_fds = g_list_remove (source->poll_fds, poll_fd); + g_hash_table_remove (source->watches, poll_fd); + g_source_remove_poll ((GSource *)source, poll_fd); + + g_free (poll_fd); +} + +GSource * +dbus_connection_gsource_new (DBusConnection *connection) +{ + GSource *source = g_source_new (&dbus_funcs, sizeof (DBusGSource)); + DBusGSource *dbus_source = (DBusGSource *)source; + + dbus_source->watches = g_hash_table_new (NULL, NULL); + dbus_source->connection = connection; + dbus_connection_ref (dbus_source->connection); + + dbus_connection_set_watch_functions (connection, + (DBusAddWatchFunction) gdbus_add_connection_watch, + (DBusRemoveWatchFunction) gdbus_remove_connection_watch, + dbus_source, + NULL); + + + return source; +} -- cgit