unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: joakim@verona.se
To: Emacs developers <emacs-devel@gnu.org>
Subject: how to wait for a process to be alive?
Date: Fri, 22 Oct 2010 11:19:21 +0200	[thread overview]
Message-ID: <m3ocam4mau.fsf@verona.se> (raw)

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

I'm working on a mode to integrate Inkscape and Emacs. So far its only
rudimentary.

I want to start Inkscape from Emacs, with code looking like this:

,----
| 
| (defun inkscape-start ()
|  (interactive)
|  (if (not (dbus-ping :session   "org.inkscape" 100))
|      (let*
|          ((ping-count 0)
|           (inkproc (start-process "inkscape" "*inkscape*" inkscape-path )))
|        (while (not(inkscape-alive))
|          (setq ping-count (+ 1 ping-count))
|          (message "pinging inkscape %d" ping-count)
|          (inkscape-sleep-for)
|          )
|        (message "registering dbus proxies")
|        (setq inkscape-application (inkscape-app-dbus-proxy-create))
|        (setq inkscape-desktop (inkscape-document-dbus-proxy-create inkscape-desktop-name))
|        (message "registering inkscape verb proxies")
|        (inkscape-make-verb-list)
|        (message "emacs-inkscape bridge ready for action!")
|        )
|    (message "inkscape already started and responding to ping")))
| 
| (defun inkscape-sleep-for ()
|   (sleep-for 10);;this call doesnt seem to wait at all.
|   (read-string "sleep-for, just press enter");; so do this as a workaround
|   ;;if the sleep-for doesnt work, we get a busy loop and we DOS dbus, and all manner of bad things happen
|   ;;TODO therefore ive factored out the sleep-for until a proper resolution is found
| )
`----

Inkscape starts asynchronously, so I need to poll it, and after its
properly living, do a number of calls.

The problem is that sleep-for doesnt sleep at all, it just
returns. Therefore I have a read-string workaround in the code above.

I suppose the sleep-for is interupted by some kind of event, but I cant
figure out which, or how to do this properly. The best would be for
Inkscape to send Emacs some kind of event rather than Emacs polling
Inkscape, but I'm not sure how to do that either.

I include all of inkscape.el below for reference.

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

;; inkscape.el -- experimental emacs/inkscape bridge
;; (c) fsf 2010
;; author:joakim verona
;; license:gpl

(require 'dbus)
(require 'dbus-introspection)

(require 'dbus-proxy) ;;TODO work around deftest problem

;;Experimental integration between inkscape and emacs using dbus.

;;Currently needs bleeding edge versions of a number of components.
;; - trunk version of inkscape with dbus enabled (see inkscape dbus bugs)
;; - trunk version of Eieio(needs a change which hasnt been merged downstream)
;; - trunk version of Jan Moringen dbus-proxy 
;; - emacs 23(i use emacs from trunk, but 23 should be ok)

;;If you accept that all this really is bleeding edge for real, and
;;not something i just say, controling inkscape from emacs is rather
;;fun!

;; the long term goal is to make an emacs that does things quickly
;;  that currently inhibits creative flow with inkscape. In
;;  particular I want to make a framework that supports specialized
;;  workflows, such as producing sketches for blog entries and web comics.
;; so, when inspiration hits you: m-x inkscape-blog-sketch, 
;;rather than fiddling about in menus etc until you loose inspiration.

;, for this we want to:
;; - make the xwidget emacs branch usable, so inkscape can be embedded in emacs
;; - make inkscape support xembed, so it can be embedded in emacs
;; - make an inkscape mode that shows just the canvas
;; - make an emacs inkscape control mode that implements a proper emacs ui on top of inkscape
;; - somehow implement the emacs buffer model with inkscape
;; - implement a form of OLE:
;;  - display svg images inline muse-mode org org mode for example(this is already mostly possible)
;;  - edit the svg inside inkscape when desired

;; very important is to support text editing in emacs. nodes in an outline-mode
;; document should preferably be bound to nodes in the inkscape document.


;;check alive
;;(dbus-ping :session   "org.inkscape" 100)

;;(dbus-introspect-xml :session   "org.inkscape" "/")

;;(dbus-introspect-get-all-nodes :session   "org.inkscape" "/")

;;(dbus-introspect-get-interface :session   "org.inkscape" "/org/inkscape/application" "org.inkscape.application")
;;(dbus-introspect-get-method-names :session   "org.inkscape" "/org/inkscape/application" "org.inkscape.application")
;;(dbus-introspect-get-method-names  :session "org.inkscape"  "/org/inkscape/desktop_24" "org.inkscape.document")
;; (dbus-introspect-get-method  :session "org.inkscape"  "/org/inkscape/desktop_24" "org.inkscape.document" "rectangle")
(defcustom inkscape-path
  "/home/joakim/build_myprojs/inkscape/inkscape/src/inkscape"
  "path to dbus-enabled inkscape")

(defvar inkscape-desktop-name "desktop_0"
  "this is currently hardcoded, since the inkscape dbus api isnt feature complete yet")

(defvar inkscape-desktop nil)
(defvar inkscape-application nil)

(defun inkscape-alive ()
  (dbus-ping :session   "org.inkscape" 100))



(defun inkscape-start ()
 (interactive)
 (if (not (dbus-ping :session   "org.inkscape" 100))
     (let*
         ((ping-count 0)
          (inkproc (start-process "inkscape" "*inkscape*" inkscape-path )))
       (while (not(inkscape-alive))
         (setq ping-count (+ 1 ping-count))
         (message "pinging inkscape %d" ping-count)
         (inkscape-sleep-for)
         )
       (message "registering dbus proxies")
       (setq inkscape-application (inkscape-app-dbus-proxy-create))
       (setq inkscape-desktop (inkscape-document-dbus-proxy-create inkscape-desktop-name))
       (message "registering inkscape verb proxies")
       (inkscape-make-verb-list)
       (message "emacs-inkscape bridge ready for action!")
       )
   (message "inkscape already started and responding to ping")))

(defun inkscape-sleep-for ()
  (sleep-for 10);;this call doesnt seem to wait at all.
  (read-string "sleep-for, just press enter");; so do this as a workaround
  ;;if the sleep-for doesnt work, we get a busy loop and we DOS dbus, and all manner of bad things happen
  ;;TODO therefore ive factored out the sleep-for until a proper resolution is found
)

;; call-verb support
;; inkscape doesnt export all functionality through proper dbus interfaces atm.
;; there is an older "verb" interface, and a dbus bridge.
;; here is some code that tries to aproximate the dbus-proxy api for the verb api

(defun inkscape-make-verb-list ()
  (start-process "inkscape-verb-list" "*inkscape-verb-list*" inkscape-path "--verb-list")
  (with-current-buffer  "*inkscape-verb-list*"
    (goto-char (point-min))
    (while (re-search-forward  "^\\([^:]+\\):\\(.*\\)$" nil t)
      (message "[%s][%s]" (match-string 1) (match-string 2))
      (inkscape-make-verb-method (match-string 1)(match-string 2)))))

(defun inkscape-make-verb-method (name doc)
  (eval `(defmethod ,(intern (inkscape-transform-method-name "inkverb" name))
           ((this ,(object-class inkscape-desktop)));;inkscape-desktop must be initialized
     ,doc
     (inkdoc-call-verb this ,name))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;creating the dbus proxies, using Jan Moringen fantastic
;;dbus-proxy library. The way emacs dbus integration was meant to be


(defun inkscape-transform-method-name (prefix name)
  "Transform NAME. prepend PREFIX.
 PREFIX can be inkapp- or inkdoc- for
 example. un-camelcase. switch underscore to dash."
  (concat prefix "-" (replace-regexp-in-string "_" "-" (dbus-proxy-transform-camel-case name))))




(defun inkscape-app-dbus-proxy-create ()
  "create dbus-proxy to talk to inkscape app"
  (let* ((dbus-proxy-transform-method-name-function (lambda (name) (inkscape-transform-method-name "inkapp" name)))
         (obj (dbus-proxy-make-remote-proxy
                    :session "org.inkscape"
                    "/org/inkscape/application" t))
         )
obj   )
)


(defun inkscape-document-dbus-proxy-create (desktop)
  "create dbus-proxy to talk to inkscape desktop"
  (let* ((dbus-proxy-transform-method-name-function (lambda (name) (inkscape-transform-method-name "inkdoc" name)))
         (obj (dbus-proxy-make-remote-proxy
                    :session "org.inkscape"
                    (concat "/org/inkscape/" desktop) t))
         )
obj   )
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;test code
(defun inkscape-dbus-proxy-test ()
  (inkscape-app-dbus-proxy-create)
  (let*
      ((doc (inkscape-document-dbus-proxy-create "desktop_0")))
    (inkdoc-rectangle doc 100 100 100 100)))

;;get all defined inkscape methods
;;(remove-if-not (lambda (x)(string-match "^ink.*-" (symbol-name x)) ) (eieio-all-generic-functions))



(defun  inkscape-test ()
  "Opens inkscape, draws a black rectangle. a dbus compatible
Inkscape needs to be running 1st. this test doesnt use the dbus-proxy."
  (let*
    ((desktop "/org/inkscape/desktop_0")
     (rect (dbus-call-method
               :session "org.inkscape" desktop
               "org.inkscape.document" "rectangle" :int32 100 :int32  100 :int32  100 :int32  100))
           )))

(provide 'inkscape)


[-- Attachment #3: Type: text/plain, Size: 19 bytes --]


-- 
Joakim Verona

             reply	other threads:[~2010-10-22  9:19 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-10-22  9:19 joakim [this message]
2010-10-22  9:35 ` how to wait for a process to be alive? Lars Magne Ingebrigtsen
2010-10-22 12:18 ` Michael Albinus

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=m3ocam4mau.fsf@verona.se \
    --to=joakim@verona.se \
    --cc=emacs-devel@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).