dbus/tools Makefile.am, 1.9, 1.10 dbus-names-model.c, NONE, 1.1 dbus-names-model.h, NONE, 1.1 dbus-tree-view.c, 1.5, 1.6 dbus-viewer.c, 1.6, 1.7

Havoc Pennington hp at freedesktop.org
Sun Jan 30 15:06:35 PST 2005


Update of /cvs/dbus/dbus/tools
In directory gabe:/tmp/cvs-serv17174/tools

Modified Files:
	Makefile.am dbus-tree-view.c dbus-viewer.c 
Added Files:
	dbus-names-model.c dbus-names-model.h 
Log Message:
2005-01-30  Havoc Pennington  <hp at 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



Index: Makefile.am
===================================================================
RCS file: /cvs/dbus/dbus/tools/Makefile.am,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- Makefile.am	21 Apr 2004 21:29:07 -0000	1.9
+++ Makefile.am	30 Jan 2005 23:06:32 -0000	1.10
@@ -31,6 +31,8 @@
 	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

--- NEW FILE: dbus-names-model.c ---
/* -*- 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);
}


--- NEW FILE: dbus-names-model.h ---
/* -*- 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 */

Index: dbus-tree-view.c
===================================================================
RCS file: /cvs/dbus/dbus/tools/dbus-tree-view.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- dbus-tree-view.c	29 Jan 2005 20:12:22 -0000	1.5
+++ dbus-tree-view.c	30 Jan 2005 23:06:32 -0000	1.6
@@ -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 @@
   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 @@
    */
   if (root != NULL)
     {
-      base_info_ref (info); /* FIXME once boxed types are working */
       gtk_tree_store_set (store, root,
                           MODEL_COLUMN_INFO, info,
                           -1);

Index: dbus-viewer.c
===================================================================
RCS file: /cvs/dbus/dbus/tools/dbus-viewer.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- dbus-viewer.c	30 Jan 2005 07:44:08 -0000	1.6
+++ dbus-viewer.c	30 Jan 2005 23:06:32 -0000	1.7
@@ -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 @@
 }
 
 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 @@
   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 @@
 
   gtk_container_add (GTK_CONTAINER (sw), w->treeview);
 
-  /* Create services option menu */
-
-  
-
   /* Show everything */
   gtk_widget_show_all (w->window);
 
@@ -287,11 +257,11 @@
 }
 
 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 @@
   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 @@
   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 @@
       ++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 @@
 
           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);



More information about the dbus-commit mailing list