// -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 2 -*- /* Copyright (C) 2010 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. */ #include #include #include #include #include #include _DEFS(giomm,gio) _PINCLUDE(glibmm/private/object_p.h) namespace Gio { namespace DBus { //The GMMPROC_EXTRA_NAMESPACE() macro is a hint to generate_wrap_init.pl to put it in the DBus sub-namespace _GMMPROC_EXTRA_NAMESPACE(DBus) _WRAP_ENUM(ProxyFlags, GDBusProxyFlags, s#^DBUS_##, NO_GTYPE) /** A client-side proxy. * This is a base class used for proxies to access a D-Bus interface on * a remote object. It can be constructed for both well-known and * unique names. * * By default, Proxy will cache all properties (and listen to changes) of * the remote object, and proxy all signals that gets emitted. This behaviour * can be changed by passing suitable ProxyFlags when the proxy is * created. If the proxy is for a well-known name, the property cache is * flushed when the name owner vanishes and reloaded when a name owner * appears. * * If a Proxy is used for a well-known name, the owner of the name is * tracked and can be read from property_g_name_owner(). * * The generic signal_g_properties_changed() and signal_g_signal() signals are * not very convenient to work with. Therefore, the recommended way of working * with proxies is to subclass Proxy, and have more natural properties and * signals in your derived class. * * This documentation was adapted from the C API documentation. The C API docs * has more information and an example. * * @newin{2,28} * @ingroup DBus */ class Proxy : public Glib::Object, public Initable, public AsyncInitable { _CLASS_GOBJECT(Proxy, GDBusProxy, G_DBUS_PROXY, Glib::Object, GObject) _IMPLEMENTS_INTERFACE(Initable) _IMPLEMENTS_INTERFACE(AsyncInitable) protected: Proxy(const Glib::RefPtr& connection, const Glib::ustring& name, const Glib::ustring& object_path, const Glib::ustring& interface_name, const SlotAsyncReady& slot, const Glib::RefPtr& cancellable, const Glib::RefPtr& info = Glib::RefPtr(), ProxyFlags flags = PROXY_FLAGS_NONE); Proxy(const Glib::RefPtr& connection, const Glib::ustring& name, const Glib::ustring& object_path, const Glib::ustring& interface_name, const SlotAsyncReady& slot, const Glib::RefPtr& info = Glib::RefPtr(), ProxyFlags flags = PROXY_FLAGS_NONE); Proxy(const Glib::RefPtr& connection, const Glib::ustring& name, const Glib::ustring& object_path, const Glib::ustring& interface_name, const Glib::RefPtr& cancellable, const Glib::RefPtr& info = Glib::RefPtr(), ProxyFlags flags = PROXY_FLAGS_NONE); Proxy(const Glib::RefPtr& connection, const Glib::ustring& name, const Glib::ustring& object_path, const Glib::ustring& interface_name, const Glib::RefPtr& info = Glib::RefPtr(), ProxyFlags flags = PROXY_FLAGS_NONE); Proxy(BusType bus_type, const Glib::ustring& name, const Glib::ustring& object_path, const Glib::ustring& interface_name, const SlotAsyncReady& slot, const Glib::RefPtr& cancellable, const Glib::RefPtr& info = Glib::RefPtr(), ProxyFlags flags = PROXY_FLAGS_NONE); Proxy(BusType bus_type, const Glib::ustring& name, const Glib::ustring& object_path, const Glib::ustring& interface_name, const SlotAsyncReady& slot, const Glib::RefPtr& info = Glib::RefPtr(), ProxyFlags flags = PROXY_FLAGS_NONE); Proxy(BusType bus_type, const Glib::ustring& name, const Glib::ustring& object_path, const Glib::ustring& interface_name, const Glib::RefPtr& cancellable, const Glib::RefPtr& info = Glib::RefPtr(), ProxyFlags flags = PROXY_FLAGS_NONE); Proxy(BusType bus_type, const Glib::ustring& name, const Glib::ustring& object_path, const Glib::ustring& interface_name, const Glib::RefPtr& info = Glib::RefPtr(), ProxyFlags flags = PROXY_FLAGS_NONE); public: _WRAP_METHOD_DOCS_ONLY(g_dbus_proxy_new) static void create(const Glib::RefPtr& connection, const Glib::ustring& name, const Glib::ustring& object_path, const Glib::ustring& interface_name, const SlotAsyncReady& slot, const Glib::RefPtr& cancellable, const Glib::RefPtr& info = Glib::RefPtr(), ProxyFlags flags = PROXY_FLAGS_NONE); /// Non-cancellable version of create(). static void create(const Glib::RefPtr& connection, const Glib::ustring& name, const Glib::ustring& object_path, const Glib::ustring& interface_name, const SlotAsyncReady& slot, const Glib::RefPtr& info = Glib::RefPtr(), ProxyFlags flags = PROXY_FLAGS_NONE); _WRAP_METHOD_DOCS_ONLY(g_dbus_proxy_new_finish) /// @throw Glib::Error. _WRAP_METHOD(static Glib::RefPtr create_finish(const Glib::RefPtr& result), g_dbus_proxy_new_finish, errthrow) _WRAP_METHOD_DOCS_ONLY(g_dbus_proxy_new_sync) static Glib::RefPtr create_sync(const Glib::RefPtr& connection, const Glib::ustring& name, const Glib::ustring& object_path, const Glib::ustring& interface_name, const Glib::RefPtr& cancellable, const Glib::RefPtr& info = Glib::RefPtr(), ProxyFlags flags = PROXY_FLAGS_NONE); /// Non-cancellable version of create_sync(). static Glib::RefPtr create_sync(const Glib::RefPtr& connection, const Glib::ustring& name, const Glib::ustring& object_path, const Glib::ustring& interface_name, const Glib::RefPtr& info = Glib::RefPtr(), ProxyFlags flags = PROXY_FLAGS_NONE); _WRAP_METHOD_DOCS_ONLY(g_dbus_proxy_new_for_bus) static void create_for_bus(BusType bus_type, const Glib::ustring& name, const Glib::ustring& object_path, const Glib::ustring& interface_name, const SlotAsyncReady& slot, const Glib::RefPtr& cancellable, const Glib::RefPtr& info = Glib::RefPtr(), ProxyFlags flags = PROXY_FLAGS_NONE); /// Non-cancellable version of create_for_bus(). static void create_for_bus(BusType bus_type, const Glib::ustring& name, const Glib::ustring& object_path, const Glib::ustring& interface_name, const SlotAsyncReady& slot, const Glib::RefPtr& info = Glib::RefPtr(), ProxyFlags flags = PROXY_FLAGS_NONE); _WRAP_METHOD_DOCS_ONLY(g_dbus_proxy_new_for_bus_finish) /// @throw Glib::Error. _WRAP_METHOD(static Glib::RefPtr create_for_bus_finish(const Glib::RefPtr& result), g_dbus_proxy_new_for_bus_finish, errthrow) _WRAP_METHOD_DOCS_ONLY(g_dbus_proxy_new_for_bus_sync) static Glib::RefPtr create_for_bus_sync(BusType bus_type, const Glib::ustring& name, const Glib::ustring& object_path, const Glib::ustring& interface_name, const Glib::RefPtr& cancellable, const Glib::RefPtr& info = Glib::RefPtr(), ProxyFlags flags = PROXY_FLAGS_NONE); /// Non-cancellable version of create_for_bus_sync(). static Glib::RefPtr create_for_bus_sync(BusType bus_type, const Glib::ustring& name, const Glib::ustring& object_path, const Glib::ustring& interface_name, const Glib::RefPtr& info = Glib::RefPtr(), ProxyFlags flags = PROXY_FLAGS_NONE); _WRAP_METHOD(ProxyFlags get_flags() const, g_dbus_proxy_get_flags) _WRAP_METHOD(Glib::RefPtr get_connection(), g_dbus_proxy_get_connection) _WRAP_METHOD(Glib::RefPtr get_connection() const, g_dbus_proxy_get_connection) _WRAP_METHOD(Glib::ustring get_name() const, g_dbus_proxy_get_name) _WRAP_METHOD(Glib::ustring get_name_owner() const, g_dbus_proxy_get_name_owner) _WRAP_METHOD(Glib::ustring get_object_path() const, g_dbus_proxy_get_object_path) _WRAP_METHOD(Glib::ustring get_interface_name() const, g_dbus_proxy_get_interface_name) _WRAP_METHOD(int get_default_timeout() const, g_dbus_proxy_get_default_timeout) _WRAP_METHOD(void set_default_timeout(int timeout_msec = -1), g_dbus_proxy_set_default_timeout) /** Looks up the value for a property from the cache. This call does no * blocking IO. * * If proxy has an expected interface (see property_g_interface_info()), * then @a property_name (for existence) is checked against it. * * @param property An output parameter in which to hold to the variant * instance that holds the value for @a property_name. * @param property_name Property name. * * @newin{2,28} */ void get_cached_property(Glib::VariantBase& property, const Glib::ustring& property_name) const; _IGNORE(g_dbus_proxy_get_cached_property) _WRAP_METHOD(void set_cached_property(const Glib::ustring& property_name, const Glib::VariantBase& value), g_dbus_proxy_set_cached_property) #m4 _CONVERSION(`gchar**', `Glib::StringArrayHandle', `Glib::StringArrayHandle($3)') _WRAP_METHOD(Glib::StringArrayHandle get_cached_property_names() const, g_dbus_proxy_get_cached_property_names) _WRAP_METHOD(void set_interface_info(const Glib::RefPtr& info), g_dbus_proxy_set_interface_info) _WRAP_METHOD(Glib::RefPtr get_interface_info(), g_dbus_proxy_get_interface_info) _WRAP_METHOD(Glib::RefPtr get_interface_info() const, g_dbus_proxy_get_interface_info, constversion) _WRAP_METHOD_DOCS_ONLY(g_dbus_proxy_call) void call( const Glib::ustring& method_name, const SlotAsyncReady& slot, const Glib::RefPtr& cancellable, const Glib::VariantContainerBase& parameters = Glib::VariantContainerBase(), int timeout_msec = -1, CallFlags flags = Gio::DBus::CALL_FLAGS_NONE ); /// A non-cancellable version of call(). void call( const Glib::ustring& method_name, const SlotAsyncReady& slot, const Glib::VariantContainerBase& parameters = Glib::VariantContainerBase(), int timeout_msec = -1, CallFlags flags = Gio::DBus::CALL_FLAGS_NONE ); /** Finishes an operation started with call(). * * @param res An AsyncResult obtained from the SlotAsyncReady passed to * call(). * @result A Variant tuple with return values. * * @throw Glib::Error. */ _WRAP_METHOD(Glib::VariantContainerBase call_finish(const Glib::RefPtr& res), g_dbus_proxy_call_finish, errthrow) //TODO: Use _WRAP_METHOD() for this? /** Synchronously invokes the method_name method on proxy. * See call(), the asynchronous version of this method for more information. * * @param method_name Name of method to invoke. * @param timeout_msec The timeout in milliseconds or -1 to use the proxy * default timeout. * @param flags Flags from the CallFlags enumeration. * @param parameters A Glib::VariantContainerBase tuple with parameters for the * signal. * @param cancellable A Cancellable. * @result A Variant tuple with return values. * * @throw Glib::Error. */ Glib::VariantContainerBase call_sync( const Glib::ustring& method_name, const Glib::RefPtr& cancellable, const Glib::VariantContainerBase& parameters = Glib::VariantContainerBase(), int timeout_msec = -1, CallFlags flags = Gio::DBus::CALL_FLAGS_NONE ); _IGNORE(g_dbus_proxy_call_sync) /// A non-cancellable version of call_sync(). Glib::VariantContainerBase call_sync( const Glib::ustring& method_name, const Glib::VariantContainerBase& parameters = Glib::VariantContainerBase(), int timeout_msec = -1, CallFlags flags = Gio::DBus::CALL_FLAGS_NONE ); #ifdef G_OS_LINUX //TODO: Use _WRAP_METHOD() for this? /** Like call() but also takes a GUnixFDList object. * This method is only available on UNIX. * * This is an asynchronous method. When the operation is finished, callback * will be invoked in the thread-default main loop of the thread you are * calling this method from. You can then call call_with_unix_fd_finish() to * get the result of the operation. See call_sync() for the synchronous * version of this function. * * @param method_name The name of the method to invoke. * @param parameters A Glib::VariantContainerBase tuple with parameters for the * method or 0 if not passing parameters. * @param slot A SlotAsyncReady to call when the request is satisfied. * @param cancellable A Cancellable. * @param fd_list A UnixFDList. * @param timeout_msec The timeout in milliseconds, -1 to use the default * timeout or G_MAXINT for no timeout. * @param flags Flags from the Gio::DBus::CallFlags enumeration. * @newin{2,34} */ void call( const Glib::ustring& method_name, const Glib::VariantContainerBase& parameters, const SlotAsyncReady& slot, const Glib::RefPtr& cancellable, const Glib::RefPtr& fd_list, int timeout_msec = -1, CallFlags flags = Gio::DBus::CALL_FLAGS_NONE); _IGNORE(g_dbus_proxy_call_with_unix_fd_list) /** A non-cancellable version of call() (with a UnixFDList). * @newin{2,34} */ void call( const Glib::ustring& object_path, const Glib::ustring& interface_name, const Glib::ustring& method_name, const Glib::VariantContainerBase& parameters, const SlotAsyncReady& slot, const Glib::RefPtr& fd_list, const Glib::ustring& bus_name = Glib::ustring(), int timeout_msec = -1, CallFlags flags = Gio::DBus::CALL_FLAGS_NONE, const Glib::VariantType& reply_type = Glib::VariantType()); #endif // G_OS_LINUX /** Finishes an operation started with call() (with a UnixFDList). * @param res A AsyncResult obtained from the SlotAsyncReady passed to * call(). * @result A Variant tuple with return values. * @throw Glib::Error. * @newin{2,34} */ _WRAP_METHOD(Glib::VariantContainerBase call_finish(const Glib::RefPtr& res{.}, Glib::RefPtr& out_fd_list{.>>}), g_dbus_proxy_call_with_unix_fd_list_finish, errthrow, ifdef G_OS_LINUX) _WRAP_METHOD( Glib::VariantContainerBase call_sync( const Glib::ustring& method_name{.}, const Glib::VariantContainerBase& parameters{.}, const Glib::RefPtr& cancellable{.?}, const Glib::RefPtr& fd_list{.}, Glib::RefPtr& out_fd_list{.>>}, int timeout_msec{.} = -1, CallFlags flags{.} = Gio::DBus::CALL_FLAGS_NONE ), g_dbus_proxy_call_with_unix_fd_list_sync, errthrow, ifdef G_OS_LINUX ) //_WRAP_PROPERTY("g-bus-type", BusType) // write-only construct-only _WRAP_PROPERTY("g-connection", Glib::RefPtr) _WRAP_PROPERTY("g-default-timeout", int) _WRAP_PROPERTY("g-flags", ProxyFlags) _WRAP_PROPERTY("g-interface-info", Glib::RefPtr) _WRAP_PROPERTY("g-interface-name", Glib::ustring) _WRAP_PROPERTY("g-name", Glib::ustring) _WRAP_PROPERTY("g-name-owner", Glib::ustring) _WRAP_PROPERTY("g-object-path", Glib::ustring) typedef std::map MapChangedProperties; // TODO: Should the signal names match the C API names (ie. the C API names // are g_signal_name while these are just signal_name). // The DBus API ensures that the variant changed_properties is of type "DICT" #m4 _CONVERSION(`GVariant*', `const MapChangedProperties&', `Glib::Variant($3, true).get()') #m4 _CONVERSION(`const MapChangedProperties&', `GVariant*', `const_cast(Glib::Variant::create($3).gobj())') #m4 _CONVERSION(`const std::vector&', `const gchar*const*',`Glib::ArrayHandler::vector_to_array($3).data()') #m4 _CONVERSION(`const gchar*const*', `const std::vector&', `Glib::ArrayHandler::array_to_vector($3, Glib::OWNERSHIP_NONE)') _WRAP_SIGNAL(void properties_changed(const MapChangedProperties& changed_properties, const std::vector& invalidated_properties), "g-properties-changed") #m4 _CONVERSION(`GVariant*', `const Glib::VariantContainerBase&', `Glib::VariantContainerBase($3, true)') #m4 _CONVERSION(`const Glib::VariantContainerBase&', `GVariant*', `const_cast(($3).gobj())') _WRAP_SIGNAL(void signal(const Glib::ustring& sender_name, const Glib::ustring& signal_name, const Glib::VariantContainerBase& parameters), "g-signal") }; } //namespace } // namespace Gio