3 * Library for simple D-Bus integration with GLib
5 * Copyright (C) 2009 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 #include <sys/signal.h>
32 #include "gdbus-cxx-bridge.h"
36 #include <boost/noncopyable.hpp>
43 std::map<std::string, std::string> c;
46 static void hello_global() {}
49 typedef boost::shared_ptr< Result1<const std::string&> > string_result;
50 struct async : private boost::noncopyable
52 async(const boost::shared_ptr<Watch> &watch, Watch *watch2, const string_result &result):
62 boost::shared_ptr<Watch> m_watch;
64 string_result m_result;
68 static gboolean method_idle(gpointer data)
70 std::auto_ptr<async> mydata(static_cast<async *>(data));
71 std::cout << "replying to method_async" << std::endl;
72 mydata->m_result->done("Hello World, asynchronous and delayed");
76 static void disconnect(const std::string &id, const std::string &peer)
78 std::cout << id << ": " << peer << " has disconnected." << std::endl;
83 static void hello_static() {}
84 void hello_const() const {}
85 static void hello_world(const char *msg) { puts(msg); }
88 void method(std::string &text)
93 void method_async(const Caller_t &caller,
94 const boost::shared_ptr<Watch> &watch,
96 const string_result &r)
98 watch->setCallback(boost::bind(disconnect, "watch1", caller));
99 Watch *watch2 = r->createWatch(boost::bind(disconnect, "watch2", caller));
100 std::cout << "method_async called by " << caller << " delay " << secs << std::endl;
101 g_timeout_add_seconds(secs, method_idle, new async(watch, watch2, r));
104 void method2(int32_t arg, int32_t &ret)
109 int32_t method3(int32_t arg)
114 void method8_simple(int32_t a1, int32_t a2, int32_t a3, int32_t a4, int32_t a5,
115 int32_t a6, int32_t a7, int32_t a8)
119 void method9_async(Result9<int32_t, int32_t, int32_t, int32_t, int32_t,
120 int32_t, int32_t, int32_t, int32_t> *r)
122 r->done(1, 2, 3, 4, 5, 6, 7, 8, 9);
126 int32_t method9(int32_t a1, int32_t a2, int32_t a3, int32_t a4, int32_t a5,
127 int32_t a6, int32_t a7, int32_t a8, int32_t a9)
133 void hash(const std::map<int8_t, int32_t> &in, std::map<int16_t, int32_t> &out)
135 for (std::map<int8_t, int32_t>::const_iterator it = in.begin();
138 out.insert(std::make_pair((int16_t)it->first, it->second * it->second));
142 void array(const std::vector<int32_t> &in, std::vector<int32_t> &out)
144 for (std::vector<int32_t>::const_iterator it = in.begin();
147 out.push_back(*it * *it);
153 throw dbus_error("org.example.error.Invalid", "error");
156 void argtest(const args &in, args &out)
169 template<> struct dbus_traits<args> :
170 public dbus_struct_traits<args, dbus_member<args, int, &args::a,
171 dbus_member<args, std::string, &args::b,
172 dbus_member_single<args, std::map<std::string, std::string>, &args::c> > > >
175 class DBusTest : public Test, private Test2
177 DBusObjectHelper m_object;
178 DBusObjectHelper m_secondary;
181 DBusTest(const DBusConnectionPtr &conn) :
182 m_object(conn, "/test", "org.example.Test"),
184 m_secondary(conn, m_object.getPath(), "org.example.Secondary"),
185 signal(m_object, "Signal")
187 m_object.add(this, &Test::method8_simple, "Method8Simple");
188 // m_object.add(this, &Test::method10_async, "Method10Async", G_DBUS_METHOD_FLAG_ASYNC);
189 // m_object.add(this, &Test::method9, "Method9");
190 m_object.add(this, &Test::method2, "Method2");
191 m_object.add(this, &Test::method3, "Method3");
192 m_object.add(this, &Test::method, "Test");
193 m_object.add(this, &Test::method_async, "TestAsync");
194 m_object.add(this, &Test::argtest, "ArgTest");
195 m_object.add(this, &Test::hash, "Hash");
196 m_object.add(this, &Test::array, "Array");
197 m_object.add(this, &Test::error, "Error");
198 m_object.add(&hello_global, "Global");
199 m_object.add(&DBusTest::hello_static, "Static");
200 m_object.add(static_cast<Test2 *>(this), &Test2::test2, "Private");
201 // The hello_const() method cannot be registered
202 // because there is no matching MakeMethodEntry<>
203 // specialization for it or DBusObjectHelper::add()
204 // fails to determine the right function type,
205 // depending how one wants to interpret the problem.
206 // m_object.add2(this, &DBusTest::hello_const, "Const");
208 m_object.add(signal);
210 m_secondary.add(this, &DBusTest::hello, "Hello");
217 EmitSignal3<int32_t, const std::string &, const std::map<int32_t, int32_t> &>signal;
220 static void hello_static() {}
221 void hello_const() const {}
225 m_secondary.activate();
231 m_object.deactivate();
232 m_secondary.deactivate();
236 static GMainLoop *main_loop = NULL;
238 static void sig_term(int sig)
240 g_main_loop_quit(main_loop);
243 } // namespace GDBusCXX
245 using namespace GDBusCXX;
247 int main(int argc, char *argv[])
249 DBusConnectionPtr conn;
253 memset(&sa, 0, sizeof(sa));
254 sa.sa_handler = sig_term;
255 sigaction(SIGINT, &sa, NULL);
256 sigaction(SIGTERM, &sa, NULL);
258 sa.sa_handler = SIG_IGN;
259 sigaction(SIGCHLD, &sa, NULL);
260 sigaction(SIGPIPE, &sa, NULL);
262 main_loop = g_main_loop_new(NULL, FALSE);
264 conn = dbus_get_bus_connection("SESSION", "org.example", false, &err);
266 std::string message = err.getMessage();
267 if (!message.empty()) {
268 fprintf(stderr, "%s\n", message.c_str());
270 fprintf(stderr, "Can't register with session bus\n");
274 std::auto_ptr<DBusTest> test(new DBusTest(conn));
276 test->signal(42, "hello world", std::map<int32_t, int32_t>());
279 test->signal(123, "here I am again", std::map<int32_t, int32_t>());
281 g_main_loop_run(main_loop);
285 // is this really necessary?
286 // if(!g_dbus_connection_close_sync(conn, NULL, NULL)) {
287 // fprintf(stderr, "Problem closing connection.\n");
290 g_main_loop_unref(main_loop);