unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* on-the-fly D-Bus proxy creation
@ 2015-02-24  8:05 Daiki Ueno
  2015-02-24  8:52 ` Michael Albinus
  2015-02-24 15:13 ` joakim
  0 siblings, 2 replies; 8+ messages in thread
From: Daiki Ueno @ 2015-02-24  8:05 UTC (permalink / raw)
  To: emacs-devel; +Cc: martin rudalics

[-- Attachment #1: Type: text/plain, Size: 1580 bytes --]

Hello,

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>';

  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

[-- Attachment #2: dbusproxy.el --]
[-- Type: text/plain, Size: 2253 bytes --]

(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"))

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2015-02-25 17:18 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
2015-02-25  8:23   ` [PATCH] Support automatic D-Bus proxy generation Daiki Ueno
2015-02-25 17:18     ` joakim

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