* how to wait for a process to be alive?
@ 2010-10-22 9:19 joakim
2010-10-22 9:35 ` Lars Magne Ingebrigtsen
2010-10-22 12:18 ` Michael Albinus
0 siblings, 2 replies; 3+ messages in thread
From: joakim @ 2010-10-22 9:19 UTC (permalink / raw)
To: Emacs developers
[-- 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
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: how to wait for a process to be alive?
2010-10-22 9:19 how to wait for a process to be alive? joakim
@ 2010-10-22 9:35 ` Lars Magne Ingebrigtsen
2010-10-22 12:18 ` Michael Albinus
1 sibling, 0 replies; 3+ messages in thread
From: Lars Magne Ingebrigtsen @ 2010-10-22 9:35 UTC (permalink / raw)
To: emacs-devel
joakim@verona.se writes:
> Inkscape starts asynchronously, so I need to poll it, and after its
> properly living, do a number of calls.
If Inkscape outputs something when it starts up, then use
`accept-process-output' to wait for output.
--
(domestic pets only, the antidote for overdose, milk.)
larsi@gnus.org * Lars Magne Ingebrigtsen
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: how to wait for a process to be alive?
2010-10-22 9:19 how to wait for a process to be alive? joakim
2010-10-22 9:35 ` Lars Magne Ingebrigtsen
@ 2010-10-22 12:18 ` Michael Albinus
1 sibling, 0 replies; 3+ messages in thread
From: Michael Albinus @ 2010-10-22 12:18 UTC (permalink / raw)
To: joakim; +Cc: Emacs developers
joakim@verona.se writes:
> 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))
dbus-ping has the side effect to start a service, if it doesn't run yet,
and if it has provided a service file (located under
/usr/share/dbus-1/services). This would already be a good way to start
the process, if such a service file exists.
If you want to check only, whether Inkscape is running, you could call
(dbus-get-name-owner :session "org.inkscape")
> 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.
Register for the D-Bus signal org.freedesktop.DBus.NameOwnerChanged. You
will get signals like this:
signal sender=org.freedesktop.DBus -> dest=(null destination) serial=8
path=/org/freedesktop/DBus; interface=org.freedesktop.DBus;
member=NameOwnerChanged
string ":1.97"
string ""
string ":1.97"
With the same dbus-get-name-owner as above call you can check, whether
Inkscape is already started.
Best regards, Michael.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2010-10-22 12:18 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-10-22 9:19 how to wait for a process to be alive? joakim
2010-10-22 9:35 ` Lars Magne Ingebrigtsen
2010-10-22 12:18 ` Michael Albinus
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).