[glibmm] DBus: Add initial implementation of a bus server/client example.



commit e541543d26bd18ea9f3364f26c61cf1ce43f487e
Author: José Alburquerque <jaalburqu svn gnome org>
Date:   Mon Jan 17 00:00:11 2011 -0500

    DBus: Add initial implementation of a bus server/client example.
    
    	* examples/Makefile.am:
    	* examples/dbus/busserver.cc: Add a partial implementation of the
    	server part of a server/client example that communicate through the
    	user's bus.
    	* examples/dbus/peer.cc: Typos.

 ChangeLog                  |   10 ++
 examples/Makefile.am       |    3 +
 examples/dbus/busserver.cc |  198 ++++++++++++++++++++++++++++++++++++++++++++
 examples/dbus/peer.cc      |   10 +-
 4 files changed, 216 insertions(+), 5 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 12a131d..16c333d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2011-01-16  José Alburquerque  <jaalburqu svn gnome org>
 
+	DBus: Add initial implementation of a bus server/client example.
+
+	* examples/Makefile.am:
+	* examples/dbus/busserver.cc: Add a partial implementation of the
+	server part of a server/client example that communicate through the
+	user's bus.
+	* examples/dbus/peer.cc: Typos.
+
+2011-01-16  José Alburquerque  <jaalburqu svn gnome org>
+
 	DBusConnection: Add a send_message() without an "out_serial" param.
 
 	* gio/src/dbusconnection.{ccg,hg} (send_message): Add new method
diff --git a/examples/Makefile.am b/examples/Makefile.am
index e65dbfb..7609bbc 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -20,6 +20,7 @@ AUTOMAKE_OPTIONS = subdir-objects
 check_PROGRAMS =			\
 	child_watch/child_watch		\
 	compose/example			\
+	dbus/busserver			\
 	dbus/peer			\
 	dbus/userbus			\
 	iochannel_stream/example	\
@@ -75,6 +76,8 @@ thread_threadpool_SOURCES  = thread/threadpool.cc
 thread_threadpool_LDADD    = $(thread_ldadd)
 
 # giomm examples
+dbus_busserver_SOURCES = dbus/busserver.cc
+dbus_busserver_LDADD   = $(giomm_ldadd)
 dbus_peer_SOURCES = dbus/peer.cc
 dbus_peer_LDADD = $(giomm_ldadd)
 dbus_userbus_SOURCES = dbus/userbus.cc
diff --git a/examples/dbus/busserver.cc b/examples/dbus/busserver.cc
new file mode 100644
index 0000000..3edf2db
--- /dev/null
+++ b/examples/dbus/busserver.cc
@@ -0,0 +1,198 @@
+/* Copyright (C) 2011 The giomm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* This is a basic server providing a clock like functionality.  Clients can
+ * get the current time, set the alarm and get notified when the alarm time is
+ * reached.  It is basic because there is only one global alarm which any
+ * client can set.  Clients listening for the alarm signal will be notified by
+ * use of the global alarm signal.  The server should be easily modifiable to
+ * allow per-client alarms, but that is left as an exercise.
+ *
+ * Along with the above it provides a method to get its stdout's file
+ * descriptor to test the Gio::DBusMessage API.
+ */
+
+#include <giomm.h>
+#include <glibmm.h>
+#include <iostream>
+
+namespace
+{
+
+static Glib::RefPtr<Gio::DBusNodeInfo> introspection_data;
+
+static Glib::ustring introspection_xml =
+  "<node>"
+  "  <interface name='org.glibmm.DBus.Clock'>"
+  "    <method name='GetTime'>"
+  "    <method name='SetAlarm'>"
+  "      <arg type='s' name='iso8601' direction='in'/>"
+  "    </method>"
+  "    <method name='GetStdout'>"
+  "    <signal name='OnAlarm'>"
+  "      <arg type='s' name='iso8601'/>"
+  "    </signal>"
+       // The time of the alarm as an iso8601 string.
+  "    <property type='s' name='Alarm' access='readwrite'/>"
+  "  </interface>"
+  "</node>";
+
+// Stores the current alarm.
+static Glib::TimeVal curr_alarm;
+
+} // anonymous namespace
+
+static void on_method_call(const Glib::RefPtr<Gio::DBusConnection>& connection,
+  const Glib::ustring& /* sender */, const Glib::ustring& /* object_path */,
+  const Glib::ustring& /* interface_name */, const Glib::ustring& method_name,
+  const Glib::VariantBase& /* parameters */,
+  const Glib::RefPtr<Gio::DBusMethodInvocation>& invocation)
+{
+  if(method_name == "GetTime")
+  {
+    Glib::TimeVal curr_time;
+    curr_time.assign_current_time();
+
+    Glib::ustring time_str = curr_time.as_iso8601();
+
+    Glib::Variant<Glib::ustring> time_var =
+      Glib::Variant<Glib::ustring>::create(time_str);
+
+    // Create a variant array to create a tuple to be returned to the client.
+    std::vector<Glib::VariantBase> var_array;
+    var_array.push_back(time_var);
+
+    // Create the tuple.
+    Glib::VariantContainerBase response =
+      Glib::VariantContainerBase::create_tuple(var_array);
+
+    // Return the tuple with the included time.
+    invocation->return_value(response);
+  }
+  else if(method_name == "SetAlarm")
+  {
+    // Get the parameter tuple.
+    Glib::VariantContainerBase parameters;
+    invocation->get_parameters(parameters);
+
+    // Get the variant string.
+    Glib::Variant<Glib::ustring> param;
+    parameters.get(param);
+
+    // Get the time string.
+    Glib::ustring time_str = param.get();
+
+    if(!curr_alarm.assign_from_iso8601(time_str))
+    {
+      // If setting alarm was not successful, return an error.
+      Gio::DBusError error(Gio::DBusError::INVALID_ARGS,
+          "Alarm string is not in ISO8601 format.");
+      invocation->return_gerror(error);
+    }
+  }
+  else if(method_name == "GetStdout")
+  {
+#ifndef G_OS_WIN32
+    if(connection->get_capabilities() &
+      Gio::DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING)
+    {
+      Glib::RefPtr<Gio::UnixFDList> list = Gio::UnixFDList::create();
+      try
+      {
+        list->append(STDOUT_FILENO);
+
+        Glib::RefPtr<Gio::DBusMessage> reply =
+          Gio::DBusMessage::create_method_reply(invocation->get_message());
+
+        reply->set_unix_fd_list(list);
+
+        connection->send_message(reply);
+      }
+      catch(const Glib::Error& ex)
+      {
+        std::cerr << "Error trying to send stdout to client: " << ex.what() <<
+          std::endl;
+        return;
+      }
+    }
+    else
+    {
+      invocation->return_dbus_error("org.glibmm.DBus.Failed", "Your message "
+        "bus daemon does not support file descriptor passing (need D-Bus >= "
+        "1.3.0)");
+    }
+#else
+    invocation->return_dbus_error("org.glibmm.DBus.Failed", "Your message bus "
+      "daemon does not support file descriptor passing (need D-Bus >= 1.3.0)");
+#endif
+  }
+  else
+  {
+    // Non-existent method on the interface.
+    Gio::DBusError error(Gio::DBusError::UNKNOWN_METHOD,
+      "Method does not exist.");
+    invocation->return_gerror(error);
+  }
+}
+
+void on_get_property(Glib::VariantBase& property,
+  const Glib::RefPtr<Gio::DBusConnection>& /* connection */,
+  const Glib::ustring& /* sender */, const Glib::ustring& /* object_path */,
+  const Glib::ustring& /* interface_name */, const Glib::ustring& property_name)
+{
+  if(property_name == "Alarm")
+  {
+    if(curr_alarm.valid())
+    {
+      Glib::ustring alarm_str = curr_alarm.as_iso8601();
+
+      Glib::Variant<Glib::ustring> alarm_var =
+        Glib::Variant<Glib::ustring>::create(alarm_str);
+
+      property = alarm_var;
+    }
+    else
+    {
+      throw Gio::Error(Gio::Error::FAILED, "Alarm has not been set.");
+    }
+  }
+  else
+  {
+    throw Gio::DBusError(Gio::DBusError::FAILED, "Unknown property name.");
+  }
+}
+
+bool on_set_property(const Glib::RefPtr<Gio::DBusConnection>& connection,
+  const Glib::ustring& sender, const Glib::ustring& object_path,
+  const Glib::ustring& interface_name, const Glib::ustring& property_name,
+  const Glib::VariantBase& value)
+{
+  if(property_name == "Alarm")
+  {
+  }
+  else
+  {
+  }
+}
+
+int main(int, char**)
+{
+  std::locale::global(std::locale(""));
+  Gio::init();
+
+  return 0;
+}
diff --git a/examples/dbus/peer.cc b/examples/dbus/peer.cc
index 6bedafc..1a7a1ca 100644
--- a/examples/dbus/peer.cc
+++ b/examples/dbus/peer.cc
@@ -93,7 +93,7 @@ static Glib::RefPtr<Gio::DBusNodeInfo> introspection_data;
 
 static Glib::ustring introspection_xml =
   "<node>"
-  "  <interface name='org.glibmm.GDBus.TestPeerInterface'>"
+  "  <interface name='org.glibmm.DBus.TestPeerInterface'>"
   "    <method name='HelloWorld'>"
   "      <arg type='s' name='greeting' direction='in'/>"
   "      <arg type='s' name='response' direction='out'/>"
@@ -175,8 +175,8 @@ bool on_new_connection(const Glib::RefPtr<Gio::DBusConnection>& connection)
   // connection must be kept so store the connection in a global variable.
   curr_connection = connection;
 
-  guint reg_id = connection->register_object("/org/glibmm/GDBus/TestObject",
-    introspection_data->lookup_interface("org.glibmm.GDBus.TestPeerInterface"),
+  guint reg_id = connection->register_object("/org/glibmm/DBus/TestObject",
+    introspection_data->lookup_interface("org.glibmm.DBus.TestPeerInterface"),
     &interface_vtable);
 
   if(reg_id == 0)
@@ -261,8 +261,8 @@ void run_as_client(Glib::ustring address)
   try
   {
     Glib::VariantContainerBase result;
-    connection->call_sync(result, "/org/glibmm/GDBus/TestObject",
-      "org.glibmm.GDBus.TestPeerInterface",
+    connection->call_sync(result, "/org/glibmm/DBus/TestObject",
+      "org.glibmm.DBus.TestPeerInterface",
       "HelloWorld", parameters);
 
     Glib::Variant<Glib::ustring> child;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]