Inkscape scripting API (Draft)
Here is the first draft of a Dbus based Inkscape scripting API:
http://www.cs.grinnell.edu/~bergsore/inkscapeDbusRef.html (Many thanks to the ConsoleKit team for the scripts and build system I used to generate this documentation.)
I would welcome any comments or criticisms, the interface is very much still up in the air so any suggestions, from small changes to major issues, would be welcome.
I would particularly like to hear if people think that this would potentially support the ways in which they use Inkscape, or whether there are use cases this doesn't address. If there are lots of uses that this interface does not support, additional interfaces geared towards different users could be added. (In fact there was originally one more interface than there is now, see document_new() for details.)
If you like the current API (in general) feel free to suggest additional functions or functionality.
Finally, how would you like to see this extended? Dbus has proven to be quite responsive and robust for this application. How would you build off the basic platform of the Inkscape application interface?
I will keep the posted link updated as I make changes based on peoples feedback.
-Soren
On Wed, 2009-07-08 at 20:16 -0700, Glimmer Labs wrote:
Here is the first draft of a Dbus based Inkscape scripting API:
The draft looks good, thanks for going through this work, I'm happy to see it getting done.
Finally, how would you like to see this extended? Dbus has proven to be quite responsive and robust for this application. How would you build off the basic platform of the Inkscape application interface?
I would like to see hooks for groups as objects. I have a bar code plugin which would benefit a lot from being able to handle resize events, text editing events and so on, even so much as being able to edit the object with ui from the plugin if required.
Best Regards, Martin Owens
First off, I forgot to mention in my first e-mail that this is a very conservative API. Most of the functions are already written and tested, and of the rest only a few will take a decent amount of coding. The others just need to call a verb or some pre-existing Inkscape function.
I tried not to put anything in this draft that I wasn't sure could be implemented.
Signals/Events:
That being said I have been thinking about signals for a while and did not put them in the first draft for two reasons. One, they complicate things a little. Having signals or asynchronous functions requires more knowledge of dbus on the client side and adds complexity. I wanted to keep the first draft simple.
Two, I'm not sure how much work it would be to add them. Sure I could add a hack in sp_document_done, but it is not enough to know there was a keyboard event, you also want to know what key was pressed (for example.) To get the data of an Inkscape event I would need to create EventListeners and register them with EventTargets and parse values and decide which to send and so on for each signal I wanted to expose.
Maybe someone who knows the event system will tell me that there is a way to expose all the Inkscape events at once without having to do a lot of coding for each separate signal I want to send, but I doubt it.
I'll keep looking into it though, it's definitely a possibility and I'm sure it will get done at some point if there is demand for it. Perhaps I'll create a "Proposed" interface to act as a sort of API wishlist.
Hi, it's great work! I apologize that I follow this thread late.
I have done some work about the event listener and signal trigger of inkscape editing events in another project[1].
In short, my implementation[2] is to add an child class of "Inkscape::XML::NodeObserver", and hook 5 notification method as: (thanks to Jon Cruz's hint, someday on IRC )
1 notifyChildAdded 2 notifyChildRemoved 3 notifyChildOrderChanged 4 notifyAttributeChanged 5 notifyContentChanged
Those hook can catch all editing events of SVG modification, even undo/redo operation, too.
I guess that if we added some parsing and object filter ( for example which node changes, and which attribute changes), we could make some convenient signal to trigger external scripts.
BTW, I do not attempt affect your current work in a rush, so please keeping going your own tempo. I just wan to say that if there is something I can help/contribute to, or there is some plan about this related work, please count me in :-)
hope this information helps...
sincerely, Mat.
[1]. http://code.google.com/p/inkboardng/ [2]. http://code.google.com/p/inkboardng/source/browse/trunk/inkdbus/inkdbus-impl...
On Thu, Jul 9, 2009 at 2:56 PM, Glimmer Labs <glimmer07@...400...> wrote:
First off, I forgot to mention in my first e-mail that this is a very conservative API. Most of the functions are already written and tested, and of the rest only a few will take a decent amount of coding. The others just need to call a verb or some pre-existing Inkscape function.
I tried not to put anything in this draft that I wasn't sure could be implemented.
Signals/Events:
That being said I have been thinking about signals for a while and did not put them in the first draft for two reasons. One, they complicate things a little. Having signals or asynchronous functions requires more knowledge of dbus on the client side and adds complexity. I wanted to keep the first draft simple.
Two, I'm not sure how much work it would be to add them. Sure I could add a hack in sp_document_done, but it is not enough to know there was a keyboard event, you also want to know what key was pressed (for example.) To get the data of an Inkscape event I would need to create EventListeners and register them with EventTargets and parse values and decide which to send and so on for each signal I wanted to expose.
Maybe someone who knows the event system will tell me that there is a way to expose all the Inkscape events at once without having to do a lot of coding for each separate signal I want to send, but I doubt it.
I'll keep looking into it though, it's definitely a possibility and I'm sure it will get done at some point if there is demand for it. Perhaps I'll create a "Proposed" interface to act as a sort of API wishlist.
Enter the BlackBerry Developer Challenge This is your chance to win up to $100,000 in prizes! For a limited time, vendors submitting new applications to BlackBerry App World(TM) will have the opportunity to enter the BlackBerry Developer Challenge. See full prize details at: http://p.sf.net/sfu/Challenge _______________________________________________ Inkscape-devel mailing list Inkscape-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/inkscape-devel
I read my previous post again and it sounds a bit too negative, please don't mind :) A big improvement would be if we could create a selection independently of what is shown on the screen (though then maybe it should be called ObjectSet), and then the selection_delete etc. functions would operate on an ObjectSet instead of on the global selection.
a comment to this:
Mat-48 wrote:
Those hook can catch all editing events of SVG modification, even undo/redo operation, too.
I guess that if we added some parsing and object filter ( for example which node changes, and which attribute changes), we could make some convenient signal to trigger external scripts.
A subtree observer that catches every change is perfect for inkboarding (conceptually it just needs to send and apply all those changes across a network), but I don't know whether it would be useful for scripts. If a script changes the XML in response to an XML change, it will break a lot of things (for example, most tools) which assume that when they store to XML, the data doesn't get modified on the way. I don't know what the signals exposed over DBus will be used for so I can't suggest anything.
Instead of filtering events sent to the root subtree observer one can add observers only to the XML nodes of interest - this is more efficient because not all events must be processed.
Regards, Krzysztof Kosiński
Martin Owens wrote:
On Wed, 2009-07-08 at 20:16 -0700, Glimmer Labs wrote:
Here is the first draft of a Dbus based Inkscape scripting API:
The draft looks good, thanks for going through this work, I'm happy to see it getting done.
+1! Thank you for this great effort! It fulfills my long-lasting dream of having Scriptographer-like functionality in Inkscape! I've looked through the draft and all features i could possibly desire are already there. Amazing stuff :)
Does this also mean that these actions would be available to plugins? That would be a(nother) godsend.
Pardon if it sounds hasty, but when can we expect a first version of this interface? I'd love to get my hands on it as soon as it's minimally usable. Again, many thanks for being on this :)
Glimmer Labs wrote:
Here is the first draft of a Dbus based Inkscape scripting API:
<snip />
I will keep the posted link updated as I make changes based on peoples feedback.
-Soren
Soren,
This is really very exciting for me. I have always wanted language-neutral scripting access to live Inkscape internals. Your Dbus work is the best imaginable compliment to our current simple but powerful stdin/stdout based extension mechanism. I could only spare a few moments to look over your API this morning, but what I see appears to be the answer to a number of requests, including a recent request for a scripting API that simplifies drawing and doesn't require in-depth knowledge of XML and SVG. My only immediate question is how one deals with and manipulates existing objects in a document, but my lack of understanding is almost certainly because of the lack of time I've spent reviewing the API. Before I can comment more I will need to get my hands dirty and work with the API. I apologize if I've missed it, but where can I checkout your branch?
lib2geom offers a lot of power for advanced users, have you given any thought to how a script author might combine 2geom and your Dbus API? Whether it be by convenience routines that bring data from Inkscape to py2geom or by exposing 2geom in Inkscape through your API, any work you do to enable this and make it convenient will surely pay dividends.
I can't wait to test this!
Aaron Spike
Thanks for the great responses all! I hadn't anticipated people would be so eager to try it out (though I should have, it's a lot of fun to play around with even at this stage.) I'll get a svn patch ready and talk to Ted about getting a branch set up.
Extension integration:
Ted and I have talked about supporting extensions. The general idea is to keep all of the advantages of the current extension system and simply provide some alternatives to the potentially inefficient stdin/stdout communication. Extensions already live in a separate process, so this should be a good solution. Live previews in particular would benefit from extensions not having to pass the entire document to make small changes.
I am currently investigating how this could be done while requiring minimal changes to existing extensions. Anyone familiar with extensions and what kind of functionality they would need, don't hesitate to speak up.
Lib2geom:
I hadn't looked at this before but I definitely will now. It does seem like a great way to give a ton of flexibility for advanced users. I have no idea whether it will be easy or hard but I'll give it a shot and let you know what I find.
Working with previous objects (ones you did not create):
Basically you select objects in a layer or document and get the id's from the selection. I've also added a selection_box to make this easier. A functional programmer could map a filter function onto selection_get() and set the result as the new selection. Then you could write a function to get whatever you needed: Select_blue_objects() Select_larger_than (50) Select_by_alpha (<, .5). The possibilities are endless (of course you could do this imperatively, but where's the fun in that?)
Keep those suggestions coming,
-Soren
Glimmer Labs wrote:
Working with previous objects (ones you did not create):
Basically you select objects in a layer or document and get the id's from the selection. I've also added a selection_box to make this easier. A functional programmer could map a filter function onto selection_get() and set the result as the new selection. Then you could write a function to get whatever you needed: Select_blue_objects() Select_larger_than (50) Select_by_alpha (<, .5). The possibilities are endless (of course you could do this imperatively, but where's the fun in that?)
This is exactly what I wanted to hear. Now does this behavior mandate that every element have an id attribute. I think Inkscape does this by default now. But it is not required by SVG and Jon Cruz has mentioned many times in the past that he would like to change our behavior. Are we talking id attributes or is there a unique id per element inside of Inkscape? How do we access elements that are placed outside of the visible SVG body and can't take part in a selection in Inkscape?
Nested transformations have been a bit of a problem in our current extensions because we are processing the raw XML and no one had put in the effort to write a tool that knows about these nested transforms. Its been so long since I worked with it that I don't remember exactly what the problems where. Are there circumstances when nested transformations will need to be taken into account to use your API or will it likely be transparent to the user because we are using Inkscape?
Aaron Spike
This is exactly what I wanted to hear. Now does this behavior mandate that every element have an id attribute. I think Inkscape does this by default now. But it is not required by SVG and Jon Cruz has mentioned many times in the past that he would like to change our behavior. Are we talking id attributes or is there a unique id per element inside of Inkscape?
It is using the attributes. My reasoning was that if someone is working in a scripting console they will see all the return values and might just use them directly if they are human readable. Plus it's a lot easier to debug when functions return ("rect2353", "rect3454", "path3645") rather than (0x344535, 0x387574, 0x457684). I think that's worth the performance hit of looking up objects by their id attributes.
I wasn't aware that that wasn't part of the SVG spec. All of my knowledge about this sort of thing comes from opening up the XML editor and changing values to see what they do. If the id attributes get dropped I'll have to find another way to represent objects, hopefully one that isn't too messy.
How do we access elements that are placed outside of the visible SVG body and can't take part in a selection in Inkscape?
The proposed spec has get_parent() and get_children() functions that could be used. I left them out because I thought they might be confusing to users who don't know about the XML tree. But if there are things that advanced users might really need them for (like finding unselectable nodes) then I could put them in.
Nested transformations have been a bit of a problem in our current extensions because we are processing the raw XML and no one had put in the effort to write a tool that knows about these nested transforms. Its been so long since I worked with it that I don't remember exactly what the problems where. Are there circumstances when nested transformations will need to be taken into account to use your API or will it likely be transparent to the user because we are using Inkscape?
I just went back and tested this. In the documentation I warned about certain operations with transformations applied but I hadn't actually checked yet. Turns out Inkscape's sp_move_selection (Which all of my move functions relied on, manipulating and restoring the selection if necessary) actually fails silently if there is a transformation applied. After some digging though I was able to find a lower-level function that compensates for transformations (Although users will have to be warned that it may affect the transform attribute.)
So basically the answer is, no it's not a magic bullet that automatically solves the problem. But there are ways to deal with it, and if I'm careful, hopefully users won't have to be.
On Jul 10, 2009, at 11:19 AM, Glimmer Labs wrote:
This is exactly what I wanted to hear. Now does this behavior mandate that every element have an id attribute. I think Inkscape does this by default now. But it is not required by SVG and Jon Cruz has mentioned many times in the past that he would like to change our behavior. Are we talking id attributes or is there a unique id per element inside of Inkscape?
I wasn't aware that that wasn't part of the SVG spec. All of my knowledge about this sort of thing comes from opening up the XML editor and changing values to see what they do. If the id attributes get dropped I'll have to find another way to represent objects, hopefully one that isn't too messy.
Yes, one main thing is that we need to kill id attributes except when absolutely required. Among other things, it really clutters the XML, and complicates things for technical users.
Another possible approach is XPath.
On Fri, 2009-07-10 at 16:07 -0700, Jon A. Cruz wrote:
On Jul 10, 2009, at 11:19 AM, Glimmer Labs wrote:
This is exactly what I wanted to hear. Now does this behavior mandate
that every element have an id attribute. I think Inkscape does this by
default now. But it is not required by SVG and Jon Cruz has mentioned
many times in the past that he would like to change our behavior. Are we
talking id attributes or is there a unique id per element inside of
Inkscape?
I wasn't aware that that wasn't part of the SVG spec. All of my
knowledge about this sort of thing comes from opening up the XML
editor and changing values to see what they do. If the id attributes
get dropped I'll have to find another way to represent objects,
hopefully one that isn't too messy.
Yes, one main thing is that we need to kill id attributes except when absolutely required. Among other things, it really clutters the XML, and complicates things for technical users.
Though, we will always have a Unique ID for nodes. Whether that be a memory address or something generated. We just need to in the API documentation specify that it may not be the same as the ID attribute in the XML document. There is no reason to make it more complex as the scripting environment just needs a handle to track elements and that one is handy right now.
--Ted
Excuse me, does this issue about unique Node ID has final conclusion now?
I encountered the same issue about node resolution during the development of inkboard[1], too. Because inkboard should share nodes' information between two different inkscape document instances via network and need implementation about node resolution, too. So, I wonder whether we can cooperate on this issue together?
I'm not sure whether there is an existing way to solve this primarily, but I currently have some works[2] about this:
1. get node by id I implement a function "sp_repr_lookup_id" in utils.cpp[2] which will get the node by referred id. However, sometimes the document contain duplicated node with the same id, or some node without id. So the method do not provide an unique node resolution. I believe the GSoC project also has implementation about this, too.
2. use position sequences. This is the current method I use in inkboard. For example, the string "0-3-0" means that the 1st child of the 3rd child of the 1st child of the document root.
This implementation provide a pair functions "char* sp_repr_get_abs_pos_from_node( Node *node )" and "Node* sp_repr_get_node_from_abs_pos( char* abs_pos, Node *root )" to convert between nodes and position sequence strings. This works fine, but this require both sharing document should have the same xml repr. Or it will cause the nodes into chaos.
I guess this is also covered by XPath, but I'm currently not so familiar with XPath.
3. Inkscape has an existing component handling whiteboard via jabber too ( on the dir $INSCAPE/src/jabber_whiteboard ). In this component, it introduce KeyNodePair, and KeyNodeTable to maintain the mapping between the Nodes and ID strings. However, jabber_whiteboard currently not work on my laptop, so I have not enough data to evaluate this method. But I guess this may become a way to provide unique node ID string for external usage.
I apologized if I got something missing or duplicated. Please info me if there is something I can contribute or adjust, I would like to change and cooperate with :-)
sincerely, Mat.
[1]. http://code.google.com/p/inkboardng/ [2]. http://code.google.com/p/inkboardng/source/browse/trunk/inkdbus/utils.cpp
On Wed, Jul 15, 2009 at 3:56 AM, Ted Gould <ted@...11...> wrote:
On Fri, 2009-07-10 at 16:07 -0700, Jon A. Cruz wrote:
On Jul 10, 2009, at 11:19 AM, Glimmer Labs wrote:
This is exactly what I wanted to hear. Now does this behavior mandate
that every element have an id attribute. I think Inkscape does this by
default now. But it is not required by SVG and Jon Cruz has mentioned
many times in the past that he would like to change our behavior. Are we
talking id attributes or is there a unique id per element inside of
Inkscape?
I wasn't aware that that wasn't part of the SVG spec. All of my
knowledge about this sort of thing comes from opening up the XML
editor and changing values to see what they do. If the id attributes
get dropped I'll have to find another way to represent objects,
hopefully one that isn't too messy.
Yes, one main thing is that we need to kill id attributes except when absolutely required. Among other things, it really clutters the XML, and complicates things for technical users.
Though, we will always have a Unique ID for nodes. Whether that be a memory address or something generated. We just need to in the API documentation specify that it may not be the same as the ID attribute in the XML document. There is no reason to make it more complex as the scripting environment just needs a handle to track elements and that one is handy right now.
--Ted
Enter the BlackBerry Developer Challenge This is your chance to win up to $100,000 in prizes! For a limited time, vendors submitting new applications to BlackBerry App World(TM) will have the opportunity to enter the BlackBerry Developer Challenge. See full prize details at: http://p.sf.net/sfu/Challenge _______________________________________________ Inkscape-devel mailing list Inkscape-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/inkscape-devel
- get node by id
I implement a function "sp_repr_lookup_id" in utils.cpp[2] which will get the node by referred id. However, sometimes the document contain duplicated node with the same id, or some node without id. So the method do not provide an unique node resolution. I believe the GSoC project also has implementation about this, too.
I used a pair of built in functions.
I start with a SPDesktop* and get a SPDocument* with sp_desktop_document(desk) (in desktop-handles.h) let's call it doc:
If I need an SPObject I use doc->getObjectById("rect1234") (in document.h) and get the node from that using ->repr if I need that as well.
If I only need an inkscape::XML::Node*, I can use sp_repr_lookup_name((doc->root)->repr, "rect1234") (in xml/repr.h).
To go the other direction (node to id) I use ->attribute("id") just like you do.
The latter is almost identical to your function, but it uses GQuark codes instead of string comparisons for extra speed, so you should probably check that out.
- use position sequences.
This is the current method I use in inkboard. For example, the string "0-3-0" means that the 1st child of the 3rd child of the 1st child of the document root.
This implementation provide a pair functions "char* sp_repr_get_abs_pos_from_node( Node *node )" and "Node* sp_repr_get_node_from_abs_pos( char* abs_pos, Node *root )" to convert between nodes and position sequence strings. This works fine, but this require both sharing document should have the same xml repr. Or it will cause the nodes into chaos.
That's a pretty straightforward representation, unfortunately it doesn't really work for my purposes. Since I return an ID to the user that they could (and probably will) save and use later. In the meantime the tree could have changed drastically, with nodes being added/removed layers reordered and so on.
It sounds like you only needs a temporary ID rather than a permanent one because it is created and then used immediately, so this system is good for a real-time application like yours.
I've taken a look at your event listener and it might be exactly what I need. I'm going to try to adapt it for sending dbus signals and I'll let you know how it goes.
Thanks for the heads up! -Soren
There is now a SVN branch for the dbus scripting work:
https://inkscape.svn.sourceforge.net/svnroot/inkscape/inkscape/branches/gsoc...
The build system should do everything automatically if you have a reasonably recent DBus installed (Ubuntu users should already have this.)
If your Inkscape executable is not in the standard place (/usr/local/bin/inkscape) you might have to modify src/extension/dbus/org.inkscape.service.in for Inkscape to start automatically when requested. This will be set automatically soon, but for now is hardcoded.
Almost all functions are implemented but a couple are still stubs. A few are under active development and will crash Inkscape, especially ones that return lists. Most of the functions are stable, however. See /src/extension/dbus/document-interface.cpp for details.
Let me know if you have any problems making or running the test script given in the documentation.
Thanks for your interest,
-Soren
I'm sorry that I've been gone for a few weeks.
Can someone point me to the discussion about Dbus running on non-Unix boxes? This is not a "downstream" thing, of course, but must be addressed at the top level.
Thanks, and sorry for responding late. I've been away.
bob(ishmal)
On Tue, 2009-07-14 at 21:05 -0500, Bob Jamison wrote:
Can someone point me to the discussion about Dbus running on non-Unix boxes? This is not a "downstream" thing, of course, but must be addressed at the top level.
I'm not sure of authoritative documentation on this. But I know that the KDE folks are trying to get the environment running on win32. I believe these are their instructions for getting it built:
http://techbase.kde.org/Getting_Started/Build/KDE4/Windows/Building_DBus
It seems that there is a DBus win32 project.
--Ted
On 7/14/2009 9:34 PM, Ted Gould wrote: I was bouncing my poor ideas off of Peter (a forgiving soul, to be sure), and my thought on the subject would be to have a launcher app that would:
1) Sense if a Dbus framework is already running 2) If not, start a user-level dbus daemon 3) Run Inkscape, use your scripting and extensions 4) When closing Inkscape, if you started your own daemon, close it, too.
This is similar to Mozilla running on Unix. It has one executable to set up the environment before the .bin is launched. When you quit Mozilla, they both close.
bob (ishmal)
On Tue, 2009-07-14 at 21:05 -0500, Bob Jamison wrote:
Can someone point me to the discussion about Dbus running on non-Unix boxes? This is not a "downstream" thing, of course, but must be addressed at the top level.
I'm not sure of authoritative documentation on this. But I know that the KDE folks are trying to get the environment running on win32. I believe these are their instructions for getting it built:
http://techbase.kde.org/Getting_Started/Build/KDE4/Windows/Building_DBus
It seems that there is a DBus win32 project.
--Ted
On 15/7/09 04:50, Bob Jamison wrote:
my thought on the subject would be to have a launcher app that would:
- Sense if a Dbus framework is already running
- If not, start a user-level dbus daemon
- Run Inkscape, use your scripting and extensions
- When closing Inkscape, if you started your own daemon, close it, too.
This is similar to Mozilla running on Unix. It has one executable to set up the environment before the .bin is launched. When you quit Mozilla, they both close.
GIMP 2.6.6 on OS X (Leopard) comes with its on dbus-daemon and dbus-launch included in the application package. The final launcher scripts wrap the call of gimp-bin like this:
| LeWitt:bin suv$ more gimp | #!/bin/sh | | export PATH=/tmp/skl/Gimp.app/Contents/Resources/bin:$PATH | export GIMP2_DIRECTORY="Library/Application Support/Gimp" | | DBUS=`dbus-launch --sh-syntax` | eval $DBUS | echo $DBUS_SESSION_BUS_ADDRESS > /tmp/skl/dbus-address-$UID | | gimp-2.6 "$@" | | rm /tmp/skl/dbus-address-$UID | kill $DBUS_SESSION_BUS_PID | #killall dbus-daemon
and
| LeWitt:bin suv$ more gimp-remote | #!/bin/sh | | export PATH=/tmp/skl/Gimp.app/Contents/Resources/bin:$PATH | export GIMP2_DIRECTORY="Library/Application Support/Gimp" | | export DBUS_SESSION_BUS_ADDRESS=`cat /tmp/skl/dbus-address-$UID` | | exec gimp-2.6 "$@"
~suv
UPDATE: If you have checked out the branch please update. A important file was inadvertently left out.
I'm working on a PPA to make it easier for people to try it out but I've never done any packaging so it might take awhile for me to get it set up.
On Tue, Jul 14, 2009 at 7:50 PM, Bob Jamison<ishmalius@...400...> wrote:
On 7/14/2009 9:34 PM, Ted Gould wrote: I was bouncing my poor ideas off of Peter (a forgiving soul, to be sure), and my thought on the subject would be to have a launcher app that would:
- Sense if a Dbus framework is already running
- If not, start a user-level dbus daemon
- Run Inkscape, use your scripting and extensions
- When closing Inkscape, if you started your own daemon, close it, too.
bob (ishmal)
This could be done but I don't know how often it would be used. Most systems with DBus installed (i.e. any modern Gnome) will have a session daemon running for each session. It could be useful for people who install DBus just to try out this API, though, and I'd certainly want to support those users, so I'll check it out.
Also I'll have to make sure that a user level DBus daemon could provide the default session bus. Otherwise users would have to look for the interface on two separate buses (The session bus, or our own private bus if that's not running.)
On Tue, 2009-07-14 at 21:05 -0500, Bob Jamison wrote:
Can someone point me to the discussion about Dbus running on non-Unix boxes? This is not a "downstream" thing, of course, but must be addressed at the top level.
I'm not sure of authoritative documentation on this. But I know that the KDE folks are trying to get the environment running on win32. I believe these are their instructions for getting it built:
http://techbase.kde.org/Getting_Started/Build/KDE4/Windows/Building_DBus
It seems that there is a DBus win32 project.
--Ted
There is a separate branch of the DBus project called winDBus, eventually it plans to merge back into the main project and make DBus multi-platform.
There are some independent efforts as well and some projects (http://www.slurdge.org/deluge-on-windows) already use DBus on windows.
I looked at the windows version of DBus when I researched my proposal for this project. My impression was that it wasn't quite stable but that it was being actively worked on.
My plan was to have it be Unix only at first and add windows support when windows DBus has been hammered out a bit more. It may always take a little effort to get DBus running on Windows, so I doubt that this API will ever be the default on that platform, but it should work in native Windows eventually.
The link Ted gave suggests that DBus on windows might be possible now for people running a msvc or minGW environment.
On Thu, 2009-07-16 at 09:59 -0700, Glimmer Labs wrote:
On Tue, Jul 14, 2009 at 7:50 PM, Bob Jamison<ishmalius@...400...> wrote:
On 7/14/2009 9:34 PM, Ted Gould wrote: I was bouncing my poor ideas off of Peter (a forgiving soul, to be sure), and my thought on the subject would be to have a launcher app that would:
- Sense if a Dbus framework is already running
- If not, start a user-level dbus daemon
- Run Inkscape, use your scripting and extensions
- When closing Inkscape, if you started your own daemon, close it, too.
This could be done but I don't know how often it would be used. Most systems with DBus installed (i.e. any modern Gnome) will have a session daemon running for each session. It could be useful for people who install DBus just to try out this API, though, and I'd certainly want to support those users, so I'll check it out.
I think that he is meaning only for Windows. At least I hope so. Please Bob correct me if I'm wrong there.
Also I'll have to make sure that a user level DBus daemon could provide the default session bus. Otherwise users would have to look for the interface on two separate buses (The session bus, or our own private bus if that's not running.)
I think the only application for having a private bus is for testing. There has been some discussion for security issues, but I think that it's not really supported.
My plan was to have it be Unix only at first and add windows support when windows DBus has been hammered out a bit more. It may always take a little effort to get DBus running on Windows, so I doubt that this API will ever be the default on that platform, but it should work in native Windows eventually.
I think that there's no reason though to not help people who want to get it on Windows :) Though, we haven't made it a requirement of the GSoC project because it was a little nebulous. I'm not sure how other windows apps would find the DBus that's running. Probably the best thing is to make it so that if the code can't connect to a bus, it just silently moves on.
--Ted
On 7/18/2009 10:23 PM, Ted Gould wrote:
I think that he is meaning only for Windows. At least I hope so. Please Bob correct me if I'm wrong there.
Well, yes and no. Of course I am thinking first of Windows and OSX, and how they should remain first-class citizens of the Inkscape environment, and not poor stepchildren.
-But- it will certainly happen often where Linux people will have enough GTK stuff to run Inkscape, but will -NOT- be running Gnome. Either a non-Gnome, or a non-recent Gnome, environment will lack dbus. A KDE environment may likely not have dbus running.
Also I'll have to make sure that a user level DBus daemon could provide the default session bus. Otherwise users would have to look for the interface on two separate buses (The session bus, or our own private bus if that's not running.)
I would be surprised if a dbus daemon would start up correctly if another were already running. If a root dbus daemon is running, then of course you don't need another one. We only would want to run one if it's not already there. It's like if you have an electric generator for your home lighting in case of a storm. Normally you would just use the power mains.
My plan was to have it be Unix only at first and add windows support when windows DBus has been hammered out a bit more. It may always take a little effort to get DBus running on Windows, so I doubt that this API will ever be the default on that platform, but it should work in native Windows eventually.
We have resisted for a long time the temptation to treat non-Unix boxes as limited-capability ports. An --ENORMOUS-- amount of work has been expended to prevent that from happening. Please let's not surrender now.
The problem doesn't really look that hard, though. We've seen worse. Remember the codepages? :-)
bob (ishmal)
On Sun, 2009-07-19 at 01:24 -0500, Bob Jamison wrote:
On 7/18/2009 10:23 PM, Ted Gould wrote:
I think that he is meaning only for Windows. At least I hope so. Please Bob correct me if I'm wrong there.
Well, yes and no. Of course I am thinking first of Windows and OSX, and how they should remain first-class citizens of the Inkscape environment, and not poor stepchildren.
Well, yes, but, we can't expect them to be exactly the same all the time. If nothing else, the number of developers contributing on win32 is smaller than the number contributing on win32. Just by that ratio I would always expect win32 to lag a little bit with new features. Not a 'dis to the people doing the work; it's just a numbers game.
-But- it will certainly happen often where Linux people will have enough GTK stuff to run Inkscape, but will -NOT- be running Gnome. Either a non-Gnome, or a non-recent Gnome, environment will lack dbus. A KDE environment may likely not have dbus running.
The Linux desktop today won't really run without DBus. Infact, most distro's won't boot without DBus. It's really become a critical service that we can count on withing the Linux Desktop.
Also I'll have to make sure that a user level DBus daemon could provide the default session bus. Otherwise users would have to look for the interface on two separate buses (The session bus, or our own private bus if that's not running.)
I would be surprised if a dbus daemon would start up correctly if another were already running. If a root dbus daemon is running, then of course you don't need another one. We only would want to run one if it's not already there. It's like if you have an electric generator for your home lighting in case of a storm. Normally you would just use the power mains.
On a typical desktop linux system there are two running. A system bus and a session bus. But there can be as many session buses as there are users logged in. It's also possible to have more than that. For instance we create custom buses for our test harnesses to ensure there isn't any interference on the bus for the tests executing.
In most cases there is very little reason to run more than on session bus. And I think that we should check for the session bus, and if it doesn't exist, assume the user doesn't want to use DBus.
My plan was to have it be Unix only at first and add windows support when windows DBus has been hammered out a bit more. It may always take a little effort to get DBus running on Windows, so I doubt that this API will ever be the default on that platform, but it should work in native Windows eventually.
We have resisted for a long time the temptation to treat non-Unix boxes as limited-capability ports. An --ENORMOUS-- amount of work has been expended to prevent that from happening. Please let's not surrender now.
Heh, remember the Alamo! Oh, wait, probably not a good reference ;)
--Ted
Hi Soren, excuse me , I lagged behind your work for some weeks.
Has you successfully done a PPA?
I would like to help, too.
sincerely, Mat.
Glimmer Labs 提到:
UPDATE: If you have checked out the branch please update. A important file was inadvertently left out.
I'm working on a PPA to make it easier for people to try it out but I've never done any packaging so it might take awhile for me to get it set up.
On Tue, Jul 14, 2009 at 7:50 PM, Bob Jamison<ishmalius@...400...> wrote:
On 7/14/2009 9:34 PM, Ted Gould wrote: I was bouncing my poor ideas off of Peter (a forgiving soul, to be sure), and my thought on the subject would be to have a launcher app that would:
- Sense if a Dbus framework is already running
- If not, start a user-level dbus daemon
- Run Inkscape, use your scripting and extensions
- When closing Inkscape, if you started your own daemon, close it, too.
bob (ishmal)
This could be done but I don't know how often it would be used. Most systems with DBus installed (i.e. any modern Gnome) will have a session daemon running for each session. It could be useful for people who install DBus just to try out this API, though, and I'd certainly want to support those users, so I'll check it out.
Also I'll have to make sure that a user level DBus daemon could provide the default session bus. Otherwise users would have to look for the interface on two separate buses (The session bus, or our own private bus if that's not running.)
On Tue, 2009-07-14 at 21:05 -0500, Bob Jamison wrote:
Can someone point me to the discussion about Dbus running on non-Unix boxes? This is not a "downstream" thing, of course, but must be addressed at the top level.
I'm not sure of authoritative documentation on this. But I know that the KDE folks are trying to get the environment running on win32. I believe these are their instructions for getting it built:
http://techbase.kde.org/Getting_Started/Build/KDE4/Windows/Building_DBus
It seems that there is a DBus win32 project.
--Ted
There is a separate branch of the DBus project called winDBus, eventually it plans to merge back into the main project and make DBus multi-platform.
There are some independent efforts as well and some projects (http://www.slurdge.org/deluge-on-windows) already use DBus on windows.
I looked at the windows version of DBus when I researched my proposal for this project. My impression was that it wasn't quite stable but that it was being actively worked on.
My plan was to have it be Unix only at first and add windows support when windows DBus has been hammered out a bit more. It may always take a little effort to get DBus running on Windows, so I doubt that this API will ever be the default on that platform, but it should work in native Windows eventually.
The link Ted gave suggests that DBus on windows might be possible now for people running a msvc or minGW environment.
Enter the BlackBerry Developer Challenge This is your chance to win up to $100,000 in prizes! For a limited time, vendors submitting new applications to BlackBerry App World(TM) will have the opportunity to enter the BlackBerry Developer Challenge. See full prize details at: http://p.sf.net/sfu/Challenge _______________________________________________ Inkscape-devel mailing list Inkscape-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/inkscape-devel
Glimmer Labs wrote:
There is now a SVN branch for the dbus scripting work:
https://inkscape.svn.sourceforge.net/svnroot/inkscape/inkscape/branches/gsoc...
The build system should do everything automatically if you have a reasonably recent DBus installed (Ubuntu users should already have this.)
I believe ubuntu users will need the libdbus-glib-1-dev package installed.
If your Inkscape executable is not in the standard place (/usr/local/bin/inkscape) you might have to modify src/extension/dbus/org.inkscape.service.in for Inkscape to start automatically when requested. This will be set automatically soon, but for now is hardcoded.
In addition to having the installation process edit the exec path in the service file, we should also discuss where best to place the service file. The most usual case for having inkscape installed in a non-standard place is to have more than one inkscape installed. I suppose our options are: 1) to continue to add the file to /usr/share/dbus-1/services and give alternate names. 2) add the file to $PREFIX/share/dbus-1/services and (let the user) add a <servicedir /> directive to the dbus configuration. I suppose both options require us to rename the service anyway. I don't know what is appropriate. (I have similar questions with py2geom installation.) Does DBus allow for two identically named services? Does DBus provide consumers with the ability to enumerate and search for services, perhaps asking which inkscapes are available?
Aaron Spike
aaron@...1252...:~/src/inkscape_dbus$ make install Making install in src make[1]: Entering directory `/home/aaron/src/inkscape_dbus/src' make install-am make[2]: Entering directory `/home/aaron/src/inkscape_dbus/src' make[3]: Entering directory `/home/aaron/src/inkscape_dbus/src' test -z "/home/aaron/opt/inkscape_dbus/bin" || /bin/mkdir -p "/home/aaron/opt/inkscape_dbus/bin" /usr/bin/install -c 'inkscape' '/home/aaron/opt/inkscape_dbus/bin/inkscape' /usr/bin/install -c 'inkview' '/home/aaron/opt/inkscape_dbus/bin/inkview' test -z ""/usr/share/dbus-1/services"" || /bin/mkdir -p ""/usr/share/dbus-1/services"" /usr/bin/install -c -m 644 'extension/dbus/org.inkscape.service' '/usr/share/dbus-1/services/org.inkscape.service' /usr/bin/install: cannot create regular file `/usr/share/dbus-1/services/org.inkscape.service': Permission denied make[3]: *** [install-serviceDATA] Error 1 make[3]: Leaving directory `/home/aaron/src/inkscape_dbus/src' make[2]: *** [install-am] Error 2 make[2]: Leaving directory `/home/aaron/src/inkscape_dbus/src' make[1]: *** [install] Error 2 make[1]: Leaving directory `/home/aaron/src/inkscape_dbus/src' make: *** [install-recursive] Error 1
On Sat, 2009-07-18 at 19:40 -0500, Aaron Spike wrote:
Glimmer Labs wrote:
If your Inkscape executable is not in the standard place (/usr/local/bin/inkscape) you might have to modify src/extension/dbus/org.inkscape.service.in for Inkscape to start automatically when requested. This will be set automatically soon, but for now is hardcoded.
In addition to having the installation process edit the exec path in the service file, we should also discuss where best to place the service file. The most usual case for having inkscape installed in a non-standard place is to have more than one inkscape installed. I suppose our options are: 1) to continue to add the file to /usr/share/dbus-1/services and give alternate names. 2) add the file to $PREFIX/share/dbus-1/services and (let the user) add a <servicedir /> directive to the dbus configuration. I suppose both options require us to rename the service anyway. I don't know what is appropriate. (I have similar questions with py2geom installation.) Does DBus allow for two identically named services? Does DBus provide consumers with the ability to enumerate and search for services, perhaps asking which inkscapes are available?
I believe that DBus activation only allows for one service of each name. Making additional names isn't that difficult though, we could definitely make that part of the build. What I did with the inkscape-devel nightly package when that was running is that I changed all the names for the icons and everything to be a different name. That was nice, but kinda a pain.
Though, I'm not sure how many developers will be using DBus activation actively. Honestly, it's kinda a trick feature that's nice to enable, but I'm not sure of any use cases right now.
--Ted
On Wed, Jul 8, 2009 at 10:16 PM, Glimmer Labs<glimmer07@...400...> wrote:
Here is the first draft of a Dbus based Inkscape scripting API:
http://www.cs.grinnell.edu/~bergsore/inkscapeDbusRef.html (Many thanks to the ConsoleKit team for the scripts and build system I used to generate this documentation.)
I would welcome any comments or criticisms, the interface is very much still up in the air so any suggestions, from small changes to major issues, would be welcome.
I would particularly like to hear if people think that this would potentially support the ways in which they use Inkscape, or whether there are use cases this doesn't address.
At a glance, I don't see API for bitmap manipulation: placing, sizing, moving ... I am very interested in scripting the creation of documents combining bitmap, vector and text.
Thanks, Kent
If there are lots of uses
that this interface does not support, additional interfaces geared towards different users could be added. (In fact there was originally one more interface than there is now, see document_new() for details.)
If you like the current API (in general) feel free to suggest additional functions or functionality.
Finally, how would you like to see this extended? Dbus has proven to be quite responsive and robust for this application. How would you build off the basic platform of the Inkscape application interface?
I will keep the posted link updated as I make changes based on peoples feedback.
-Soren
Enter the BlackBerry Developer Challenge This is your chance to win up to $100,000 in prizes! For a limited time, vendors submitting new applications to BlackBerry App World(TM) will have the opportunity to enter the BlackBerry Developer Challenge. See full prize details at: http://p.sf.net/sfu/Challenge _______________________________________________ Inkscape-devel mailing list Inkscape-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/inkscape-devel
At a glance, I don't see API for bitmap manipulation: placing, sizing, moving ... I am very interested in scripting the creation of documents combining bitmap, vector and text.
Thanks, Kent
I've added a function to import an image. It returns an id like all the other shape creation functions and can be used with any of the (non-path-specific) API functions to move, rotate, resize, set width/height (will distort), etc. It pretty much behaves like a rectangle without path or style.
The only thing you can't do right now is trace it into a path, since that is a complicated operation with many variables.
-Soren
On Thu, Jul 23, 2009 at 3:00 PM, Glimmer Labs<glimmer07@...400...> wrote:
At a glance, I don't see API for bitmap manipulation: placing, sizing, moving ... I am very interested in scripting the creation of documents combining bitmap, vector and text.
Thanks, Kent
I've added a function to import an image. It returns an id like all the other shape creation functions and can be used with any of the (non-path-specific) API functions to move, rotate, resize, set width/height (will distort), etc. It pretty much behaves like a rectangle without path or style.
Wow. I'd given up on the old way several times, now 5 lines does it:
import dbus bus = dbus.SessionBus() inkdoc1 = bus.get_object('org.inkscape', '/org/inkscape/desktop_0') doc1 = dbus.Interface(inkdoc1, dbus_interface="org.inkscape.document") print doc1.image(10 ,10, '/home/ktenney/Firefox_wallpaper.png')
$ image2816
That is _so_ cool.
Is there going to be collaboration on building a Python class library for the dbus API?
Thanks, Kent
The only thing you can't do right now is trace it into a path, since that is a complicated operation with many variables.
-Soren
Is there going to be collaboration on building a Python class library for the dbus API?
I've tried to do as much as possible on the Inkscape side but there will definitely be things that are better done on the client side to cut down on messages.
I've already amassed a fairly extensive Python test script but so far all the helper functions have eventually migrated to the API.
If anyone has any particularly useful functions though I could find a place to host them and link them from the documentation.
-Soren
P.S. I'm going to be out of town next week, and will not be able to check e-mail. So if anyone has questions, I'm not just being unresponsive and will get back to you next weekend.
On Fri, 2009-07-24 at 09:17 -0500, Kent Tenney wrote:
import dbus bus = dbus.SessionBus() inkdoc1 = bus.get_object('org.inkscape', '/org/inkscape/desktop_0') doc1 = dbus.Interface(inkdoc1, dbus_interface="org.inkscape.document") print doc1.image(10 ,10, '/home/ktenney/Firefox_wallpaper.png')
Besides what Soren already said, we also plan on making a small library using GObject that hides all the DBus stuff. This library will support GObject introspection so it will work with Python and other languages easily. It should hopefully make it a little easier, and turn that into 2 lines instead of that lengthy 5 ;)
--Ted
Some random thoughts after reading the documentation.
The API looks like it is tied to the UI and uses global objects / state. For example, it seems that I have to change the selection in order to delete an object. I heard this called the "accumulate and fire" anti-pattern. Of course exposing methods to retrieve the contents of the selection are a must, but changing the selection or any other UI element should not be necessary to execute operations. The downside is that it requires many changes on the Inkscape side - several important internal functions require an SPDesktop for no reason other than getting the selection, while they should operate on object lists instead. 0.47 is supposed to be a refactoring release, but to me it looks like what was done so far just scratches the surface.
The demos are exciting, but let's also think about doing it right from day 1 so that we won't have to turn around, waste time and break things later.
Regards, Krzysztof Kosiński
On Sat, 2009-07-25 at 17:37 -0700, Krzysztof Kosiński wrote:
The API looks like it is tied to the UI and uses global objects / state.
I think that you're thinking about the API a little bit differently. Specifically, you're thinking about it talking to people who know what "anti-pattern" means :)
The API that Soren developed is tied closely to the UI, for one of the things that it's meant to do is empower a scripting console for technical users to be able to quickly do operations that would be otherwise difficult. Think of something like Autocad here. So the idea is that it might be easier for you to select all the rectangles using a quick script rather than figure out where they are. We also want people to be able to turn their scripts into extensions for sharing and to help developers get involved in the project. (easy contributions are addictive :)
That all being said, I think your idea of a non-visible desktop is a good one.
--Ted
I somehow missed this e-mail originally. My apologies for the late reply.
2009/7/25 Krzysztof Kosiński <tweenk.pl@...400...>:
The API looks like it is tied to the UI and uses global objects / state ... but changing the selection or any other UI element should not be necessary to execute operations. The downside is that it requires many changes on the Inkscape side ... The demos are exciting, but let's also think about doing it right from day 1 so that we won't have to turn around, waste time and break things later.
Regards, Krzysztof Kosiński
The original plan was to have two distinct interfaces. One directly tied to the UI that would require a SPDesktop, and one that would only require a SPDocument and would not show a window.
The second one was eventually put on hold (see application-interface in the documentation for details) because so much of the functionality was selection based.
Having a way of grouping objects other than selections was the initial plan, but for better or worse most of Inkscape's functionality is implemented through selections. To avoid them, lots of complex code that takes into account many different factors would have to be duplicated reducing maintainability.
The good news is that if Inkscape ever did refactor the way operations on multiple objects are performed, the dbus code could support that without much modification. It's just not something I could tackle this summer.
I didn't find this comment overly negative at all. It's a good point, though as Ted pointed out the direct relation to the UI does have it's advantages for certain users (which is why I wanted two separate interfaces.)
Thanks for the input, -Soren
Glimmer Labs wrote:
The good news is that if Inkscape ever did refactor the way operations on multiple objects are performed, the dbus code could support that without much modification. It's just not something I could tackle this summer.
That's great! I hope that sooner or later we'll rewrite most of the selection functions to take a list or set of SPObjects. Even though the exposed API might have some shortcomings right now, its technical principle is excellent, as it allows tightly integrated, language-neutral plugins in separate processes. In fact this might be one of the first FOSS implementation of such a design. I know that Konqueror keeps the Flash plugin in a separate process, but that's different, as NSAPI doesn't really allow the plugins to integrate with the browser. You can definitely be proud of your project :)
Regards, Krzysztof
participants (11)
-
Aaron Spike
-
Bob Jamison
-
Glimmer Labs
-
Jon A. Cruz
-
Kent Tenney
-
Krzysztof Kosiński
-
Martin Owens
-
Mat
-
ricardo lafuente
-
Ted Gould
-
~suv