diff options
author | Havoc Pennington <hp@redhat.com> | 2005-01-30 23:06:32 +0000 |
---|---|---|
committer | Havoc Pennington <hp@redhat.com> | 2005-01-30 23:06:32 +0000 |
commit | 1dcacffc325e50754d4cc3338822d1f03c8b6e45 (patch) | |
tree | 2e41d02141bf61be249ee6a9f8df6bd891a7d1e1 /tools | |
parent | 4d985d98906577e3344fc1107d341b8ac969db1e (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.am | 2 | ||||
-rw-r--r-- | tools/dbus-names-model.c | 352 | ||||
-rw-r--r-- | tools/dbus-names-model.h | 31 | ||||
-rw-r--r-- | tools/dbus-tree-view.c | 13 | ||||
-rw-r--r-- | tools/dbus-viewer.c | 110 |
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); |