2004-04-15 Olivier Andrieu <oliv__a@users.sourceforge.net>
authorOlivier Andrieu <oliv__a@users.sourceforge.net>
Thu, 15 Apr 2004 22:08:05 +0000 (22:08 +0000)
committerOlivier Andrieu <oliv__a@users.sourceforge.net>
Thu, 15 Apr 2004 22:08:05 +0000 (22:08 +0000)
* bus/driver.c (bus_driver_handle_get_service_owner):
implement a GetServiceOwner method.
* doc/dbus-specification.xml: document it.
* dbus/dbus-errors.h: add a 'ServiceHasNoOwner' error.

* glib/dbus-gproxy.c (dbus_gproxy_new_for_service_owner):
implement, using the bus GetServiceOwner method.

* test/glib/test-dbus-glib.c:
use dbus_gproxy_new_for_service_owner so that we can receive the
signal.

ChangeLog
bus/driver.c
dbus/dbus-errors.h
doc/.cvsignore
doc/dbus-specification.xml
glib/dbus-gproxy.c
test/glib/test-dbus-glib.c

index e306348..0aacd5c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2004-04-15  Olivier Andrieu  <oliv__a@users.sourceforge.net>
+
+       * bus/driver.c (bus_driver_handle_get_service_owner):
+       implement a GetServiceOwner method.
+       * doc/dbus-specification.xml: document it.
+       * dbus/dbus-errors.h: add a 'ServiceHasNoOwner' error.
+       
+       * glib/dbus-gproxy.c (dbus_gproxy_new_for_service_owner):
+       implement, using the bus GetServiceOwner method.
+
+       * test/glib/test-dbus-glib.c:
+       use dbus_gproxy_new_for_service_owner so that we can receive the
+       signal. 
+
 2004-04-14  Olivier Andrieu  <oliv__a@users.sourceforge.net>
 
        * test/glib/test-dbus-glib.c (timed_exit): fail the test after
index 3ffae2e..a9dddd1 100644 (file)
@@ -756,6 +756,79 @@ bus_driver_handle_remove_match (DBusConnection *connection,
   return FALSE;
 }
 
+static dbus_bool_t
+bus_driver_handle_get_service_owner (DBusConnection *connection,
+                                    BusTransaction *transaction,
+                                    DBusMessage    *message,
+                                    DBusError      *error)
+{
+  char *text;
+  const char *base_name;
+  DBusString str;
+  BusRegistry *registry;
+  BusService *service;
+  DBusMessage *reply;
+  
+  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+  registry = bus_connection_get_registry (connection);
+
+  text = NULL;
+  reply = NULL;
+
+  if (! dbus_message_get_args (message, error,
+                              DBUS_TYPE_STRING, &text,
+                              DBUS_TYPE_INVALID))
+      goto failed;
+
+  _dbus_string_init_const (&str, text);
+  service = bus_registry_lookup (registry, &str);
+  if (service == NULL)
+    {
+      dbus_set_error (error, 
+                     DBUS_ERROR_SERVICE_HAS_NO_OWNER,
+                     "Could not get owner of service '%s': no such service", text);
+      goto failed;
+    }
+
+  base_name = bus_connection_get_name (bus_service_get_primary_owner (service));
+  if (base_name == NULL)
+    {
+      dbus_set_error (error,
+                     DBUS_ERROR_FAILED,
+                     "Could not determine base service for '%s'", text);
+      goto failed;
+    }
+  _dbus_assert (*base_name == ':');
+
+  reply = dbus_message_new_method_return (message);
+  if (reply == NULL)
+    goto oom;
+
+  if (! dbus_message_append_args (reply, 
+                                 DBUS_TYPE_STRING, base_name,
+                                 DBUS_TYPE_INVALID))
+    goto oom;
+  
+  if (! bus_transaction_send_from_driver (transaction, connection, reply))
+    goto oom;
+
+  dbus_message_unref (reply);
+  dbus_free (text);
+
+  return TRUE;
+
+ oom:
+  BUS_SET_OOM (error);
+
+ failed:
+  _DBUS_ASSERT_ERROR_IS_SET (error);
+  if (reply)
+    dbus_message_unref (reply);
+  dbus_free (text);
+  return FALSE;
+}
+
 /* For speed it might be useful to sort this in order of
  * frequency of use (but doesn't matter with only a few items
  * anyhow)
@@ -774,7 +847,8 @@ struct
   { "ServiceExists", bus_driver_handle_service_exists },
   { "ListServices", bus_driver_handle_list_services },
   { "AddMatch", bus_driver_handle_add_match },
-  { "RemoveMatch", bus_driver_handle_remove_match }
+  { "RemoveMatch", bus_driver_handle_remove_match },
+  { "GetServiceOwner", bus_driver_handle_get_service_owner }
 };
 
 dbus_bool_t
index 9d20123..ec8c5d9 100644 (file)
@@ -56,6 +56,7 @@ struct DBusError
 #define DBUS_ERROR_NO_MEMORY                  "org.freedesktop.DBus.Error.NoMemory"
 #define DBUS_ERROR_ACTIVATE_SERVICE_NOT_FOUND "org.freedesktop.DBus.Error.ServiceNotFound"
 #define DBUS_ERROR_SERVICE_DOES_NOT_EXIST     "org.freedesktop.DBus.Error.ServiceDoesNotExist"
+#define DBUS_ERROR_SERVICE_HAS_NO_OWNER       "org.freedesktop.DBus.Error.ServiceHasNoOwner"
 #define DBUS_ERROR_NO_REPLY                   "org.freedesktop.DBus.Error.NoReply"
 #define DBUS_ERROR_IO_ERROR                   "org.freedesktop.DBus.Error.IOError"
 #define DBUS_ERROR_BAD_ADDRESS                "org.freedesktop.DBus.Error.BadAddress"
index eded08f..371668d 100644 (file)
@@ -8,3 +8,4 @@ Makefile.in
 api
 dbus-specification.html
 dbus-test-plan.html
+dbus-tutorial.html
index 94dc740..2f22b77 100644 (file)
 
       </sect3>
 
+      <sect3 id="bus-messages-get-service-owner">
+        <title><literal>org.freedesktop.DBus.GetServiceOwner</literal></title>
+        <para>
+          As a method:
+          <programlisting>
+            STRING GetServiceOwner (in STRING service_name)
+          </programlisting>
+          Message arguments:
+          <informaltable>
+            <tgroup cols="3">
+              <thead>
+                <row>
+                  <entry>Argument</entry>
+                  <entry>Type</entry>
+                  <entry>Description</entry>
+                </row>
+              </thead>
+              <tbody>
+                <row>
+                  <entry>0</entry>
+                  <entry>STRING</entry>
+                  <entry>Name of the service to query</entry>
+                </row>
+              </tbody>
+            </tgroup>
+          </informaltable>
+        Reply arguments:
+        <informaltable>
+          <tgroup cols="3">
+            <thead>
+              <row>
+                <entry>Argument</entry>
+                <entry>Type</entry>
+                <entry>Description</entry>
+              </row>
+            </thead>
+            <tbody>
+              <row>
+                <entry>0</entry>
+                <entry>STRING</entry>
+                <entry>Return value, a base service name</entry>
+              </row>
+            </tbody>
+          </tgroup>
+        </informaltable>
+        Returns the base service name of the primary owner of the
+        service in argument. If the requested service isn't active,
+        returns a
+        <literal>org.freedesktop.DBus.Error.ServiceHasNoOwner</literal> error.
+       </para>
+      </sect3>
+
       <sect3 id="bus-messages-out-of-memory">
         <title><literal>org.freedesktop.DBus.Error.NoMemory</literal></title>
         <para>
index 878c2a2..906fd2e 100644 (file)
@@ -932,12 +932,67 @@ dbus_gproxy_new_for_service_owner (DBusConnection           *connection,
                                    const char               *interface_name,
                                    GError                  **error)
 {
+  DBusGProxy *proxy;
+
+  DBusMessage *request, *reply;
+  DBusError derror;
+  char *base_service_name;
+
   g_return_val_if_fail (connection != NULL, NULL);
   g_return_val_if_fail (service_name != NULL, NULL);
   g_return_val_if_fail (path_name != NULL, NULL);
   g_return_val_if_fail (interface_name != NULL, NULL);
 
+  dbus_error_init (&derror);
+
+  proxy = NULL;
+  base_service_name = NULL;
+  reply = NULL;
+
+  request = dbus_message_new_method_call (DBUS_SERVICE_ORG_FREEDESKTOP_DBUS,
+                                         DBUS_PATH_ORG_FREEDESKTOP_DBUS,
+                                         DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
+                                         "GetServiceOwner");
+  if (request == NULL)
+    g_error ("Out of memory");
+  
+  if (! dbus_message_append_args (request, 
+                                 DBUS_TYPE_STRING, service_name, 
+                                 DBUS_TYPE_INVALID))
+    g_error ("Out of memory");
+
+  reply = dbus_connection_send_with_reply_and_block (connection, request,
+                                                    2000, &derror);
+  if (reply == NULL)
+    goto error;
+
+  if (dbus_set_error_from_message (&derror, reply))
+    goto error;
+
+  if (! dbus_message_get_args (reply, &derror, 
+                              DBUS_TYPE_STRING, &base_service_name, 
+                              DBUS_TYPE_INVALID))
+    goto error;
+      
+
+  proxy = dbus_gproxy_new (connection, base_service_name,
+                           path_name, interface_name);
+
+  goto out;
 
+ error:
+  g_assert (dbus_error_is_set (&derror));
+  dbus_set_g_error (error, &derror);
+  dbus_error_free (&derror);
+
+ out:
+  if (request)
+    dbus_message_unref (request);
+  if (reply)
+    dbus_message_unref (reply);
+  dbus_free (base_service_name);
+
+  return proxy;
 }
 
 /**
index ed94afa..ad08164 100644 (file)
@@ -172,11 +172,20 @@ main (int argc, char **argv)
 
   /* Talk to the new service */
   
-  proxy = dbus_gproxy_new_for_service (connection,
-                                       "org.freedesktop.DBus.TestSuiteEchoService",
-                                       "/org/freedesktop/TestSuite",
-                                       "org.freedesktop.TestSuite");
+  proxy = dbus_gproxy_new_for_service_owner (connection,
+                                            "org.freedesktop.DBus.TestSuiteEchoService",
+                                            "/org/freedesktop/TestSuite",
+                                            "org.freedesktop.TestSuite",
+                                            &error);
   
+  if (proxy == NULL)
+    {
+      g_printerr ("Failed to create proxy for service owner: %s\n",
+                  error->message);
+      g_error_free (error);
+      exit (1);      
+    }
+
   call = dbus_gproxy_begin_call (proxy, "Echo",
                                  DBUS_TYPE_STRING,
                                  "my string hello",