From: joakim@verona.se
To: Daiki Ueno <ueno@gnu.org>
Cc: martin rudalics <rudalics@gmx.at>, emacs-devel@gnu.org
Subject: Re: on-the-fly D-Bus proxy creation
Date: Tue, 24 Feb 2015 16:13:49 +0100 [thread overview]
Message-ID: <m361arz6j6.fsf@exodia.verona.se> (raw)
In-Reply-To: <m3pp8zivjl.fsf-ueno@gnu.org> (Daiki Ueno's message of "Tue, 24 Feb 2015 17:05:34 +0900")
Daiki Ueno <ueno@gnu.org> 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
next prev parent reply other threads:[~2015-02-24 15:13 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-02-24 8:05 on-the-fly D-Bus proxy creation Daiki Ueno
2015-02-24 8:52 ` Michael Albinus
2015-02-24 9:21 ` Daiki Ueno
2015-02-24 9:47 ` Michael Albinus
2015-02-24 11:02 ` Daiki Ueno
2015-02-24 15:13 ` joakim [this message]
2015-02-25 8:23 ` [PATCH] Support automatic D-Bus proxy generation Daiki Ueno
2015-02-25 17:18 ` joakim
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m361arz6j6.fsf@exodia.verona.se \
--to=joakim@verona.se \
--cc=emacs-devel@gnu.org \
--cc=rudalics@gmx.at \
--cc=ueno@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).