summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2005-01-30 23:06:32 +0000
committerHavoc Pennington <hp@redhat.com>2005-01-30 23:06:32 +0000
commit1dcacffc325e50754d4cc3338822d1f03c8b6e45 (patch)
tree2e41d02141bf61be249ee6a9f8df6bd891a7d1e1 /tools
parent4d985d98906577e3344fc1107d341b8ac969db1e (diff)
2005-01-30 Havoc Pennington <hp@redhat.com>
* glib/dbus-glib.c (dbus_g_pending_call_set_notify): new function (dbus_g_pending_call_cancel): new function * dbus/dbus-glib.h: move GType decls for connection/message here; * dbus/dbus-glib.c: move all the g_type and ref/unref stuff in here, just kind of rationalizing how we handle all that * tools/dbus-names-model.c: new file for a tree model listing the services on a bus * tools/dbus-tree-view.c (model_new): use proper typing on the model rows
Diffstat (limited to 'tools')
-rw-r--r--tools/Makefile.am2
-rw-r--r--tools/dbus-names-model.c352
-rw-r--r--tools/dbus-names-model.h31
-rw-r--r--tools/dbus-tree-view.c13
-rw-r--r--tools/dbus-viewer.c110
5 files changed, 437 insertions, 71 deletions
diff --git a/tools/Makefile.am b/tools/Makefile.am
index d3accc88..b6747b0f 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -31,6 +31,8 @@ dbus_cleanup_sockets_SOURCES= \
dbus-cleanup-sockets.c
dbus_viewer_SOURCES= \
+ dbus-names-model.c \
+ dbus-names-model.h \
dbus-tree-view.c \
dbus-tree-view.h \
dbus-viewer.c
diff --git a/tools/dbus-names-model.c b/tools/dbus-names-model.c
new file mode 100644
index 00000000..09f1236d
--- /dev/null
+++ b/tools/dbus-names-model.c
@@ -0,0 +1,352 @@
+/* -*- mode: C; c-file-style: "gnu" -*- */
+/* dbus-names-model.c GtkTreeModel for names on the bus
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * 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-names-model.h"
+#include <glib/gi18n.h>
+
+enum
+{
+ MODEL_COLUMN_NAME_DATA,
+
+ MODEL_COLUMN_LAST
+};
+
+typedef struct
+{
+ int refcount;
+ char *name;
+} NameData;
+
+static NameData*
+name_data_new (const char *name)
+{
+ NameData *nd;
+
+ nd = g_new0 (NameData, 1);
+
+ nd->refcount = 1;
+ nd->name = g_strdup (name);
+
+ return nd;
+}
+
+static NameData*
+name_data_ref (NameData *nd)
+{
+ nd->refcount += 1;
+ return nd;
+}
+
+static void
+name_data_unref (NameData *nd)
+{
+ nd->refcount -= 1;
+ if (nd->refcount == 0)
+ {
+ g_free (nd->name);
+ g_free (nd);
+ }
+}
+
+static GType
+name_data_get_gtype (void)
+{
+ static GType our_type = 0;
+
+ if (our_type == 0)
+ our_type = g_boxed_type_register_static ("NameData",
+ (GBoxedCopyFunc) name_data_ref,
+ (GBoxedFreeFunc) name_data_unref);
+
+ return our_type;
+}
+
+#define NAME_DATA_TYPE (name_data_get_gtype())
+
+
+typedef struct NamesModel NamesModel;
+typedef struct NamesModelClass NamesModelClass;
+
+GType names_model_get_type (void);
+
+struct NamesModel
+{
+ GtkTreeStore parent;
+ DBusGConnection *connection;
+ DBusGProxy *driver_proxy;
+ DBusGPendingCall *pending_list_names;
+};
+
+struct NamesModelClass
+{
+ GtkTreeStoreClass parent;
+};
+
+#define TYPE_NAMES_MODEL (names_model_get_type ())
+#define NAMES_MODEL(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), TYPE_NAMES_MODEL, NamesModel))
+#define NAMES_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_NAMES_MODEL, NamesModelClass))
+#define IS_NAMES_MODEL(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), TYPE_NAMES_MODEL))
+#define IS_NAMES_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_NAMES_MODEL))
+#define NAMES_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_NAMES_MODEL, NamesModelClass))
+
+static void
+have_names_notify (DBusGPendingCall *call,
+ void *data)
+{
+ NamesModel *names_model;
+ GError *error;
+ char **names;
+ int n_elements;
+ int i;
+
+ names_model = NAMES_MODEL (data);
+
+ g_assert (names_model->pending_list_names);
+ g_assert (names_model->driver_proxy);
+
+ names = NULL;
+ error = NULL;
+ if (!dbus_g_proxy_end_call (names_model->driver_proxy,
+ names_model->pending_list_names,
+ &error, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
+ &names, &n_elements, DBUS_TYPE_INVALID))
+ {
+ g_assert (names == NULL);
+ g_assert (error != NULL);
+
+ g_printerr (_("Failed to load names on the bus: %s\n"), error->message);
+ return;
+ }
+
+ i = 0;
+ while (names[i])
+ {
+ NameData *nd;
+ GtkTreeIter iter;
+
+ nd = name_data_new (names[i]);
+
+ gtk_tree_store_append (GTK_TREE_STORE (names_model),
+ &iter, NULL);
+
+ gtk_tree_store_set (GTK_TREE_STORE (names_model),
+ &iter,
+ MODEL_COLUMN_NAME_DATA, nd,
+ -1);
+
+ name_data_unref (nd);
+
+ ++i;
+ }
+
+ g_strfreev (names);
+}
+
+static void
+names_model_reload (NamesModel *names_model)
+{
+ GtkTreeStore *tree_store;
+
+ tree_store = GTK_TREE_STORE (names_model);
+
+ if (names_model->pending_list_names)
+ {
+ dbus_g_pending_call_cancel (names_model->pending_list_names);
+ dbus_g_pending_call_unref (names_model->pending_list_names);
+ names_model->pending_list_names = NULL;
+ }
+
+ gtk_tree_store_clear (tree_store);
+
+ if (names_model->connection == NULL)
+ return;
+
+ names_model->pending_list_names =
+ dbus_g_proxy_begin_call (names_model->driver_proxy,
+ "ListNames",
+ DBUS_TYPE_INVALID);
+
+ dbus_g_pending_call_set_notify (names_model->pending_list_names,
+ have_names_notify, names_model, NULL);
+}
+
+static void
+names_model_set_connection (NamesModel *names_model,
+ DBusGConnection *connection)
+{
+ const char *match_rule = "type='signal',member='NameOwnerChanged'";
+
+ g_return_if_fail (IS_NAMES_MODEL (names_model));
+
+ if (connection == names_model->connection)
+ return;
+
+ if (names_model->connection)
+ {
+ dbus_g_proxy_call_no_reply (names_model->driver_proxy,
+ "RemoveMatch",
+ DBUS_TYPE_STRING, &match_rule,
+ DBUS_TYPE_INVALID);
+ g_object_unref (names_model->driver_proxy);
+ names_model->driver_proxy = NULL;
+ dbus_g_connection_unref (names_model->connection);
+ names_model->connection = NULL;
+ }
+
+ if (connection)
+ {
+ names_model->connection = connection;
+ dbus_g_connection_ref (names_model->connection);
+
+ names_model->driver_proxy =
+ dbus_g_proxy_new_for_name (names_model->connection,
+ DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
+ DBUS_PATH_ORG_FREEDESKTOP_DBUS,
+ DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS);
+ g_assert (names_model->driver_proxy);
+ }
+
+ names_model_reload (names_model);
+}
+
+G_DEFINE_TYPE(NamesModel, names_model, GTK_TYPE_TREE_STORE)
+
+/* Properties */
+enum
+{
+ PROP_0,
+ PROP_CONNECTION
+};
+
+static void
+names_model_dispose (GObject *object)
+{
+ NamesModel *names_model = NAMES_MODEL (object);
+
+ names_model_set_connection (names_model, NULL);
+
+ g_assert (names_model->connection == NULL);
+ g_assert (names_model->driver_proxy == NULL);
+ g_assert (names_model->pending_list_names == NULL);
+
+ (G_OBJECT_CLASS (names_model_parent_class)->dispose) (object);
+}
+
+static void
+names_model_finalize (GObject *object)
+{
+ NamesModel *names_model = NAMES_MODEL (object);
+
+ g_assert (names_model->connection == NULL);
+ g_assert (names_model->driver_proxy == NULL);
+ g_assert (names_model->pending_list_names == NULL);
+
+ (G_OBJECT_CLASS (names_model_parent_class)->finalize) (object);
+}
+
+static void
+names_model_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ NamesModel *names_model;
+
+ names_model = NAMES_MODEL (object);
+
+ switch (prop_id)
+ {
+ case PROP_CONNECTION:
+ names_model_set_connection (names_model, g_value_get_boxed (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+names_model_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ NamesModel *names_model;
+
+ names_model = NAMES_MODEL (object);
+
+ switch (prop_id)
+ {
+ case PROP_CONNECTION:
+ g_value_set_boxed (value, names_model->connection);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+names_model_init (NamesModel *names_model)
+{
+ GtkTreeStore *tree_store;
+ GType types[MODEL_COLUMN_LAST];
+
+ tree_store = GTK_TREE_STORE (names_model);
+
+ types[0] = NAME_DATA_TYPE;
+ gtk_tree_store_set_column_types (tree_store, MODEL_COLUMN_LAST, types);
+}
+
+static void
+names_model_class_init (NamesModelClass *names_model_class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (names_model_class);
+
+ gobject_class->finalize = names_model_finalize;
+ gobject_class->dispose = names_model_dispose;
+ gobject_class->set_property = names_model_set_property;
+ gobject_class->get_property = names_model_get_property;
+
+ g_object_class_install_property (gobject_class,
+ PROP_CONNECTION,
+ g_param_spec_boxed ("connection",
+ _("Bus connection"),
+ _("Connection to the message bus"),
+ DBUS_TYPE_G_CONNECTION,
+ G_PARAM_READWRITE));
+}
+
+GtkTreeModel*
+names_model_new (DBusGConnection *connection)
+{
+ NamesModel *names_model;
+
+ names_model = g_object_new (TYPE_NAMES_MODEL,
+ "connection", connection,
+ NULL);
+
+ return GTK_TREE_MODEL (names_model);
+}
+
diff --git a/tools/dbus-names-model.h b/tools/dbus-names-model.h
new file mode 100644
index 00000000..c2b54fc8
--- /dev/null
+++ b/tools/dbus-names-model.h
@@ -0,0 +1,31 @@
+/* -*- mode: C; c-file-style: "gnu" -*- */
+/* dbus-names-model.h GtkTreeModel for names on the bus
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * 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
+ *
+ */
+#ifndef DBUS_NAMES_MODEL_H
+#define DBUS_NAMES_MODEL_H
+
+#include <gtk/gtk.h>
+#include <dbus/dbus-glib.h>
+
+GtkTreeModel* names_model_new (DBusGConnection *connection);
+
+#endif /* DBUS_NAMES_MODEL_H */
diff --git a/tools/dbus-tree-view.c b/tools/dbus-tree-view.c
index 7c52935e..d2898fb3 100644
--- a/tools/dbus-tree-view.c
+++ b/tools/dbus-tree-view.c
@@ -23,10 +23,7 @@
#include <string.h>
#include <config.h>
#include "dbus-tree-view.h"
-
-#include <libintl.h>
-#define _(x) dgettext (GETTEXT_PACKAGE, x)
-#define N_(x) x
+#include <glib/gi18n.h>
enum
{
@@ -52,12 +49,7 @@ model_new (void)
GtkTreeStore *store;
store = gtk_tree_store_new (MODEL_COLUMN_LAST,
- G_TYPE_POINTER);
- /* FIXME, BASE_INFO_TYPE doesn't work right (crashes),
- * G_TYPE_POINTER has a memleak. BASE_INFO_TYPE problem maybe just a
- * bad GTK build on my laptop.
- */
- /* BASE_INFO_TYPE); */
+ BASE_INFO_TYPE);
model = GTK_TREE_MODEL (store);
@@ -114,7 +106,6 @@ set_info (GtkTreeModel *model,
*/
if (root != NULL)
{
- base_info_ref (info); /* FIXME once boxed types are working */
gtk_tree_store_set (store, root,
MODEL_COLUMN_INFO, info,
-1);
diff --git a/tools/dbus-viewer.c b/tools/dbus-viewer.c
index abd299f6..524030c6 100644
--- a/tools/dbus-viewer.c
+++ b/tools/dbus-viewer.c
@@ -27,58 +27,19 @@
#include <string.h>
#include <gtk/gtk.h>
#include "dbus-tree-view.h"
+#include "dbus-names-model.h"
#include <glib/dbus-gparser.h>
#include <glib/dbus-gutils.h>
#include <dbus/dbus-glib.h>
-
-#include <libintl.h>
-#define _(x) dgettext (GETTEXT_PACKAGE, x)
-#define N_(x) x
-
-typedef struct
-{
- int refcount;
- char *name;
-
-} ServiceData;
-
-static ServiceData*
-service_data_new (const char *name)
-{
- ServiceData *sd;
-
- sd = g_new0 (ServiceData, 1);
-
- sd->refcount = 1;
- sd->name = g_strdup (name);
-
- return sd;
-}
-
-static void
-service_data_ref (ServiceData *sd)
-{
- sd->refcount += 1;
-}
-
-static void
-service_data_unref (ServiceData *sd)
-{
- sd->refcount -= 1;
- if (sd->refcount == 0)
- {
- g_free (sd->name);
- g_free (sd);
- }
-}
+#include <glib/gi18n.h>
typedef struct
{
GtkWidget *window;
GtkWidget *treeview;
- GtkWidget *service_menu;
+ GtkWidget *name_menu;
- GSList *services;
+ GtkTreeModel *names_model;
} TreeWindow;
@@ -92,12 +53,14 @@ window_closed_callback (GtkWidget *window,
}
static TreeWindow*
-tree_window_new (void)
+tree_window_new (DBusGConnection *connection,
+ GtkTreeModel *names_model)
{
TreeWindow *w;
GtkWidget *sw;
GtkWidget *vbox;
GtkWidget *hbox;
+ GtkWidget *combo;
/* Should use glade, blah */
@@ -117,6 +80,17 @@ tree_window_new (void)
hbox = gtk_hbox_new (FALSE, 6);
gtk_container_add (GTK_CONTAINER (vbox), hbox);
+
+ /* Create names option menu */
+ if (connection)
+ {
+ w->names_model = names_model;
+
+ combo = gtk_combo_box_new_with_model (w->names_model);
+
+ gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, FALSE, 0);
+ }
+
/* Create tree view */
sw = gtk_scrolled_window_new (NULL, NULL);
@@ -130,10 +104,6 @@ tree_window_new (void)
gtk_container_add (GTK_CONTAINER (sw), w->treeview);
- /* Create services option menu */
-
-
-
/* Show everything */
gtk_widget_show_all (w->window);
@@ -287,11 +257,11 @@ load_child_nodes (const char *service_name,
}
static NodeInfo*
-load_from_service (const char *service_name,
- GError **error)
+load_from_service (DBusGConnection *connection,
+ const char *service_name,
+ GError **error)
{
- DBusGConnection *connection;
- DBusGProxy *root_proxy;
+ DBusGProxy *root_proxy;
DBusGPendingCall *call;
const char *data;
NodeInfo *node;
@@ -300,11 +270,7 @@ load_from_service (const char *service_name,
node = NULL;
call = NULL;
path = NULL;
-
- connection = dbus_g_bus_get (DBUS_BUS_SESSION, error);
- if (connection == NULL)
- return NULL;
-
+
#if 1
/* this will end up autolaunching the service when we introspect it */
root_proxy = dbus_g_proxy_new_for_name (connection,
@@ -396,6 +362,9 @@ main (int argc, char **argv)
gboolean end_of_args;
GSList *tmp;
gboolean services;
+ DBusGConnection *connection;
+ GError *error;
+ GtkTreeModel *names_model;
bindtextdomain (GETTEXT_PACKAGE, DBUS_LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
@@ -443,20 +412,41 @@ main (int argc, char **argv)
++i;
}
+ if (services)
+ {
+ error = NULL;
+ connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+ if (connection == NULL)
+ {
+ g_printerr ("Could not open bus connection: %s\n",
+ error->message);
+ g_error_free (error);
+ exit (1);
+ }
+
+ g_assert (connection == dbus_g_bus_get (DBUS_BUS_SESSION, NULL));
+
+ names_model = names_model_new (connection);
+ }
+ else
+ {
+ connection = NULL;
+ names_model = NULL;
+ }
+
files = g_slist_reverse (files);
tmp = files;
while (tmp != NULL)
{
NodeInfo *node;
- GError *error;
const char *filename;
filename = tmp->data;
error = NULL;
if (services)
- node = load_from_service (filename, &error);
+ node = load_from_service (connection, filename, &error);
else
node = description_load_from_file (filename,
&error);
@@ -485,7 +475,7 @@ main (int argc, char **argv)
path = _dbus_gutils_split_path (name);
- w = tree_window_new ();
+ w = tree_window_new (connection, names_model);
dbus_tree_view_update (GTK_TREE_VIEW (w->treeview),
(const char**) path,
node);