unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
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



  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).