[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: on-the-fly D-Bus proxy creation
From: |
joakim |
Subject: |
Re: on-the-fly D-Bus proxy creation |
Date: |
Tue, 24 Feb 2015 16:13:49 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/25.0.50 (gnu/linux) |
Daiki Ueno <address@hidden> writes:
> Hello,
Hello Daiki,
>
> There are several programming languages with support for D-Bus client
> implementation. For example, with the following code:
> https://git.gnome.org/browse/gnome-shell/tree/js/ui/keyboard.js#n56
>
> const CaribouDaemonIface = '<node> \
> <interface name="org.gnome.Caribou.Daemon"> \
> <method name="Run" /> \
> <method name="Quit" /> \
> </interface> \
> </node>';
I use Jan Moringens dbus-proxy in my Inkmacs project, which is an Emacs
interface for Inkscape.
It would be nice if there were comparable functionality directly in
Emacs or ELPA.
>
> const CaribouDaemonProxy =
> Gio.DBusProxy.makeProxyWrapper(CaribouDaemonIface);
>
> One can call a D-Bus method as a normal method of CaribouDaemonProxy.
> This is really handy and I wished to have similar feature in Elisp
> (though I haven't ever written any practical D-Bus code in Elisp).
>
> Thanks to cl-generic, I gave it a try. With the attached code (far from
> complete though), a client can be implemented as:
>
> (dbus-define-proxy search-provider "\
> <node>
> <interface name=\"org.gnome.Shell.SearchProvider2\">
> <method name=\"GetInitialResultSet\">
> <arg type=\"as\" name=\"terms\" direction=\"in\" />
> <arg type=\"as\" name=\"results\" direction=\"out\" />
> </method>
> <!-- actually, there are more methods in this interface -->
> </interface>
> </node>")
>
> Then you can create a client and call D-Bus methods:
>
> (setq search-provider
> (search-provider-make :session
> "org.gnome.Weather.BackgroundService"
> "/org/gnome/Weather/BackgroundService"))
> (search-provider-call-GetInitialResultSet search-provider '("tokyo"))
>
> If this seems to be useful, I can finish it off as a patch.
>
> Thanks,
> --
> Daiki Ueno
>
> (require 'dbus)
>
> (eval-when-compile (require 'cl-lib))
> (eval-when-compile (require 'xml))
>
> (cl-defstruct dbus-proxy
> (bus :read-only t)
> (service :read-only t)
> (path :read-only t))
>
> (defmacro dbus-define-proxy (name xml)
> (let* ((node (car (with-temp-buffer
> (insert xml)
> (xml-parse-region (point-min) (point-max)))))
> (interface (car (xml-get-children node 'interface)))
> (methods (xml-get-children interface 'method))
> (interface-name (xml-get-attribute-or-nil interface 'name)))
> `(progn
> (cl-defstruct (,name (:include dbus-proxy)
> (:constructor nil)
> (:constructor ,(intern (format "%s-make" name))
> (bus service path)))
> ;; FIXME: slots for cached properties?
> )
> ,@(mapcar
> (lambda (method)
> (let ((method-name (xml-get-attribute-or-nil method 'name))
> ;; FIXME: parse argument types?
> (in-args
> (mapcar #'intern
> (delq nil
> (mapcar
> (lambda (arg)
> (let ((direction (xml-get-attribute-or-nil
> arg 'direction)))
> (if (or (null direction)
> (not (equal direction "out")))
> (xml-get-attribute-or-nil
> arg 'name))))
> (xml-get-children method 'arg))))))
> ;; FIXME: un-CamelCasify method-name?
> `(cl-defmethod ,(intern (format "%s-call-%s" name method-name))
> ((proxy ,name) ,@in-args &rest args)
> (apply #'dbus-call-method
> (dbus-proxy-bus proxy)
> (dbus-proxy-service proxy)
> (dbus-proxy-path proxy)
> ,interface-name
> ,method-name
> ,@in-args
> args))))
> methods)
> ;; FIXME: asynchronous method calls, signals?
> )))
>
> (dbus-define-proxy search-provider "\
> <node>
> <interface name=\"org.gnome.Shell.SearchProvider2\">
> <method name=\"GetInitialResultSet\">
> <arg type=\"as\" name=\"terms\" direction=\"in\" />
> <arg type=\"as\" name=\"results\" direction=\"out\" />
> </method>
> <!-- actually, there are more methods in this interface -->
> </interface>
> </node>")
>
> ;; (setq search-provider
> ;; (search-provider-make :session
> ;; "org.gnome.Weather.BackgroundService"
> ;; "/org/gnome/Weather/BackgroundService"))
> ;; (search-provider-call-GetInitialResultSet search-provider '("tokyo"))
>
--
Joakim Verona