<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Daniel P. Berrangé &#187; Entangle</title>
	<atom:link href="http://berrange.com/topics/entangle/feed/" rel="self" type="application/rss+xml" />
	<link>http://berrange.com</link>
	<description>Writing about photography, open source software, virtualization &#38; more</description>
	<lastBuildDate>Tue, 03 Apr 2012 20:26:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Announce: Release of Entangle v0.3.2 – An app for tethered camera control &amp; capture</title>
		<link>http://berrange.com/posts/2012/04/03/announce-release-of-entangle-v0-3-2-an-app-for-tethered-camera-control-capture/</link>
		<comments>http://berrange.com/posts/2012/04/03/announce-release-of-entangle-v0-3-2-an-app-for-tethered-camera-control-capture/#comments</comments>
		<pubDate>Tue, 03 Apr 2012 19:59:35 +0000</pubDate>
		<dc:creator>Daniel Berrange</dc:creator>
				<category><![CDATA[Entangle]]></category>
		<category><![CDATA[Fedora]]></category>
		<category><![CDATA[Photography]]></category>
		<category><![CDATA[entangle]]></category>
		<category><![CDATA[fedora]]></category>
		<category><![CDATA[photography]]></category>
		<category><![CDATA[tethered capture]]></category>
		<category><![CDATA[transifex]]></category>
		<category><![CDATA[translation]]></category>

		<guid isPermaLink="false">http://berrange.com/?p=644</guid>
		<description><![CDATA[I am pleased to announce a new release 0.3.2 of Entangle is available for download from the usual location: http://entangle-photo.org/download/ This release has focused almost exclusively on i18n, integrating with the Fedora Transifex team for translations Major code style cleanup Mark all translatable strings in code &#38; UI files Register with Transifex for translations via [...]]]></description>
			<content:encoded><![CDATA[<p>I am pleased to announce a new release 0.3.2 of Entangle is available for download from the usual location:</p>
<ul>
<li><a href="http://entangle-photo.org/download/">http://entangle-photo.org/download/</a></li>
</ul>
<p>This release has focused almost exclusively on i18n, integrating with the Fedora Transifex team for translations</p>
<ul>
<li>Major code style cleanup</li>
<li>Mark all translatable strings in code &amp; UI files</li>
<li>Register with Transifex for translations via Fedora team</li>
<li>Pull in translations (German, Polish, Ukrainian, Japanese: full, Spanish, Chinese: partial).</li>
<li>Add m4 macros for compiler warnings, missing from previous release dist.</li>
</ul>
<p>There are a great many languages with no coverage here, so if you are able to help out, please join the Fedora translation team:</p>
<ul>
<li><a href="https://fedora.transifex.net/projects/p/entangle/">https://fedora.transifex.net/projects/p/entangle/</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://berrange.com/posts/2012/04/03/announce-release-of-entangle-v0-3-2-an-app-for-tethered-camera-control-capture/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Announce: Release of Entangle v0.3.1 – An app for tethered camera control &amp; capture</title>
		<link>http://berrange.com/posts/2012/02/13/announce-release-of-entangle-v0-3-1-an-app-for-tethered-camera-control-capture/</link>
		<comments>http://berrange.com/posts/2012/02/13/announce-release-of-entangle-v0-3-1-an-app-for-tethered-camera-control-capture/#comments</comments>
		<pubDate>Mon, 13 Feb 2012 22:25:08 +0000</pubDate>
		<dc:creator>Daniel Berrange</dc:creator>
				<category><![CDATA[Entangle]]></category>
		<category><![CDATA[Fedora]]></category>
		<category><![CDATA[Photography]]></category>
		<category><![CDATA[camera control]]></category>
		<category><![CDATA[entangle]]></category>
		<category><![CDATA[libgphoto2]]></category>
		<category><![CDATA[photography]]></category>
		<category><![CDATA[tethered capture]]></category>

		<guid isPermaLink="false">http://berrange.com/?p=613</guid>
		<description><![CDATA[I am pleased to announce a new release 0.3.1 of Entangle, a GTK3 desktop application for tethered camera control &#38; capture, is available for download from the usual location. This release has focused exclusively on bug fixing following the major refactoring that went into the previous release. If you were having trouble with the previous [...]]]></description>
			<content:encoded><![CDATA[<p>I am pleased to announce a new <a href="http://entangle-photo.org/download/sources/entangle-0.3.1.tar.gz">release 0.3.1</a> of <a href="http://entangle-photo.org">Entangle</a>, a GTK3 desktop application for tethered camera control &amp; capture, is available for download from<a href="http://entangle-photo.org/download/"> the usual location</a>. This release has focused exclusively on bug fixing following the major refactoring that went into the previous release. If you were having trouble with the previous release crashing, then I hope this new one should improve things significantly.</p>
<ul>
<li>Fix crash in handling camera control combo list</li>
<li>Add notice about need to set XDG_DATA_DIRS when installing into unusual directories</li>
<li>Add workaround to avoid immediate crash if schemas were not found in XDG_DATA_DIRS</li>
<li>Compile schema files after installation</li>
<li>Fix crash updating widget sensitivity</li>
<li>Fix crashes &amp; race conditions during capture of images</li>
<li>Fix infinite preview error message popups which can hang the window manager</li>
<li>Fix crash when retrying a failed connection attempt</li>
<li>Fix thread locking when hiding status display</li>
<li>Avoid running multiple threads for monitoring status</li>
<li>Fix initial sensitivity of camera control panels</li>
<li>Update README with new URLs for bugs/mailing lists</li>
</ul>
<p>Since the latest release I have also registered Entangle with <a href="http://gna.org">GNA!</a>, to get support for <a href="http://entangle-photo.org/communicate/">mailing lists</a> and <a href="http://entangle-photo.org/bugs/">bug tracking</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://berrange.com/posts/2012/02/13/announce-release-of-entangle-v0-3-1-an-app-for-tethered-camera-control-capture/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Announce: Release of Entangle v0.3.0 – An app for tethered camera control &amp; capture</title>
		<link>http://berrange.com/posts/2011/11/29/announce-release-of-entangle-v0-3-0-%e2%80%93-an-app-for-tethered-camera-control-capture/</link>
		<comments>http://berrange.com/posts/2011/11/29/announce-release-of-entangle-v0-3-0-%e2%80%93-an-app-for-tethered-camera-control-capture/#comments</comments>
		<pubDate>Tue, 29 Nov 2011 00:17:27 +0000</pubDate>
		<dc:creator>Daniel Berrange</dc:creator>
				<category><![CDATA[Entangle]]></category>
		<category><![CDATA[Fedora]]></category>
		<category><![CDATA[Photography]]></category>

		<guid isPermaLink="false">http://berrange.com/?p=552</guid>
		<description><![CDATA[Over a year has gone by since I released Entangle 0.2.0, so I am very pleased to be able to announce that I have now just released Entangle 0.3.0, available from the usual download place which also contains the concise list of changes. There have in fact been a great many changes in this release, [...]]]></description>
			<content:encoded><![CDATA[<p>Over a year has gone by since I released <a href="http://berrange.com/posts/2010/09/18/announce-release-of-entangle-v0-2-0-%e2%80%93-an-app-for-tethered-camera-control-capture/">Entangle 0.2.0</a>, so I am very pleased to be able to announce that I have now just released Entangle <a href="http://entangle-photo.org/download/sources/entangle-0.3.0.tar.gz">0.3.0</a>, available from the <a href="http://entangle-photo.org/download/">usual download place</a> which also contains the concise list of changes.</p>
<p>There have in fact been a great many changes in this release, but many of them will not be immediately obvious from looking at the updated <a href="http://entangle-photo.org/screenshots/">screenshots</a>.</p>
<p>First of all, has been a big effort to port to the latest best practice desktop application libraries</p>
<ul>
<li>Port Gtk2 to <strong>GTK3</strong>. To enable use of many of the new desktop features, in particular, libpeas, Entangle now targets Gtk3 instead of Gtk2</li>
<li>Port LibGlade to <strong>GtkBuilder</strong>. With the use of Gtk3 there is no longer any point in using the external Glade library for UI building. Instead Entangle now uses the GtkBuilder infrastructure that is part of regular Gtk</li>
<li>Port GConf to <strong>GSettings</strong>. With the use of Gtk3, a newer Glib2 is required, which in turn brings in the GSettings APis. With these present, there is no longer any point in using the external GConf library</li>
<li>Port Unique/StartupNotifications to <strong>GApplication</strong>. Again, since a newer Glib2 is required, it is possible to take advantage of the GApplication APIs, to avoid using the external Unique/StartupNotifcation libraries.</li>
</ul>
<p>Next up was a major internal rewrite of the way the UI handles camera operations. In previous releases, most operations were handed off to a camera scheduler thread. The design of this was overly complicated and not friendly to future extension. Having recently gained experience with the way asynchronous operations are done by the GIO library, I decided that this would be an effective approach for Entangle. So all the internal thread scheduling code was ripped out, and the GIO style asynchronous APIs were added in its place. Doing this work was a major blocking item in why it has taken so long to release 0.3.0.  Now it is all complete, I am very pleased with the way it has turned out. The code for dealing with the camera is so much simpler &amp; more flexible at the same time.</p>
<p>With that out of the way, there are the general user visible feature improvements</p>
<ul>
<li><strong>Config refresh</strong>. For Nikon cameras, Entangle automatically updates the UI whenever any camera configuration setting changes</li>
<li><strong>Continuous monitoring</strong>. Instead of having to explicitly start/stop monitoring, Entangle now monitors the camera for new images at all times, and auto-downloads them as they are captured</li>
<li><strong>Continuous preview mode</strong>. Previously preview would be stopped after an image was captured. Now it is possible to capture many images in sequence, while remaining in preview mode</li>
<li><strong>Folder preserved</strong>. Previously when connecting to a camera, the session folder would be reset to a default location based on camera model name. Now Entangle simply always remembers the user&#8217;s last folder</li>
<li><strong>Avoid delete after download</strong>. The default behaviour is to delete files from the camera after downloading. This can now be disabled, to allow images to remain on the memory card.</li>
<li><strong>Config UI improvements</strong>. The UI for displaying camera settings has been improved &amp; simplified. The &#8220;Other PTP properties&#8221; panel has been removed to improve UI performance. The &#8216;Camera Status&#8217; panel now just uses labels, instead of readonly text fields for a more compact display.</li>
<li><strong>Image metadata summary.</strong> When moving the mouse over the Entangle window, a summary of the image metadata (extracted with GExiv2) will be displayed, showing the aperture, focal length, shutter speed, ISO and resolution.</li>
</ul>
<p>With such large changes in the basic infrastructure, there are bound to be new wierd bugs introduced, but overall this release should be a good foundation for ongoing incremental development of Entangle.</p>
]]></content:encoded>
			<wfw:commentRss>http://berrange.com/posts/2011/11/29/announce-release-of-entangle-v0-3-0-%e2%80%93-an-app-for-tethered-camera-control-capture/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Announce: Release of Entangle v0.2.0 – An app for tethered camera control &amp; capture</title>
		<link>http://berrange.com/posts/2010/09/18/announce-release-of-entangle-v0-2-0-%e2%80%93-an-app-for-tethered-camera-control-capture/</link>
		<comments>http://berrange.com/posts/2010/09/18/announce-release-of-entangle-v0-2-0-%e2%80%93-an-app-for-tethered-camera-control-capture/#comments</comments>
		<pubDate>Sat, 18 Sep 2010 09:50:53 +0000</pubDate>
		<dc:creator>Daniel Berrange</dc:creator>
				<category><![CDATA[Entangle]]></category>

		<guid isPermaLink="false">http://berrange.com/?p=383</guid>
		<description><![CDATA[A few months on from the first release, I&#8217;ve polished off the latest changes in Entangle and pushed out a new release version 0.2.0. This is primarily a bug fix and code maintenance release, with the following important changes Better compatibility with cameras which don&#8217;t support event notifications, allowing use of capture functionality Rewrote the [...]]]></description>
			<content:encoded><![CDATA[<p>A few months on from the <a href="http://berrange.com/posts/2010/04/09/announce-release-of-entangle-v0-1-0-an-app-for-tethered-camera-control-capture/">first release</a>, I&#8217;ve polished off the latest changes in <a href="http://entangle-photo.org/">Entangle</a> and pushed out a new release <a href="http://entangle-photo.org/download/sources/entangle-0.2.0.tar.gz">version 0.2.0</a>. This is primarily a bug fix and code maintenance release, with the following important changes</p>
<ul>
<li>Better compatibility with cameras which don&#8217;t support event notifications, allowing use of capture functionality</li>
<li>Rewrote the preview mode to actually be useful, providing a continuously updating live view until ready to capture</li>
<li>Directly offers to unmount the camera if it is locked by the GVFS gphoto2 plugin preventing its use for capture.</li>
<li>Replaces custom plugin code with use of libpeas.</li>
<li>Vastly improved the error reporting and logging to make diagnosis of camera problems easier</li>
<li>Fixed a nasty infinite loop in the camera capture code where a camera event could keep resetting the event timeout</li>
<li>Fixed a crash in accessing udev properties</li>
</ul>
<p>It is already built for Fedora 14 and on its way into updates-testing, Fedora 15 will have to wait due to broken build roots caused by mutually conflicting upstart/systemd packages:-(  Alternatively grab the source code from <a href="http://entangle-photo.org/download/sources/">the download area</a>. For the next release I&#8217;m aiming to improve the full screen mode to give access to some of the capture &amp; config controls, and generally improve the UI for camera configuration controls.</p>
]]></content:encoded>
			<wfw:commentRss>http://berrange.com/posts/2010/09/18/announce-release-of-entangle-v0-2-0-%e2%80%93-an-app-for-tethered-camera-control-capture/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Announce: Release of Entangle v0.1.0 &#8211; An app for tethered camera control &amp; capture</title>
		<link>http://berrange.com/posts/2010/04/09/announce-release-of-entangle-v0-1-0-an-app-for-tethered-camera-control-capture/</link>
		<comments>http://berrange.com/posts/2010/04/09/announce-release-of-entangle-v0-1-0-an-app-for-tethered-camera-control-capture/#comments</comments>
		<pubDate>Fri, 09 Apr 2010 21:35:13 +0000</pubDate>
		<dc:creator>Daniel Berrange</dc:creator>
				<category><![CDATA[Entangle]]></category>

		<guid isPermaLink="false">http://berrange.com/?p=321</guid>
		<description><![CDATA[In the middle of the night on Wednesday I finally bundled up a first release of the application now called Entangle (formerly referred to as Capa). Entangle provides a GTK desktop application for tethered camera control &#38; capture, using the gphoto library. This first v0.1.0 release includes Control over nearly all camera settings exposed by [...]]]></description>
			<content:encoded><![CDATA[<p>In the middle of the night on Wednesday I finally bundled up a <a href="http://entangle-photo.org/download/sources/">first release</a> of the application now called <a href="http://entangle-photo.org/">Entangle</a> (formerly <a href="http://berrange.com/posts/2009/12/21/capa-a-desktop-application-for-photo-capture-via-a-digital-camera/">referred to</a> as Capa). Entangle provides a <a href="http://gtk.org">GTK</a> desktop application for tethered camera control &amp; capture, using the <a href="http://gphoto.org/">gphoto</a> library. This first <a href="http://entangle-photo.org/download/sources/entangle-0.1.0.tar.gz">v0.1.0</a> release includes</p>
<ul>
<li>Control over nearly all camera settings exposed by libgphoto, from simple things like shutter speed, aperture, ISO, to advanced things like Nikon CLS flash group power, autofocus points and more.</li>
<li>Remote trigger of the camera shutter from the connected computer and download of the captured image</li>
<li>Preview of the scene to be captured using &#8220;live view&#8221; capability in recent dSLRs, though the UI needs work</li>
<li>Monitoring of the camera &amp; automatic download of new images as they are captured</li>
<li>Fullscreen and presentation modes, xrandr aware, to allow display on arbitrary monitors</li>
<li>ICC profiles for accurate display of image colours. Use <a href="http://www.gnome.org/projects/gnome-color-manager/">GNOME Colour Manager</a> to setup your monitor profile</li>
</ul>
<p>That may sound like a nice list of features, but there is still plenty of work to be done, not least improving the UI for controlling camera settings which is not at all scalable when there are hundreds of settings available. There is a <a href="http://berrange.com/posts/2010/01/10/using-gobject-introspection-gjs-to-provide-a-javascript-plugin-engine/">crude plugin</a> system taking advantage of GObject introspection to allow extensions to be written using JavaScript, but at <a href="http://lists.fedoraproject.org/pipermail/devel/2010-January/129403.html">Bastien&#8217;s suggestion</a> I&#8217;ll likely re-write that to use libgpe. The engine of the app can also easily be used to create a GIMP plugin for image acquisition</p>
<p>The <a href="https://bugzilla.redhat.com/show_bug.cgi?id=580317">Fedora review</a> is approved and so as soon as CVS is ready I&#8217;ll be building for F13 &amp; rawhide, since the design team apparently want it to be part of the <a href="http://fedoraproject.org/wiki/Artwork/ArtTeamProjects/FedoraArtStudio">Design Studio Spin</a> which surprised me somewhat !</p>
]]></content:encoded>
			<wfw:commentRss>http://berrange.com/posts/2010/04/09/announce-release-of-entangle-v0-1-0-an-app-for-tethered-camera-control-capture/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Using GObject Introspection + Gjs to provide a JavaScript plugin engine</title>
		<link>http://berrange.com/posts/2010/01/10/using-gobject-introspection-gjs-to-provide-a-javascript-plugin-engine/</link>
		<comments>http://berrange.com/posts/2010/01/10/using-gobject-introspection-gjs-to-provide-a-javascript-plugin-engine/#comments</comments>
		<pubDate>Sun, 10 Jan 2010 19:39:00 +0000</pubDate>
		<dc:creator>Daniel Berrange</dc:creator>
				<category><![CDATA[Entangle]]></category>

		<guid isPermaLink="false">http://wordpress.berrange.com/?p=7</guid>
		<description><![CDATA[In writing the Capa photo capture application, one of the things I wanted to support was some form of plugin engine to allow 3rd parties to easily extend its functionality. The core application code itself is designed to have a formal separation of backend and frontend logic. The backend is focused on providing the core [...]]]></description>
			<content:encoded><![CDATA[<p>
In writing the <a href="http://capa-project.org">Capa photo capture</a> application, one of the things I wanted to support was some form of plugin engine to allow 3rd parties to easily extend its functionality. The core application code itself is designed to have a formal separation of backend and frontend logic. The backend is focused on providing the core object model &#038; operation, typically wrapping external libraries like HAL, libgphoto, lcms in GObject classes, with no use of GTK allowed here. The primary frontend builds on this backend, to produce a GTK based user interface.  It is also intended to build another frontend that provides a GIMP plugin.
</p>
<p>
Back to the question of plugins for the main frontend. If the goal is to allow people to easily write extensions, a plugin engine based on writing C code is not really very desirable. Firefox uses JavaScript for its plugin engine and this has been hugely successful in lowering the bar for contributors. Wouldn&#8217;t it be nice if any GTK application could provide a JavaScript plugin engine ? Yes, indeed and thanks to the recent development of <a href="http://live.gnome.org/GObjectIntrospection">GObject introspection</a> this is incredibly easy.
</p>
<p>
GObject introspection provides a means to query the GObject type system and discover all classes, interfaces, methods, properties, signals, all data types associated with their parameters and any calling conventions. This is an incredibly powerful capability with far reaching implications, the most important being that you will never again have to <strong>write</strong> a language binding for any GObject based library. There is enough metadata available in the GObject introspection system to provide language bindings in a 100% automated fashion. Notice I said <em>&#8220;provide&#8221;</em>, rather than <em>&#8220;generate&#8221;</em> because if targetting a dynamic language (Perl, Python JavaScript) it won&#8217;t even be necessary to auto-generate code ahead of time &#8211; everything can and will happen at runtime based on the introspection data. Say goodbye to hand written language bindings. Say goodbye to Swig. Say goodbye to any other home grown code generators.
</p>
<h2>Adding support for introspection</h2>
<p>
That&#8217;s the sales pitch, how about the reality ? The <a href="http://gitorious.org/capa/capa">Capa code</a> is based on GObject and was thus ready &#038; willing to be introspected. The first step in adding introspection support is to add some m4 magic to the <code>configure.ac</code> to look for the introspection tools &#038; library. This is simple boilerplate code that will be identical for every application using GObject + autoconf
</p>
<pre>
GOBJECT_INTROSPECTION_REQUIRED=0.6.2
AC_SUBST(GOBJECT_INTROSPECTION_REQUIRED)

AC_ARG_ENABLE([introspection],
        AS_HELP_STRING([--enable-introspection], [enable GObject introspection]),
        [], [enable_introspection=check])

if test "x$enable_introspection" != "xno" ; then
        PKG_CHECK_MODULES([GOBJECT_INTROSPECTION],
                          [gobject-introspection-1.0 &gt;= $GOBJECT_INTROSPECTION_REQUIRED],
                          [enable_introspection=yes],
                          [
                             if test "x$enable_introspection" = "xcheck"; then
                               enable_introspection=no
                             else
                               AC_MSG_ERROR([gobject-introspection is not available])
                             fi
                          ])
        if test "x$enable_introspection" = "xyes" ; then
          AC_DEFINE([WITH_GOBJECT_INTROSPECTION], [1], [enable GObject introspection support])
          AC_SUBST(GOBJECT_INTROSPECTION_CFLAGS)
          AC_SUBST(GOBJECT_INTROSPECTION_LIBS)
          AC_SUBST([G_IR_SCANNER], [$($PKG_CONFIG --variable=g_ir_scanner gobject-introspection-1.0)])
          AC_SUBST([G_IR_COMPILER], [$($PKG_CONFIG --variable=g_ir_compiler gobject-introspection-1.0)])
        fi
fi
AM_CONDITIONAL([WITH_GOBJECT_INTROSPECTION], [test "x$enable_introspection" = "xyes"])
</pre>
<p>
The next step is to add Makefile.am rules to extract the introspection data. This is a two step process, the first step runs <code>g-ir-scanner</code> across all the source code and the actual compiled binary / library to generate a <code>.gir</code> file.  This is an XML representation of the introspection data. The second step runs <code>g-ir-compiler</code> to turn the XML data into a machine usable binary format so it can be efficiently accessed. When running <code>g-ir-scanner</code> on a binary, as opposed to a library, it is necessary for that binary to support an extra command line flag called <code>--introspect-dump</code>. I add this code the main.c source file to support that
</p>
<pre>
#if WITH_GOBJECT_INTROSPECTION
    static gchar *introspect = NULL;
#endif

    static const GOptionEntry entries[] = {
        ...snip other options...
#if WITH_GOBJECT_INTROSPECTION
        { "introspect-dump", 'i', 0, G_OPTION_ARG_STRING, &#038;introspect;, "Dump introspection data", NULL },
#endif
        { NULL, 0, 0, 0, NULL, NULL, NULL },
    };

    ...parse command line args...

#if WITH_GOBJECT_INTROSPECTION
    if (introspect) {
        g_irepository_dump(introspect, NULL);
        return 0;
    }
#endif
</pre>
<p>
Back to the Makefile.am rules. <code>g-ir-scanner</code> has quite a few arguments you need to set. The <code>--include</code> args provide the names of introspection metadata files for any libraries depended on. The <code>-I</code> args provide the CPP include paths to the application&#8217;s header files. The <code>--pkg</code> args provide the names of any <code>pkg-config</code> files that code builds against. There are a few others too which I won&#8217;t cover &#8211; they&#8217;re all in the man page. The upshot is that the Makefile.am gained rules
</p>
<pre>
if WITH_GOBJECT_INTROSPECTION
Capa-0.1.gir: capa $(G_IR_SCANNER) Makefile.am
        $(G_IR_SCANNER) -v \
                --namespace Capa \
                --nsversion 0.1 \
                --include GObject-2.0 \
                --include Gtk-2.0 \
                --include GPhoto-2.0 \
                --program=$(builddir)/capa \
                --add-include-path=$(srcdir) \
                --add-include-path=$(builddir) \
                --output $@ \
                -I$(srcdir)/backend \
                -I$(srcdir)/frontend \
                --verbose \
                --pkg=glib-2.0 \
                --pkg=gthread-2.0 \
                --pkg=gdk-pixbuf-2.0 \
                --pkg=gobject-2.0 \
                --pkg=gtk+-2.0 \
                --pkg=libgphoto2 \
                --pkg=libglade-2.0 \
                --pkg=hal \
                --pkg=dbus-glib-1 \
                $(libcapa_backend_la_SOURCES:%=$(srcdir)/%) \
                $(libcapa_frontend_la_SOURCES:%=$(srcdir)/%) \
                $(capa_SOURCES:%=$(srcdir)/%)

girdir = $(datadir)/gir-1.0
gir_DATA = Capa-0.1.gir

typelibsdir = $(libdir)/girepository-1.0
typelibs_DATA = Capa-0.1.typelib

%.typelib: %.gir
        g-ir-compiler \
                --includedir=$(srcdir) \
                --includedir=$(builddir) \
                -o $@ $<

CLEANFILES += Capa-0.1.gir $(typelibs_DATA)

endif # WITH_GOBJECT_INTROSPECTION
</pre>
<p>
After making those changes &#038; rebuilding, it is wise to check the <code>.gir</code> file, since the <code>g-ir-scanner</code> doesn't always get everything correct. It may be necessary to <a href="http://live.gnome.org/GObjectIntrospection/Annotations">provide annotations</a> in the source files to help it out. For example, it got object ownership wrong on some getters, requiring annotations n the return values such as
</p>
<pre>
/**
 * capa_app_get_plugin_manager: Retrieve the plugin manager
 *
 * Returns: <strong>(transfer none):</strong> the plugin manager
 */
</pre>
<p>
The final step was add rules to the RPM specfile, which are fairly self-explanatory
</p>
<pre>
%define with_introspection 0

%if 0%{?fedora} >= 12
%define with_introspection 1
%endif
%if 0%{?rhel} >= 6
%define with_introspection 1
%endif

%if %{with_introspection}
BuildRequires: gobject-introspection-devel
BuildRequires: gir-repository-devel
%endif

%prep
....
%if %{with_introspection}
%define introspection_arg --enable-introspection
%else
%define introspection_arg --disable-introspection
%endif

%configure %{introspection_arg}

%files
....
%if %{with_introspection}
%{_datadir}/gir-1.0/Capa-0.1.gir
%{_libdir}/girepository-1.0/Capa-0.1.typelib
%endif
</pre>
<p>
That is all. The entire API is now accessible from Perl, JavaScript, Python without ever having written a line of code for those languages. It is also possible to generate a .jar file to make it accessible from Java.
</p>
<h2>Adding support for a JavaScript plugin engine</h2>
<p>
Since the API is now accessible from JavaScript, adding a JavaScript plugin engine ought to be easy at this point. There are in fact 2 competing JavaScript engines supporting GObject introspection, <a href="http://live.gnome.org/Gjs">Gjs</a> and <a href="http://live.gnome.org/Seed">Seed</a>. Seed looks more advanced, documented &#038; polished, but Gjs was what's in Fedora currently, so I used that. Again the first step was checking for it in configure.ac
</p>
<pre>
AC_ARG_WITH([javascript],
      AS_HELP_STRING([--with-javascript],[enable JavaScript plugins]),
      [], [with_javascript=check])

if test "x$with_javascript" != "xno" ; then
  if test "x$enable_introspection" = "xno" ; then
    if test "x$with_javascript" = "xyes"; then
      AC_MSG_ERROR([gobject-introspection is requird for javascript plugins])
    fi
  fi

  PKG_CHECK_MODULES(GJS, gjs-1.0 &gt;= $GJS_REQUIRED)
  AC_SUBST(GJS_CFLAGS)
  AC_SUBST(GJS_LIBS)

  PKG_CHECK_MODULES(GJS_GI, gjs-gi-1.0 &gt;= $GJS_REQUIRED)
  AC_SUBST(GJS_GI_CFLAGS)
  AC_SUBST(GJS_GI_LIBS)

  with_javascript=yes
  AC_DEFINE([WITH_JAVASCRIPT], [1], [enable JavaScript plugins])
fi
AM_CONDITIONAL([WITH_JAVASCRIPT], [test "x$with_javascript" = "xyes"])
</pre>
<p>
I won't go into any details on the way Capa scans for plugins (it uses $HOME/.local/share/capa/plugins/
<plugin-name>/main.js), merely illustrate how to execute a plugin once it has been located. The important object in the Gjs API is <code>GjsContext</code>, providing the execution context for the javascript code. It is possible to have multiple contexts, so each plugin is independent and potentially able to be sandboxed.  The JavaScript file to be invoked is <code>main.js</code><code> in the plugin's base directory. The first step is to setup the context's search path to point to the plugin base directory:<br />
</code></plugin-name></p>
<pre>
void runplugin(const gchar *plugindir) {
    const gchar *searchpath[2];
    GjsContext *context;

    searchpath[0] = plugindir;
    searchpath[1] = NULL;

    context = gjs_context_new_with_search_path((gchar **)searchpath);
</pre>
<p>
The context is now ready to execute some javascript code. The Capa plugin system expects the <code>main.js</code> file to contain a method called <code>activate</code>. To start the plugin, we can thus simply evaluate <code>const Main = imports.main; Main.activate();</code>
</p>
<pre>
   const gchar *script = "const Main = imports.main; Main.activate();";

   gjs_context_eval(context,
                     script,
                     -1,
                     "main.js",
                     &status;,
                     NULL);

   if (status !=0) {
     fprintf(stderr, "Loading plugin failed\n");
   }
</pre>
<p>
Presto, you now have a javascript plugin running, having written no JavaScript at any point in the process. There is one slight issue in this though - how does the plugin get access to the application instance ? One way would be to provide a static method in your API to get hold of the application's main object, but I really wanted to pass the object into the plugin's <code>activate</code> method. This is where I hit Gjs's limitations - there appears to be no official API to set any global variable except for <code>ARGV</code>. After much poking around in the Gjs code though I discovered an exported method, which wasn't in the header files
</p>
<pre>
JSContext* gjs_context_get_context(GjsContext *js_context);
</pre>
<p>
And decided to (temporarily) abuse that until a better way could be found. I have an object instance of the <code>CapaApp</code> class which I wanted to pass into the <code>activate</code> method. The first step was to set this in the global namespace of the script being evaluated. Gjs comes with an API for converting a GObject instance into a JSObject instance which the runtime needs. Thus I wrote a simple helper
</p>
<pre>
static void set_global(GjsContext *context,
                       const char *name,
                       GObject *value)
{
    JSContext *jscontext;
    JSObject *jsglobal;
    JSObject *jsvalue;

    jscontext = gjs_context_get_context(context);
    jsglobal = JS_GetGlobalObject(jscontext);
    JS_EnterLocalRootScope(jscontext);
    jsvalue = gjs_object_from_g_object(jscontext, value);
    JS_DefineProperty(jscontext, jsglobal,
                      name, OBJECT_TO_JSVAL(jsvalue),
                      NULL, NULL,
                      JSPROP_READONLY | JSPROP_PERMANENT);
    JS_LeaveLocalRootScope(jscontext);
}
</pre>
<p>
There was one little surprise in this though. The <code>gjs_object_from_g_object</code> method will only succeed if the current Gjs context has the introspection data for that object loaded. So it was necessary to import my application's introspection data by eval'ing <code>const Capa = imports.gi.Capa</code>. That done, it was now possible to pass variables into the plugin. The complete revised plugin loading code looks like
</p>
<pre>
void runplugin(CapaApp *application, const gchar *plugindir) {
    const gchar *script = "const Main = imports.main; Main.activate(app);";
    const gchar *searchpath[2];
    GjsContext *context;

    searchpath[0] = plugindir;
    searchpath[1] = NULL;

    context = gjs_context_new_with_search_path((gchar **)searchpath);

    gjs_context_eval(context,
                     "const Capa = imports.gi.Capa",
                     -1,
                     "dummy.js",
                     &status;,
                     NULL);

    set_global(context, plugin, "app", application);

    gjs_context_eval(context,
                     script,
                     -1,
                     "main.js",
                     &status;,
                     NULL);

    if (status !=0) {
      fprintf(stderr, "Loading plugin failed\n");
    }
</pre>
<p>
This code is slightly simplified, omitting error handling, for purposes of this blog post, but <a href="http://gitorious.org/capa/capa/blobs/master/src/backend/capa-plugin-javascript.c">the real thing</a> is not much harder. Looking at the code again, there is really very little (if anything) about the code which is specific to my application. It would be quite easy to pull out the code which finds &#038; loads plugins into a library (eg "libgplugin"). This would make it possible for any existing GTK applications to be retrofitted with support plugins simply by generating introspection data for their internal APIs, and then instantiating a "PluginManager" object instance.
</p>
<p>
In summary, GObject Introspection is an incredibly compelling addition to GLib. With a mere handful of additions to <code>configure.ac</code> and <code>Makefile.am</code>, it completely solves "language bindings" problem for you. I'd go as far as to say that this is a single most compelling reason to write any new C libraries using GLib/GObject. Furthermore if there are existing C libraries not using GObject, then provide a GObject wrapper for them as a top priority. Don't ever write or auto-generate a language binding again.  Writing GTK applications either entirely in JavaScript, or in a mix of C + JavaScript plugins is also a really nice development, avoiding the issue of "clashing runtime environments" seen when using Python + GTK. The Gjs/Seed/GObject developers deserve warm praise for these great enhancements.</p>
]]></content:encoded>
			<wfw:commentRss>http://berrange.com/posts/2010/01/10/using-gobject-introspection-gjs-to-provide-a-javascript-plugin-engine/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Following gphoto SVN development with GIT</title>
		<link>http://berrange.com/posts/2010/01/10/following-gphoto-svn-development-with-git/</link>
		<comments>http://berrange.com/posts/2010/01/10/following-gphoto-svn-development-with-git/#comments</comments>
		<pubDate>Sun, 10 Jan 2010 18:25:00 +0000</pubDate>
		<dc:creator>Daniel Berrange</dc:creator>
				<category><![CDATA[Entangle]]></category>

		<guid isPermaLink="false">http://wordpress.berrange.com/?p=6</guid>
		<description><![CDATA[Since I started developing the Capa photo capture application, I&#8217;ve been following development of gphoto much more closely. Unfortunately gphoto is using subversion for source control. There are many things wrong with subversion in comparison to modern SCM systems like Mercurial or GIT. In this particular case though, the main problem is speed, or lack [...]]]></description>
			<content:encoded><![CDATA[<p>
Since I started developing the <a href="http://capa-project.org">Capa photo capture</a> application, I&#8217;ve been following development of <a href="http://gphoto.org">gphoto</a> much more closely. Unfortunately gphoto is using subversion for source control. There are many things wrong with subversion in comparison to modern SCM systems like Mercurial or GIT. In this particular case though, the main problem is speed, or lack thereof. gphoto uses <a href="http://sourceforge.net">sourceforge</a> as its hosting service and sf.net subversion servers are slower than you can possibly imagine. As an example, run &#8216;svn log&#8217; to browse changes and you&#8217;ll be waiting 30 seconds for it to even start to give you an answer. Then run &#8216;svn diff&#8217; to look at the contents of a change and you&#8217;ll be waiting another 30 seconds or more. Totally unacceptable. Once you&#8217;ve used a distributed SCM system like Mercurial or GIT, you cease to have tolerance for any operations which take longer than a 2-3 seconds.
</p>
<p>
Fortunately, GIT has the ability to checkout directly from SVN repository. The gphoto SVN repository actually contains many separate sub-projects in it and I didn&#8217;t want to import them all to my local GIT repository. This meant I couldn&#8217;t make use of the branch / tag tracking support directly and had todo things the long way. The good news is that the long way has already <a href="http://www.dmo.ca/blog/20070608113513/">been blogged about</a> and it isn&#8217;t hard.
</p>
<p>
There were two projects I was interested in getting, libgphoto (the main library) &amp; gphoto (the command line frontend) and I wanted each to end up in their own GIT repository. For both, I wanted the trunk and 2.4.x branch. Starting with gphoto, since it has much less history, the first step was to clone the trunk
</p>
<pre>
# git svn clone https://gphoto.svn.sourceforge.net/svnroot/gphoto/trunk/gphoto2 gphoto2
</pre>
<p>
This takes a fairly long time because it pulls down every single SVN changeset in the repository. Once that&#8217;s complete though, the .git/config contains
</p>
<pre>
[svn-remote "svn"]
        url = https://gphoto.svn.sourceforge.net/svnroot/gphoto/trunk/gphoto2
        fetch = :refs/remotes/git-svn
</pre>
<p>
And the local &#8216;master&#8217; branch is connected to the &#8216;git-svn&#8217; remote.
</p>
<pre>
$ git branch -a
* master
  remotes/git-svn
</pre>
<p>
Anytime further changes are made in the SVN repository, those can be pulled down to the local GIT repository using <code>git svn fetch git-svn</code>. At this point it is possible to add in the branches. Simply edit the <code>.git/config</code> file and add another &#8216;svn-remote&#8217; entry, this time pointing at the branch path.
</p>
<pre>
[svn-remote "svn24"]
        url = https://gphoto.svn.sourceforge.net/svnroot/gphoto/branches/libgphoto2-2_4/gphoto2
        fetch = :refs/remotes/git-svn-2.4
</pre>
<p>
And then pull down all the changes for that branch, and create a local branch for this
</p>
<pre>
# git svn fetch svn24
# git checkout -b v2.4 git-svn-2.4
</pre>
<p>
This leaves a local branch &#8216;v2.4&#8242; and a remote branch &#8216;git-svn-2.4&#8242;
</p>
<pre>
$ git branch -a
  master
* v2.4
  remotes/git-svn
  remotes/git-svn-2.4
</pre>
<p>
That takes care of the <code>gphoto2</code> frontend command line app codebase. It is then a simply matter to repeat the same thing substituting <code>libgphoto2</code> into the SVN paths to checkout the library codebase. Though this takes a little longer because it has much much more history. This little upfront pain to clone the SVN repo to GIT will be paid back many hundreds of times over thanks to the speed that GIT brings to SCM operation.
</p>
<p>
The moral of the story is simple: Don&#8217;t ever choose subversion. If you have the choice, use GIT. If you don&#8217;t have the choice, then mirror SVN to GIT anyway.
</p>
<p>
<strong>Edit:</strong> One thing I forgot to mention is that after setting up all branches, run a <code>git gc</code> on the repo. This will dramatically reduce the disk usage &#038; speed up GIT operations further
</p>
<pre>
$ du -h -c -s .
45M .
45M total
$ git gc
Counting objects: 3695, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3663/3663), done.
Writing objects: 100% (3695/3695), done.
Total 3695 (delta 3081), reused 0 (delta 0)
$ du -h -c -s .
5.0M .
5.0M total
</pre>
<p>
Going from 45 MB to 5 MB is quite impressive !</p>
]]></content:encoded>
			<wfw:commentRss>http://berrange.com/posts/2010/01/10/following-gphoto-svn-development-with-git/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Capa: a desktop application for photo capture via a digital camera</title>
		<link>http://berrange.com/posts/2009/12/21/capa-a-desktop-application-for-photo-capture-via-a-digital-camera/</link>
		<comments>http://berrange.com/posts/2009/12/21/capa-a-desktop-application-for-photo-capture-via-a-digital-camera/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 12:25:00 +0000</pubDate>
		<dc:creator>Daniel Berrange</dc:creator>
				<category><![CDATA[Entangle]]></category>

		<guid isPermaLink="false">http://wordpress.berrange.com/?p=9</guid>
		<description><![CDATA[A couple of months ago I attended an LPMG event on the subject of off-camera flash. The talk was quite interactive with the presenters using a wide array of camera and flash equipment on stage to demonstrate the techniques they were covering. The cameras were connected to a laptop, in turn connected to a projector, [...]]]></description>
			<content:encoded><![CDATA[<p>
A couple of months ago I attended an <a href="http://www.lpmg.org.uk">LPMG</a> event on the subject of <a href="http://www.meetup.com/lpmg-org-uk/calendar/10939555/">off-camera flash</a>. The talk was quite interactive with the presenters using a wide array of camera and flash equipment on stage to demonstrate the techniques they were covering. The cameras were connected to a laptop, in turn connected to a projector, allowing the audience to view the photos on the big screen as soon as they were captured.
</p>
<p>
I&#8217;m not entirely certain, but I believe the presenters were using <a href="http://imaging.nikon.com/products/imaging/lineup/software/control_pro2/index.htm">Nikon Camera Control Pro</a> on the laptop for control of the digital SLR. Watching it, I couldn&#8217;t help wondering if it was possible to do remote camera control &amp; capture on a Linux laptop using only open source software. After a short investigation I discovered that, in addition to its image file download/management capabilities, <a href="http://gphoto.org/">gphoto</a> allows for triggering the shutter and changing settings on digital cameras. Applications providing graphical frontends to gphoto though, only appeared to expose its image file download/management capabilities. Thus decided to write a graphical frontend myself. I&#8217;m calling it <a href="http://capa-project.org/">Capa</a>
</p>
<p>
Before continuing with more wordy stuff, here is what everyone is really wanting, a screenshot<br />
<a href="http://capa-project.org/screenshots.html"><img width="500" src="http://capa-project.org/screenshot-camera-manager.png" /></a>
</p>
<p>
The goal of the Capa application is to provide a simple and efficient interface for tethered shooting and controlling camera settings. It will leave all file management tasks to other applications such as the gphoto plugins for GVFS or FUSE. The two main libraries on which the application is built are <a href="http://gphoto.org">gphoto</a> and <a href="http://gtk.org">GTK</a>. The source code is being licensed under the terms of the GPLv3+
</p>
<p>
The code is at a very early stage of development with no formal releases yet, but it is at the point where it might be useful to people beyond myself, hence this blog posting. At this point it is capable of either triggering the camera shutter directly, or event monitoring where it detects photos shot on the camera. In both cases it will immediately download and display all photos. When a new image is detected it will be immediately downloaded &#038; displayed. The images are not left on the memory card. The current <em>session</em> defines a directory on the host computer where all images are saved, defaulting to a directory under $HOME/Pictures (or wherever your XDG preferences point). The UI for changing tunable settings is rather crude. If you&#8217;re lucky it may work, but don&#8217;t count on it yet :-)
</p>
<p>
The interface is fully colour management aware. It is capable of automatically detecting the monitor&#8217;s current configured ICC profile in accordance with the <a href="http://www.burtonini.com/computing/x-icc-profiles-spec-latest.html">X11 ICC profile specification</a>. All images displayed by the application, whether full size or as thumbnails, will have the necessary colour profile transformation applied. <a href="http://projects.gnome.org/gnome-color-manager/">GNOME Colour Manager</a> is an excellent new app for configuring your display profiles in the necessary manner for them to work with Capa. Integration with HAL allows immediate automatic detection of any newly plugged in USB cameras and similar support for UDev is planned.
</p>
<p>
In the very near future it is intended that <a href="http://live.gnome.org/GObjectIntrospection">GObject introspection</a> and <a href="http://live.gnome.org/Gjs">GJS</a> will be used to support a JavaScript plugin engine. The codebase has a strict separation between its object model and UI model specifically designed to facilitate plugins. This will allow end user customization &#038; scripting of the UI to best suit their needs. For example, timer triggered shooting, motion detection and many other neat ideas could be provided via plugins.
</p>
<p>
For a little more information visit the <a href="http://capa-project.org/">Capa website</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://berrange.com/posts/2009/12/21/capa-a-desktop-application-for-photo-capture-via-a-digital-camera/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

