<?xml version="1.0"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">

  <channel>
    <title>Woohoo</title>
    <link>http://abandonedwig.info</link>
    <atom:link href="http://abandonedwig.info/blog/rss.xml" rel="self" type="application/rss+xml" />
    <description>Abandoned Wig blog</description>
    <language>en-us</language>
    <pubDate>Mon, 25 Feb 2013 19:56:21 EST</pubDate>
    <lastBuildDate>Mon, 25 Feb 2013 19:56:21 EST</lastBuildDate>

    
    
      <item>
        <title>Edge-distance anti-aliasing</title>
        <link>http://abandonedwig.info/blog/2013/02/24/edge-distance-anti-aliasing.html</link>
        <pubDate>Sun, 24 Feb 2013 00:00:00 EST</pubDate>
        <name>Martin Robinson (Martin Robinson)</name>
        <guid>http://abandonedwig.info/blog/2013/02/24/edge-distance-anti-aliasing.html</guid>
        <description>&lt;p&gt;(You might want to go &lt;a href='http://abandonedwig.info/edge-distance-anti-aliasing/demo.html'&gt;straight to the demo&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Some months ago, I noticed that the &lt;a href='http://src.chromium.org/viewvc/chrome/trunk/src/cc/'&gt;Chromium compositor&lt;/a&gt;, the code which powers Chromium&amp;#8217;s accelerated compositing implementation (and also &lt;a href='http://code.google.com/p/chromium/wiki/Aura'&gt;Aura!&lt;/a&gt;) was anti-aliasing layer edges. This was especially surprising to me since I knew for a fact that my hardware didn&amp;#8217;t support &lt;a href='http://en.wikipedia.org/wiki/Multisample_anti-aliasing'&gt;multisample anti-aliasing&lt;/a&gt; yet. Some people from the Chromium graphics team, who are incredibly friendly and helpful, pointed me to a very clever bit of code they were using to do edge-distance anti-aliasing for composited layers.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://en.wikipedia.org/wiki/Aliasing'&gt;Aliasing&lt;/a&gt; can happen when you sample a signal that has details that cannot be captured by your sample frequency. In the case of graphics, it&amp;#8217;s what happens when features of the image exist in an area smaller than a pixel. One important feature is the edge of a piece of geometry, such as the edge of a shape drawn onto the page. When you start rotating shapes and projecting them with 3D CSS transforms, geometry that before aligned to pixel boundaries can move to the spaces between pixel boundaries.&lt;/p&gt;

&lt;p&gt;For instance, let&amp;#8217;s zoom into the edge of triangle that we are rendering. Maybe in this case it&amp;#8217;s half of a rotated div.&lt;/p&gt;

&lt;p&gt;&lt;img alt='A polygon without anti-aliasing' src='http://abandonedwig.info/edge-distance-anti-aliasing/no-antialiasing-final.png' /&gt;&lt;/p&gt;

&lt;p&gt;If we naively decided the color of every pixel based on whether any of the triangle covered it at all, we&amp;#8217;d end up with a jagged edge.&lt;/p&gt;

&lt;p&gt;One thing we could do to make the edge smooth is to determine how much area of the pixel is covered by the triangle. We could adjust the transparency of the shape color (the alpha value) by that percentage when painting the pixel. This process is a type of &lt;i&gt;anti-aliasing&lt;/i&gt; and the percentage that the triangle covers the pixel is called &lt;i&gt;coverage&lt;/i&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img alt='A polygon with anti-aliasing' src='http://abandonedwig.info/edge-distance-anti-aliasing/antialiasing-final.png' /&gt;&lt;/p&gt;

&lt;p&gt;Think of all the complicated geometric calculations we&amp;#8217;d have to do to figure out the ratio exactly. Since we have to make these calculations for every pixel up to 60 times per second (for smooth animations), our rendering would be pretty slow if we actually did them! Instead, it&amp;#8217;d be nice if we could somehow estimate how much of the pixel is covered and do less work. One approach is to calculate the distance from the pixel to the edge of the shape. If the pixel is more than one pixel&amp;#8217;s distance away from the edge, we know that we should not paint the triangle color at all. If the pixel is closer than one one pixel&amp;#8217;s distance from the edge, we should paint the triangle color, but reduced by some transparency factor.&lt;/p&gt;

&lt;p&gt;Luckily, OpenGL can run a little program for every pixel &lt;a href='#fn1'&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; it paints. This program is called a fragment shader. We can write up this logic in the fragment shader and change the triangle color for every pixel.&lt;/p&gt;

&lt;p&gt;Perhaps some of those reading who have had experience with OpenGL may notice here that this isn&amp;#8217;t going to work as I&amp;#8217;ve described. OpenGL already does something like the naive approach I talked about first. Some pixels (the ones OpenGL decided should be painted with the triangle color), will be properly anti-aliased, but many pixels will not be painted at all. For instance, if the coverage of the pixel is only 20% and OpenGL decided not to paint it, we wouldn&amp;#8217;t even have a chance to determine how far it was from the triangle edge, because the fragment shader wouldn&amp;#8217;t run for those missing pixels.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s &amp;#8220;trick&amp;#8221; OpenGL into painting more pixels than it would otherwise. A simple way to do this is to just make the triangle a little bit bigger. In fact, we can expand all the edges by less than one pixel and OpenGL will paint all those missing pixels. Now we have smooth edges!&lt;/p&gt;

&lt;p&gt;&lt;img alt='Expanding the drawing area' src='http://abandonedwig.info/edge-distance-anti-aliasing/antialiasing-final-expanded.png' /&gt;&lt;/p&gt;

&lt;p&gt;I spent some time implementing this for the TextureMapper accelerated compositor (and thus WebKitGTK+), so it&amp;#8217;s not just the Chromium compositor that has this feature any longer. For me it makes a huge difference in the quality of 3D CSS content. For the purposes of demonstration, I&amp;#8217;ve also reimplemented it in WebGL, so if you have a modern browser you can &lt;a href='http://abandonedwig.info/edge-distance-anti-aliasing/demo.html'&gt;see it in action&lt;/a&gt;.&lt;/p&gt;
&lt;a href='http://abandonedwig.info/edge-distance-anti-aliasing/demo.html'&gt;&lt;img alt='A screenshot of the edge-distance anti-aliasing demo' src='http://abandonedwig.info/edge-distance-anti-aliasing/demo.png' /&gt;&lt;/a&gt;&lt;ol class='footnotes'&gt;
     &lt;li&gt;&lt;a name='fn1' /&gt; Fragments and pixels are actually different things, but I'm glossing over this difference for the sake of simplicity.&lt;/li&gt;
&lt;/ol&gt;</description>
      </item>
    
    
    
      <item>
        <title>Accelerated compositing update</title>
        <link>http://abandonedwig.info/blog/2012/07/07/accelerated-compositing-update.html</link>
        <pubDate>Sat, 07 Jul 2012 00:00:00 EDT</pubDate>
        <name>Martin Robinson (Martin Robinson)</name>
        <guid>http://abandonedwig.info/blog/2012/07/07/accelerated-compositing-update.html</guid>
        <description>&lt;div class='post'&gt;
I believe it's past time to break the silence here, so what follows is a short update on the progress we've made at &lt;a href=&quot;http://igalia.com/&quot;&gt;Igalia&lt;/a&gt; toward 3D CSS transforms and hardware accelerated animation in WebKitGTK+ (otherwise known as accelerated compositing). I'm happy to say that both the initial WebKit1 and WebKit2 implementation of this work have &lt;a href=&quot;https://bugs.webkit.org/show_bug.cgi?id=86037&quot;&gt;finally landed&lt;/a&gt;, and you can try it out now in the latest unstable releases. Epiphany in Gnome 3.6 will include accelerated compositing (smooth animations and fast WebGL), a port to the brand new WebKit2GTK+ API (stability and security), and a new interface. It's quite pleasant to watch the progress of my own &lt;a href=&quot;http://neugierig.org/software/chromium/notes/2012/02/the-end.html&quot;&gt;rounding error&lt;/a&gt; as each day it continues transforming into a modern browser.&lt;br /&gt;&lt;br /&gt;There were some interesting design choices to make when implementing accelerated compositing in WebKit2. Ports typically choose one of two possibilities for where to actually composite the content of page layers. The first and simplest path, taken by the GTK+ and Mac ports is to do all GPU composition in the WebProcess, which the same process that renders the layer content. This is by far the simplest and most straight-forward path, as WebKit does not have to send bitmap and layer data across the process boundary. The Qt and EFL ports have chosen to do composition in the UIProcess, which is the process that controls the user interface components surrounding the page content. From what I understand, this more complex design is an attempt to lower the latency of touch events and to decrease the number of OpenGL context switches. It's unclear now what the best approach is for browsers on embedded systems, but composition in the WebProcess works quite well for Epiphany at the moment.&lt;br /&gt;&lt;br /&gt;During this development cycle we'll continue to improve the implementation of accelerated compositing, but we hope to start looking at other rendering and interactivity improvements such as accelerated canvas, a tiled backing store, touch event handling and a threaded scrolling implementation.&amp;nbsp;&lt;span style=&quot;background-color: white;&quot;&gt;I'm most excited about accelerated canvas, because of the work we've been doing recently on Cairo GL. The GL backend of Cairo has been experimental for some time and isn't widely distributed, but recently there's been &lt;/span&gt;&lt;a href=&quot;http://code.google.com/p/cairogles/&quot; style=&quot;background-color: white;&quot;&gt;an attempt&lt;/a&gt;&lt;span style=&quot;background-color: white;&quot;&gt; to increase its performance and to make it more suitable for embedded platforms.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Once we integrate Cairo GL with our accelerated compositing architecture in WebKitGTk+, canvas content can be rasterized directly on the GPU instead of the CPU. For most systems accelerated canvas means better performance and lower power usage. Hopefully, I can land the patches to enable this as early as Gnome 3.6, but I'm still not sure when the OpenGL backend in Cairo will be officially supported. This means that, for the moment at least, you'll need to compile Cairo yourself to test accelerated canvas.&lt;/div&gt;
</description>
      </item>
    
    
    
      <item>
        <title>WebKitGTK+ hackfest wrapup: accelerated compositing</title>
        <link>http://abandonedwig.info/blog/2011/12/08/webkitgtk-hackfest-wrapup-accelerated.html</link>
        <pubDate>Thu, 08 Dec 2011 00:00:00 EST</pubDate>
        <name>Martin Robinson (Martin Robinson)</name>
        <guid>http://abandonedwig.info/blog/2011/12/08/webkitgtk-hackfest-wrapup-accelerated.html</guid>
        <description>&lt;div class='post'&gt;
I just returned from this year's&amp;nbsp;&lt;a href=&quot;http://live.gnome.org/Hackfests/WebKitGTK2011&quot;&gt;WebKitGTK+ hackfest&lt;/a&gt;. Not only was it the most productive hackfest to date, the diversity of the people involved was incredible. Attendees included hackers from Igalia, Collabora, RedHat and Motorola. It's great to be part of a company which can pull this kind of event together.&lt;br /&gt;&lt;br /&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: left; margin-right: 1em; position: static; text-align: left; z-index: auto;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;a href=&quot;http://www.flickr.com/photos/mariosp/6429999491/in/photostrea&quot;&gt;&lt;img alt=&quot;WebKitGTK+ 2011 Hackfest&quot; height=&quot;160&quot; src=&quot;http://farm8.staticflickr.com/7035/6429999491_82a5d7d58e_m.jpg&quot; width=&quot;240&quot; /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://www.flickr.com/photos/mariosp/6429999491/in/photostream&quot;&gt;Planning&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&amp;nbsp;One of the things different about this hackfest were the &lt;a href=&quot;http://en.wikipedia.org/wiki/Birds_of_a_feather_(computing)&quot;&gt;BoFs&lt;/a&gt;, which were mainly planning sessions. The WebKitGTK+ community has shifted from a ragtag group of developers unafraid of &lt;tt&gt;g_object_ref&lt;/tt&gt; and &lt;tt&gt;g_object_unref&lt;/tt&gt; furiously hacking on a tiny WebKit port to an integral piece of the Gnome renaissance moving steadily toward ambitious goals. I'm obviously biased, but I believe the investment of small companies with strong ideals like &lt;a href=&quot;http://igalia.com/&quot;&gt;Igalia&lt;/a&gt; and &lt;a href=&quot;http://collabora.co.uk/&quot;&gt;Collabora&lt;/a&gt; is directly responsible.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;Others have already reported on &lt;a href=&quot;http://blogs.igalia.com/juanjo/2011/12/04/webkitgtk-hackfest-wrap-up/&quot;&gt;some of the incredible work&lt;/a&gt; at the hackfest including the &lt;a href=&quot;http://blogs.gnome.org/xan/2011/12/04/a-new-design-for-epiphany-web/&quot;&gt;bold new Epiphany redesign&lt;/a&gt;, &lt;a href=&quot;http://blogs.igalia.com/mario/2011/12/06/webkitgtk-hackfest-wk2-a11y-and-ephiphanys-ad-blocker/&quot;&gt;accessibility support for WebKit2&lt;/a&gt;, and &lt;a href=&quot;http://blog.kov.eti.br/?p=223&quot;&gt;JHBuild-ification&lt;/a&gt;. I'd like to talk a bit about something in which I'm personally involved: &lt;a href=&quot;http://www.chromium.org/developers/design-documents/gpu-accelerated-compositing-in-chrome&quot;&gt;accelerated compositing&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;float: right; margin-left: 1em; position: relative; text-align: right; z-index: 0;&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;&quot;&gt;&lt;a href=&quot;http://live.gnome.org/Design/Apps/Web&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;240&quot; src=&quot;http://blogs.gnome.org/xan/files/2011/12/web-overview.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;http://live.gnome.org/Design/Apps/Web&quot;&gt;Epiphany's new look&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Accelerated compositing was introduced in 2009 with the bulk of the work provided by Apple and Google. GPUs are quite fast, but because of the overhead of moving bits from main main memory to GPU memory, &lt;a href=&quot;https://plus.google.com/105051985738280261832/posts/2FXDCz8x93s&quot;&gt;you need to use them intelligently to see any speedup&lt;/a&gt;. Accelerated compositing is the smarts needed to use the GPU intelligently in WebKit. We're also trying to push these smarts down into painting libraries such as &lt;a href=&quot;http://cairographics.org/OpenGL/&quot;&gt;Cairo&lt;/a&gt; and &lt;a href=&quot;http://code.google.com/p/skia/wiki/GrContext&quot;&gt;Skia&lt;/a&gt;, but that's a more difficult task, with less immediate benefit. The best performance improvements come from using the GPU at the place that maintains the drawing state.&lt;br /&gt;&lt;br /&gt;In the context of WebKit, drawing state is the rendered page itself, with all its layered divs, canvas elements, video tags and WebGL contexts. WebKit stores elements to render in a data structure called the &quot;&lt;a href=&quot;http://www.webkit.org/blog/114/webcore-rendering-i-the-basics/&quot;&gt;render tree&lt;/a&gt;.&quot; Members of the the render tree which are drawn in main memory must be sent to the GPU to be displayed on the screen. Furthermore, some of these elements may be rendered on the GPU itself, so ideally we want to avoid copying them to main memory only to copy them back to the GPU at a later stage.&lt;br /&gt;&lt;br /&gt;CPUs are very fast, so it's often sufficient to rasterize things into main memory. On the other hand, when the entire page is rendered by the CPU, it spends a lot of time doing &quot;boring&quot; tasks that the GPU loves doing, such as compositing (blending images into each other). Accelerated compositing attacks this by slicing the page into layers of related content. The way this slicing works is a heuristic, but generally speaking divs at the same z-index, with the same CSS transform, WebGL contexts and hardware accelerated video are their own layer. It renders each of the non-GPU layers into an image and then uploads all the images to be composited by the GPU along with layers that are already there.&lt;br /&gt;&lt;br /&gt;Collabora, which created the Clutter port of WebKit has an implementation of accelerated compositing using Clutter. At the hackfest, Joone Hurr and Gustavo Noronha Silva started integrating this version into WebKitGTK+. The nice thing about the Clutter implementation is that it's almost complete. The unfortunate thing is that Clutter uses COGL which has very poor support for using raw OpenGL in the application. Obviously this means that the WebKitGTK+ port would need to rewrite it's WebGL backend. Igalia is also working on two implementations (OpenGL and the Cairo fallback) using No'am Rosenthal's very nice TextureMapper abstraction.&lt;br /&gt;&lt;br /&gt;During the hackfest, we decided to attempt to integrate all three approaches into the tree. The Clutter version is a nice stopgap for people who want to play with accelerated compositing or are using Clutter already. The intial parts of this implementation should be landing soon. Over the next few months we'll also be submitting OpenGL and Cairo versions of accelerated compositing. We already made great progress at the hackfest. If you're interested in following the work, you can follow the &lt;a href=&quot;https://bugs.webkit.org/show_bug.cgi?id=74087&quot;&gt;accelerated compositing metabug&lt;/a&gt;.&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://foundation.gnome.org/&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://www.gnome.org/wp-content/themes/gnome-grass/images/gnome-logo.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://igalia.com/&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://3.bp.blogspot.com/-T1wYSHpQsiQ/TuDcfC9AmXI/AAAAAAAAASY/oii41HDU3tA/s1600/igalia.png.4KFG6V&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://collabora.co.uk/&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;104&quot; src=&quot;http://laszlopandy.com/blog_files/collabora-logo.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
</description>
      </item>
    
    
    
      <item>
        <title>Building a bike</title>
        <link>http://abandonedwig.info/blog/2011/09/23/building-a-bike.html</link>
        <pubDate>Fri, 23 Sep 2011 00:00:00 EDT</pubDate>
        <name>Martin Robinson (Martin Robinson)</name>
        <guid>http://abandonedwig.info/blog/2011/09/23/building-a-bike.html</guid>
        <description>&lt;div class='post'&gt;
For some years now, I've been meaning to build a bicycle. Because I balked at the idea of owning more than one, I never did. Recently my unrestrained minimalism was given a reprieve in the form of cascading, terminal bicycle theft.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://2.bp.blogspot.com/-XGnQGGg3izI/Tn1Cy0aLsJI/AAAAAAAAARo/5OQtZ63Be7Y/s1600/saddle.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left:1em; margin-right:1em&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;267&quot; width=&quot;400&quot; src=&quot;http://2.bp.blogspot.com/-XGnQGGg3izI/Tn1Cy0aLsJI/AAAAAAAAARo/5OQtZ63Be7Y/s400/saddle.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;For five years, I've only locked one wheel on my trusty &lt;a href=&quot;http://www.mrmartinweb.com/bicycle.html#Nishiki&quot;&gt;1983 Nishiki International&lt;/a&gt; (this bicycle was actually named Super Famicom and the Crane Techniques). For some reason, the corroded spokes on the 27&quot; wheels never seemed enough of a prize for thievery. Over time I even began to leave the rear wheel unlocked. Apparently either a downturn in the economy or my own luck was sufficient to leave my bicycle without a rear wheel one night. &lt;br /&gt;&lt;br /&gt;I locked my limping ride to the rack in my apartment's parking garage. Upon returning two weeks later from the &lt;a href=&quot;http://igalia.com&quot;&gt;Igalia Assembly&lt;/a&gt; and the lovely &lt;a href=&quot;https://desktopsummit.org/&quot;&gt;Berlin Desktop Summit&lt;/a&gt;, I found my drop handlebars, stem, brake levers and brake cables  Scrounging from wounded bikes is a gray area, it seems. In any case, it was decided: time to build a bicycle.&lt;br /&gt;&lt;br /&gt;The process took a bit more than a month, though I worked only two or three days a week at it. My schedule generally followed the hours of the &lt;a href=&quot;http://www.bikekitchen.org/&quot;&gt;San Francisco Bike Kitchen&lt;/a&gt;, an awesome community bike shop bursting with incredibly knowledgeable volunteer mechanics and tools. I floundered a bit at first, because it isn't clear what order you should do things in, but the entire process went really smoothly.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Frame&lt;/b&gt; -  I had a &lt;a href=&quot;http://surlybikes.com/bikes/pacer&quot;&gt;new frame&lt;/a&gt;, which was a kick-ass birthday present from Lauryn. New frames aren't always ready for assembly yet, you may need to face and chase them. Because of manufacturing tolerances and excess paint, facing and chasing prepares the metal on the ends of the headtube and bottom bracket shell. Amazingly, the Bike Kitchen had the expensive, specialized tools for this task. One of their mechanics also stood over my shoulder as I shaved bits of metal off of my frame. It reminded me a lot of the first time I installed a processor on a motherboard, hand shaking with the thought of destroying it.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://1.bp.blogspot.com/-xhCLifQo-Xc/Tn1DhqqLcHI/AAAAAAAAASI/uMbi9R1MveA/s1600/surly.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left:1em; margin-right:1em&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; width=&quot;267&quot; src=&quot;http://1.bp.blogspot.com/-xhCLifQo-Xc/Tn1DhqqLcHI/AAAAAAAAASI/uMbi9R1MveA/s400/surly.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;Fork&lt;/b&gt; - My frame came with a fork, but the fork itself was actually a lot longer than I needed. Cutting a fork at a bike shop typically costs about $50, but again at the Kitchen they showed me how to measure for the cut and guided me in the proper application of a pipe cutter. This was probably the second time I returned home from the Bike Kitchen absolutely astounded.&lt;br /&gt;&lt;br /&gt;Measuring your fork can be a little tricky. At first I was under the impression that I needed the rest of the bicycle assembled to measure it. This isn't strictly true. If you know about how much of the fork you need, you can increase the measurement slightly. By moving the spacers around you can adjust the height of your handlebars up and down. It's important to remember that you can lower your handlebars on a long fork, but raising them on a short fork requires a steep stem or specialized adapters.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Headset&lt;/b&gt; - The headset is composed of the two little rings that sit between your fork and the top and bottom of your headtube. They have bearings in them, so that your fork can turn side to side. I made a mistake and started trying to assemble my headtube before cutting the fork. It was a lot easier once the fork was cut. There's a tool for pressing the headset cups into the headtube, it's like a very particular vice which ensures that they press in straight.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Bottom bracket&lt;/b&gt; - The bottom bracket is the spindle that the pedals rotate and the metal housing and bearings that the spindle rotates in. This was a fairly commodity part, though since I was reusing the crankset and pedals from my old bicyle, I had to be careful about what size I purchased. Against all odds I was able to combine information from old &lt;a href=&quot;http://www.equusbicycle.com/bike/sugino/&quot;&gt;Siguino crankset brochures&lt;/a&gt; and &lt;a href=&quot;http://www.sheldonbrown.com/bbsize.html&quot;&gt;Sheldon Brown&lt;/a&gt; to find the right size. This was actually a pretty simple process, but was made difficult by the font on the crankset which made &quot;GS&quot; look like &quot;G5.&quot; I'm &lt;a href=&quot;http://www.mrmartinweb.com/bicycle.html#Nishiki&quot;&gt;not the only one&lt;/a&gt; who made this mistake.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://3.bp.blogspot.com/-yav3VcExm4s/Tn1CzJrXHaI/AAAAAAAAAR4/mVX9uTl2Ois/s1600/defailer.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left:1em; margin-right:1em&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; width=&quot;267&quot; src=&quot;http://3.bp.blogspot.com/-yav3VcExm4s/Tn1CzJrXHaI/AAAAAAAAAR4/mVX9uTl2Ois/s400/defailer.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Once again, I was able to install these parts with the tools and assistance at the Bike Kitchen. A lot of the bicycle fell into place, after that. I installed the wheels next, mostly because I was tired of carrying my frame back and forth to the shop. I picked up used drop handlebars and a stem from there for eleven dollars  For some reason, no one stole the seatpost and seat from my old bicycle, so I essentially plugged that in directly. At this point my work seemed deceptively like something I could ride.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://1.bp.blogspot.com/-tuVT58QZaf4/Tn1CyyemxaI/AAAAAAAAARg/BKGTVZSFmHY/s1600/cassette.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left:1em; margin-right:1em&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;267&quot; width=&quot;400&quot; src=&quot;http://1.bp.blogspot.com/-tuVT58QZaf4/Tn1CyyemxaI/AAAAAAAAARg/BKGTVZSFmHY/s400/cassette.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Next I assembled the rest of the drive train. Installing the rear-wheel cassette was simple with the right tool, which I purchased since it was only seven dollars. The difference between nine and eight speed chains tripped me up briefly, but was not much of an issue in the end. Once the pedals seemed to turn the rear wheel and the rear derailleur was adjusted properly, I installed the brakes, brake levers, and handle bar tape. Since that time, I have ridden it with only minor adjustments.&lt;br /&gt;&lt;br /&gt;Observations:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt; The Bicycle Kitchen is awesome. The first time I attempted to go, I showed up an hour after they opened. I was disheartened to realize that the waiting list was so long that I wouldn't be able to get in that night. Everything in San Francisco has a waiting list though, so I arrived 10 minute before they opened every other time I went.&lt;/li&gt;&lt;li&gt;A lot of this process was made less daunting by the fact that there is an incredible number of tutorials and information available on the web. I spent a lot of time on the &lt;a href=&quot;http://www.parktool.com/blog/repair-help&quot;&gt;Park Tools&lt;/a&gt; website and the &lt;a href=&quot;http://www.youtube.com/user/Bikewagon&quot;&gt;Bike Wagon YouTube&lt;/a&gt; channel. I imagine this made me sound less clueless at the Bike Kitchen and just simply misinformed.&lt;/li&gt;&lt;li&gt;The fact that friction shifters actually have &quot;friction&quot; in their name is a subtle signal that you shouldn't load them down with grease. The ghost shifting problems are much better now.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://1.bp.blogspot.com/-Xr5A2JUCpOQ/Tn1DbIRNXQI/AAAAAAAAASA/cl7T-Ho2GAQ/s1600/full.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left:1em; margin-right:1em&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;267&quot; width=&quot;400&quot; src=&quot;http://1.bp.blogspot.com/-Xr5A2JUCpOQ/Tn1DbIRNXQI/AAAAAAAAASA/cl7T-Ho2GAQ/s400/full.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
</description>
      </item>
    
    
    
      <item>
        <title>Faster Shadows</title>
        <link>http://abandonedwig.info/blog/2011/03/13/faster-shadows.html</link>
        <pubDate>Sun, 13 Mar 2011 00:00:00 EST</pubDate>
        <name>Martin Robinson (Martin Robinson)</name>
        <guid>http://abandonedwig.info/blog/2011/03/13/faster-shadows.html</guid>
        <description>&lt;div class='post'&gt;
One area we paid particular attention last year at &lt;a href=&quot;http://igalia.com/&quot;&gt;Igalia&lt;/a&gt; was the performance of shadow rendering in web content. While web shadows are not yet ubiquitous, a slow shadow implementation can cause poor scrolling and redraw performance, ruining your day like an afternoon full of stepping in wet cement. Until recently, the GTK+ (and all Cairo) ports had one of these slow shadow implementations. Scrolling through identi.ca posts could lock Epiphany's user interface for several painful seconds. Alex and I set out to improve this situation.&lt;br /&gt;&lt;br /&gt;I separate shadowed web content into three categories: CSS &lt;a href=&quot;http://www.w3.org/TR/css3-background/#the-box-shadow&quot;&gt;box&lt;/a&gt; and &lt;a href=&quot;http://www.w3.org/TR/2011/WD-css3-text-20110215/#text-shadow&quot;&gt;text shadows&lt;/a&gt;, &lt;a href=&quot;http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#shadows&quot;&gt;canvas shadows&lt;/a&gt; and SVG shadows. Even though a different standard addresses each of these categories of shadows, the process of drawing the shadow remains very similar. The web rendering engine simply draws a copy of the shadowed object underneath itself with a solid fill (the shadow fill). This &quot;shadow image&quot; may also be blurred with a certain radius. For each of the standards that I mentioned, it is sufficient to blur the shadow image by estimating a &lt;a href=&quot;http://en.wikipedia.org/wiki/Gaussian_blur&quot;&gt;Gaussian blur&lt;/a&gt; on its pixels.&lt;br /&gt;&lt;br /&gt;A Gaussian blur is just the application of the &lt;a href=&quot;http://en.wikipedia.org/wiki/Normal_distribution&quot;&gt;normal distribution&lt;/a&gt; to the pixel values of an image. The value of a pixel in the blurred image is calculated by combining the values of the pixels around it in the original image. The contribution of a particular surrounding pixel decreases with the distance from the target pixel. Until recently the Cairo port performed an &lt;em&gt;actual&lt;/em&gt; Gaussian blur with an expensive two-dimensional kernel. The&amp;nbsp;first speed improvement involved making &lt;a href=&quot;http://ariya.blogspot.com/&quot;&gt;Ariya Hidayat's&lt;/a&gt; &lt;a href=&quot;http://trac.webkit.org/changeset/67559&quot;&gt;fast blurring algorithm&lt;/a&gt; (for the Qt port) cross-platform and using it for our own shadows. This algorithm estimates a Gaussian blur by performing multiple one-dimension motion blurs. This decreases the number of pixels that need to be read to calculate a target pixel and also increases the number of cache hits during the blurring calculation.&lt;br /&gt;&lt;br /&gt;In the course of our work we realized that we were not clipping the shadowed area when blurring. For instance, &lt;a href=&quot;http://identi.ca/&quot;&gt;identi.ca&lt;/a&gt; has one long column of content that extends down the page with a box blur. Instead of blurring just the part of the column visible in the viewport, we were blurring the entire box. This simple fix alone was enough to make most sites usable.&lt;br /&gt;&lt;br /&gt;Alex performed the &lt;a href=&quot;http://trac.webkit.org/changeset/69092&quot;&gt;final and most novel optimization&lt;/a&gt; for box shadows. Here's an image extremely typical web content with a shadowed div.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;281&quot; src=&quot;http://1.bp.blogspot.com/-gOVZs7QvkKE/TX1JPbbEBfI/AAAAAAAAAOs/u2USjvvJbB4/s400/one.png&quot; width=&quot;283&quot; /&gt;&lt;/div&gt;If we remove everything but the shadow we are left with what you see below. A lot of this information is repeated. In fact, we can divide the image into nine regions of unique information. Obviously we are calculating the same few values over and over again. Keep in mind that the slowest part of creating a blurry shadow is estimating the Gaussian.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;273&quot; src=&quot;http://3.bp.blogspot.com/-RA4OeJrGq2M/TX1JkqtBD5I/AAAAAAAAAO0/9yzV_PIEAIY/s400/two.png&quot; width=&quot;270&quot; /&gt;&lt;br /&gt;&lt;img border=&quot;0&quot; height=&quot;273&quot; src=&quot;http://2.bp.blogspot.com/-z9fSUszyz-w/TX1Jtxe3GII/AAAAAAAAAO8/rTENqnWATZ0/s400/three.png&quot; width=&quot;270&quot; /&gt;&lt;br /&gt;&lt;/div&gt;Each of non-corner regions of the box are made up of the same row of pixels repeated down their length.  In fact, if we had only one a single row of those blurred pixels we could just copy it into the region where the shadow belongs. This is precisely what Alex's implementation does. Instead of rendering the large shadowed area above, we can simply calculate a smaller box and copy the data into the target image.  &lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;110&quot; src=&quot;http://3.bp.blogspot.com/-np4whfyd0XE/TX1J4dbGXHI/AAAAAAAAAPE/ftm-67jio1w/s400/four.png&quot; width=&quot;120&quot; /&gt;&lt;/div&gt;I'm quite pleased with the performance of shadows now. There are a few more optimizations we could do, such as extending the tiling optimization to inset shadows. In fact, the Mac port has made our implementation cross-platform and has already added support for inset shadows. Hopefully more WebKit ports will soon be able to benefit from these optimizations.&lt;/div&gt;
</description>
      </item>
    
    
    
      <item>
        <title>Node.js Knockout</title>
        <link>http://abandonedwig.info/blog/2010/08/30/nodejs-knockout.html</link>
        <pubDate>Mon, 30 Aug 2010 00:00:00 EDT</pubDate>
        <name>Martin Robinson (Martin Robinson)</name>
        <guid>http://abandonedwig.info/blog/2010/08/30/nodejs-knockout.html</guid>
        <description>&lt;div class='post'&gt;
I participated in the &lt;a href=&quot;http://nodeknockout.com/&quot;&gt;Node.js Knockout&lt;/a&gt; this year, kindly hosted by &lt;a href=&quot;http://fortnightlabs.com/&quot;&gt;Fortnight Labs&lt;/a&gt;. Our team became a bit smaller as we neared the competition, so we decided to make something dead simple. When you're making software, it's good to have a vision statement. Even if you don't finish the software, you'll at least have a well-constructed sentence, which is progress.  Frankly, I was too embarrassed to mention my vision statement to my teammate, Josh.&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Each tweet is a tiny burst of light illuminating a cold, dark world.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;My opinion is that if you're not inspired after reading that, you've probably lost the ability to feel actual human emotions such as hope, rage, and yellow.  We decided to make a Twitter visualization for people like you.&lt;br /&gt;&lt;br /&gt;I'd never written anything on &lt;a href=&quot;http://nodejs.org/&quot;&gt;node.js&lt;/a&gt; before this competition and it did nothing but impress me. Node.js is built from the ground up with asynchronicity in mind, so ideally you aren't bound by the overhead of creating one thread per connection. Think &lt;a href=&quot;http://twistedmatrix.com/trac/&quot;&gt;Twisted&lt;/a&gt;. We also used &lt;a href=&quot;http://socket.io/&quot;&gt;Socket.IO&lt;/a&gt;, which made WebSockets sinfully pleasant.&lt;br /&gt;&lt;br /&gt;My partner, Josh, handled the server-side part of the application and I generally worked on the client-side&lt;sup&gt;1&lt;/sup&gt;. My favorite challenge was calculating the &lt;a href=&quot;http://en.wikipedia.org/wiki/Robinson_projection&quot;&gt;Robinson Projection&lt;/a&gt; for mapping latitude and longitude onto the map surface. It turns out that Robinson, unlike most projection progenitors, &lt;a href=&quot;http://findarticles.com/p/articles/mi_hb3006/is_2_31/ai_n29118548/&quot;&gt;relied on lookup tables and interpolation&lt;/a&gt; rather than providing a set of formulas only. I was easily able to port some Robinson Projection code from &lt;a href=&quot;http://trac.osgeo.org/proj4j/&quot;&gt;Java&lt;/a&gt; (which had itself been ported from &lt;a href=&quot;http://trac.osgeo.org/proj/&quot;&gt;C&lt;/a&gt;). It was some time later that I realized I had to scale the resulting numbers by the limits of projection output. It all seemed so obvious later on.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://node-us.no.de/&quot;&gt;In any case, I hope this amuses you for a couple seconds.&lt;/a&gt; The code will be on github after it's been cleaned up and licensed.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;I clumsily contributed a last minute cache optimization which had a negligible effect on the output.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;/div&gt;
</description>
      </item>
    
    
    
      <item>
        <title>Moving</title>
        <link>http://abandonedwig.info/blog/2010/08/30/moving-around.html</link>
        <pubDate>Mon, 30 Aug 2010 00:00:00 EDT</pubDate>
        <name>Martin Robinson (Martin Robinson)</name>
        <guid>http://abandonedwig.info/blog/2010/08/30/moving-around.html</guid>
        <description>&lt;div class='post'&gt;
My blog has a new &lt;a href=&quot;http://blog.abandonedwig.info&quot;&gt;URL&lt;/a&gt;. Please update your RSS subscriptions accordingly!&lt;/div&gt;
</description>
      </item>
    
    
    
      <item>
        <title>Looking back at the WebKit GTK hackfest</title>
        <link>http://abandonedwig.info/blog/2010/01/23/looking-back-at-webkit-gtk-hackfest.html</link>
        <pubDate>Sat, 23 Jan 2010 00:00:00 EST</pubDate>
        <name>Martin Robinson (Martin Robinson)</name>
        <guid>http://abandonedwig.info/blog/2010/01/23/looking-back-at-webkit-gtk-hackfest.html</guid>
        <description>&lt;div class='post'&gt;
In December, I attended the WebKit GTK hackfest which has been &lt;a href=&quot;http://blogs.gnome.org/xan/2009/12/21/webkitgtk-hackfest-day-g_maxint/&quot;&gt;summed&lt;/a&gt; &lt;a href=&quot;http://arstechnica.com/open-source/news/2010/01/webkitgtk-hackfest-improves-html-renderer-for-gnome-apps.ars&quot;&gt;up&lt;/a&gt; &lt;a href=&quot;http://danw.mysterion.org/2010/01/webkitgtk-hackfest/&quot;&gt;nicely&lt;/a&gt; in &lt;a href=&quot;http://blog.kov.eti.br/?p=100&quot;&gt;many&lt;/a&gt; &lt;a href=&quot;http://www.twotoasts.de/index.php?/archives/25-Back-from-the-WebKitGTK+-hackfest.html&quot;&gt;other&lt;/a&gt; &lt;a href=&quot;http://base-art.net/Articles/112/&quot;&gt;places&lt;/a&gt;. Some of the things I worked on (apart from getting my luggage):&lt;br /&gt;&lt;br /&gt;With the closing of &lt;a href=&quot;https://bugs.webkit.org/show_bug.cgi?id=20736&quot;&gt;20736&lt;/a&gt; WebKit GTK should now properly support windows with RGBA colormaps. This means that WebKit GTK can now be used to create nice desktop widgets or non-rectangular applications without worrying about BadMatch errors. Surprisingly non-rectangular windows is one of the most requested features for &lt;a href=&quot;http://www.appcelerator.com&quot;&gt;Titanium&lt;/a&gt; and we now support it on OS X, Linux and Windows via the &lt;tt&gt;transparent-background&lt;/tt&gt; property in tiapp.xml.&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;http://abandonedwig.info/blog/uploaded_images/rgba-colormaps-704760.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 331px; height: 400px;&quot; src=&quot;http://abandonedwig.info/blog/uploaded_images/rgba-colormaps-704752.png&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The first big part of my &lt;a href=&quot;https://bugs.webkit.org/show_bug.cgi?id=30623&quot;&gt;clipboard / drag-and-drop reorganization&lt;/a&gt; also landed. Once I get the remaining patches together, DOM DataTransfer access to WebKit GTK clipboard and drag-and-drop data will work properly. With luck one day you'll be able to drop your photos and videos onto your web browser and have them upload seamlessly.&lt;br /&gt;&lt;br /&gt;The hackfest itself was in A Coru&amp;ntilde;a, a picturesque Galician city right on the coast of the Atlantic (which I managed to call the &lt;i&gt;Pacific&lt;/i&gt; once, against all odds). I also had a rather abrupt introduction to the bounty of European languages &amp;mdash; Spain has four recognized regional languages apart from Spanish (Castilian).&lt;br /&gt;&lt;br /&gt;&lt;div style=&quot;font-size:small;text-align:center&quot;&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;http://www.flickr.com/photos/mariosp/4201554598/in/set-72157622899055111&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 500px; height: 375px;&quot; src=&quot;http://farm3.static.flickr.com/2773/4201554598_3fea667df2.jpg&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://blogs.gnome.org/xan/&quot;&gt;Xan&lt;/a&gt; and me, probably trying to convince him that drag-and-drop is the future.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;On a personal note, the hackfest solidified my love for open source software. I want to keep doing this, however possible. &lt;a href=&quot;http://neugierig.org/&quot;&gt;Evan Martin&lt;/a&gt; made a really good point about open source at some point during the hackfest. He said that people sometimes think that being open source means that you can simply host an archive of your source code somewhere. There is more to it though, including having an open and active community and understanding and responding to your users. Some of this is just good software development practice, but being open source requires doing even more work to open the development process.&lt;br /&gt;&lt;br /&gt;One important aspect of this work is having community discussions and allowing the community to help make decisions. One look at the WebKit development mailing list shows this working. There are many interests tied up with WebKit and some of them are direct competitors, yet somehow they manage to coordinate development on a humongous project. LWN.net recently posted a &lt;a href=&quot;http://lwn.net/Articles/370157/&quot;&gt;great article related to this topic&lt;/a&gt;, which I think exemplifies what not to do.&lt;/div&gt;
</description>
      </item>
    
    
    
      <item>
        <title>Managing the Python GIL via RAII</title>
        <link>http://abandonedwig.info/blog/2009/10/06/managing-python-gil-via-raii.html</link>
        <pubDate>Tue, 06 Oct 2009 00:00:00 EDT</pubDate>
        <name>Martin Robinson (Martin Robinson)</name>
        <guid>http://abandonedwig.info/blog/2009/10/06/managing-python-gil-via-raii.html</guid>
        <description>&lt;div class='post'&gt;
One of the killer features of C++ is &lt;a href=&quot;http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization&quot;&gt;&lt;acronym title=&quot;Resource Acquisition is Initialization&quot;&gt;RAII&lt;/acronym&gt;&lt;/a&gt;. RAII means that the amount of special-case cleanup code in the case of exceptions or early exits is minimized. For more on exactly how this happens, I recommend the Wikipedia article linked above.&lt;br /&gt;&lt;br /&gt;This feature became useful to me when making our Python Kroll module work properly with the Python GIL. There were two usage patterns I was interested in for this work.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Letting Python code in other threads run&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;PyThreadState* threadState = PyEval_SaveThread();&lt;br /&gt;...do some expensive non-Python work here...&lt;br /&gt;PyEval_RestoreThread(threadState);&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Taking back the GIL to use the Python API&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;PyGILState gstate = PyGILState_Ensure();&lt;br /&gt;...use the Python API here...&lt;br /&gt;PyGILState_Release(gstate);&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The problem with this approach is that if an uncaught exception escapes from anywhere between the ellipses, the cleanup code (&lt;tt&gt;PyEval_RestoreThread&lt;/tt&gt; or &lt;tt&gt;PyGILState_Release&lt;/tt&gt;) will not run, likely leaving the program in a bad state. It turns out that RAII has a very elegant solution to this problem.&lt;code&gt;&lt;pre&gt;&lt;br /&gt;    class PyLockGIL&lt;br /&gt;    {&lt;br /&gt;        PyLockGIL() : gstate(PyGILState_Ensure())&lt;br /&gt;        { }&lt;br /&gt;&lt;br /&gt;        ~PyLockGIL()&lt;br /&gt;        {&lt;br /&gt;            PyGILState_Release(gstate);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        PyGILState_STATE gstate;&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;    class PyAllowThreads&lt;br /&gt;    {&lt;br /&gt;        PyAllowThreads() : threadState(PyEval_SaveThread())&lt;br /&gt;        { }&lt;br /&gt;&lt;br /&gt;        ~PyAllowThreads()&lt;br /&gt;        {&lt;br /&gt;            PyEval_RestoreThread(threadState);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        PyThreadState* threadState;&lt;br /&gt;    };&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;The acquisition and release of the GIL is just wrapped in the constructors and destructors of objects that are allocated on the stack. Here is the previous example using these new objects:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;{&lt;br /&gt;    PyLockGIL lock&lt;br /&gt;    ...do some expensive non-Python work here...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;    PyAllowThreads allow;&lt;br /&gt;    ...use the Python API here...&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Notice that braces can be used to fine tune the amount of code with the desired GIL state. The destructor for these objects will be called as soon as they go out of scope.&lt;/div&gt;
</description>
      </item>
    
    
    
      <item>
        <title>End-run around registration-free COM</title>
        <link>http://abandonedwig.info/blog/2009/04/23/end-run-around-registration-free-com.html</link>
        <pubDate>Thu, 23 Apr 2009 00:00:00 EDT</pubDate>
        <name>Martin Robinson (Martin Robinson)</name>
        <guid>http://abandonedwig.info/blog/2009/04/23/end-run-around-registration-free-com.html</guid>
        <description>&lt;div class='post'&gt;
With the introduction of registration-free COM, Windows now allows you to create COM objects without registering their DLLs in the registry. This means that you can include your COM DLLs with your application files and run the application without being an administrator and mucking with regsvr32. Instead you include (or embed in your executable/DLL) a manifest which specifies the location of the COM DLL relative to your application. &lt;br /&gt;&lt;br /&gt;This &quot;new&quot; (it was introduced with Windows XP, I believe) approach is not flexible enough for Titanium, which doesn't know until after run-time which WebKit DLL it will be using. Writing this manifest file into the application directory and restarting or copying the DLLs into the application directory is a less than ideal solution. While the copy may work in Vista because of the wonky UAC virtualization of write permissions (that's an entirely different rant), copying an entire DLL and its dependencies at startup is expensive and defeats the purpose of DLLs.&lt;br /&gt;&lt;br /&gt;This situation bothered me until I stumbled upon &lt;a href=&quot;http://blogs.msdn.com/gpalem/archive/2007/03/26/avoid-registration-free-com-manifest-problems-with-activation-context-api.aspx&quot;&gt;this blog post &lt;/a&gt;in the murky underbelly of the interblogs. It basically describes an approach using the somewhat thinly documented (perhaps intentionally) &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/aa375134.aspx&quot;&gt;activation context API&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;This Windows nightmare has a happy ending in that we were able to simply point an activation context at the WebKit DLL's manifest path. Here's what it looks like (this is originally from Gopalakrishna's blog which I linked to above):&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;// This is a normal CoCreateInstance -- done as if the COM DLL&lt;br /&gt;// was actually registered with the system -- it will fail&lt;br /&gt;IMyComponent* pObj = NULL;&lt;br /&gt;HRESULT hr = CoCreateInstance(&lt;br /&gt;    CLSID_MyComponent, &lt;br /&gt;    NULL, &lt;br /&gt;    CLSCTX_INPROC_SERVER, &lt;br /&gt;    IID_IMyComponent,&lt;br /&gt;    (void**)&amp;pObj);&lt;br /&gt;&lt;br /&gt;ACTCTX actctx;&lt;br /&gt;ZeroMemory(&amp;actctx, sizeof(actctx));&lt;br /&gt;actctx.cbSize = sizeof(actctx);&lt;br /&gt;actctx.lpSource = &quot;C:\Path\To\My\Manifest.manifest&quot;;&lt;br /&gt;HANDLE pActCtx = CreateActCtx(&amp;actctx);&lt;br /&gt;ULONG_PTR lpCookie;&lt;br /&gt;&lt;br /&gt;if(pActCtx != INVALID_HANDLE_VALUE)&lt;br /&gt;{&lt;br /&gt;    if (ActivateActCtx(pActCtx, &amp;lpCookie))&lt;br /&gt;    {&lt;br /&gt;       // CoCreateInstance should succeed now. &lt;br /&gt;       HRESULT hr = CoCreateInstance(&lt;br /&gt;           CLSID_MyComponent, &lt;br /&gt;           NULL, &lt;br /&gt;           CLSCTX_INPROC_SERVER, &lt;br /&gt;           IID_IMyComponent,&lt;br /&gt;           (void**)&amp;pObj);&lt;br /&gt;       DeactivateActCtx(0, lpCookie);&lt;br /&gt;    }&lt;br /&gt;    ReleaseActCtx(pActCtx);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</description>
      </item>
    
    
    
      <item>
        <title>Avoiding the Logging Performance Hit</title>
        <link>http://abandonedwig.info/blog/2009/04/04/avoiding-logging-performance-hit.html</link>
        <pubDate>Sat, 04 Apr 2009 00:00:00 EDT</pubDate>
        <name>Martin Robinson (Martin Robinson)</name>
        <guid>http://abandonedwig.info/blog/2009/04/04/avoiding-logging-performance-hit.html</guid>
        <description>&lt;div class='post'&gt;
Sometimes you have a function or a method which more often throws away its arguments than actually uses them. Quite possibly the most common example of this situation is logging. Often you'll see a snippet like this:&lt;pre&gt;&lt;code&gt;&lt;br /&gt;log.Debug(&quot;Processing &quot; + index + &quot; of &quot; + count);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;It's just the way things are that debug log statements are used more liberally than error statements. Even if log.debug(...) doesn't actually log it's argument, your program will still pay the penalty of doing the string concatenation continuously. As a result many programmers are forced to write code that looks like this:&lt;pre&gt;&lt;code&gt;&lt;br /&gt;if (log.IsDebug()&lt;br /&gt;{&lt;br /&gt;    log.Debug(&quot;Processing &quot; + index + &quot; of &quot; + count);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Now the internal state of the logger must be examined externally for every debug statement. D solves this issue through &lt;a href=&quot;http://www.digitalmars.com/d/2.0/lazy-evaluation.html&quot;&gt;lazily evaluated functional arguments&lt;/a&gt;. In D you can change the signature of your function to look like this:&lt;pre&gt;&lt;code&gt;&lt;br /&gt;void Debug(lazy char[] entry)&lt;br /&gt;{&lt;br /&gt;   if (debug)&lt;br /&gt;     fwritefln(logfile, entry());&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This is really just syntactic sugar around D's delegate parameters in which you can pass a function as an argument. The end result, though, is that the statement that composed the argument won't be evaluated until it is actually used.&lt;br /&gt;&lt;br /&gt;Titanium and Kroll are written in C++ though, which doesn't have the same kind of syntactic niceties that D does. Recently, when putting the first bits of the logging system into Kroll, I decided that I wasn't satisfied with the Java-style debugging which I wrote above. I wanted to fully encapsulate the behavior of the logger &lt;span style=&quot;font-style:italic;&quot;&gt;and&lt;/span&gt; avoid paying the penalty of uneeded string processing. One common approach for C/C++ is to use macros, but as Walter Bright explains in his essay on lazy argument evaluation, this isn't the best solution.&lt;br /&gt;&lt;br /&gt;Luckily, C and C++ have variadic arguments which allow us to create both easy-to-read logging code and to avoid paying a penalty for those statements which should essentially be no-ops. I  harnessed the power of a seldom-used friend from the C library for this task: &lt;a href=&quot;http://www.opengroup.org/onlinepubs/9699919799/functions/vprintf.html&quot;&gt;vsnprintf&lt;/a&gt;. vsnprintf operates much like snprintf, except that instead of taking a variable list of arguments it takes a va_list (basically a variadic list of arguments that can be passed forward to other functions). Here is the resulting code from Kroll:&lt;pre&gt;&lt;code&gt;&lt;br /&gt;  std::string Logger::Format(const char* format, va_list args)&lt;br /&gt;  {&lt;br /&gt;    // Protect the buffer&lt;br /&gt;    Poco::Mutex::ScopedLock lock(this-&gt;mutex);&lt;br /&gt; &lt;br /&gt;    vsnprintf(Logger::buffer, LOGGER_MAX_ENTRY_SIZE - 1, format, args);&lt;br /&gt;    Logger::buffer[LOGGER_MAX_ENTRY_SIZE - 1] = '\0';&lt;br /&gt;    std::string text = buffer;&lt;br /&gt;    return text;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  void Logger::Log(Level level, const char* format, va_list args)&lt;br /&gt;  {&lt;br /&gt;    Poco::Logger&amp; loggerImpl = Poco::Logger::get(name);&lt;br /&gt; &lt;br /&gt;    // Don't do formatting when this logger filters the message.&lt;br /&gt;    // This prevents unecessary string manipulation.&lt;br /&gt;    if (level &gt;= (Level) loggerImpl.getLevel())&lt;br /&gt;    {&lt;br /&gt;      std::string messageText = Logger::Format(format, args);&lt;br /&gt;      this-&gt;Log(level, messageText);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  void Logger::Debug(const char* format, ...)&lt;br /&gt;  {&lt;br /&gt;    va_list args;&lt;br /&gt;    va_start(args, format);&lt;br /&gt;    this-&gt;Log(LDEBUG, format, args);&lt;br /&gt;  }&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;A typical logging statement looks like this:&lt;pre&gt;&lt;code&gt;&lt;br /&gt;log.Debug(&quot;Processing %i of %i&quot;, index, count);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
</description>
      </item>
    
    
    
      <item>
        <title>DBus and Threads</title>
        <link>http://abandonedwig.info/blog/2009/03/06/dbus-and-threads.html</link>
        <pubDate>Fri, 06 Mar 2009 00:00:00 EST</pubDate>
        <name>Martin Robinson (Martin Robinson)</name>
        <guid>http://abandonedwig.info/blog/2009/03/06/dbus-and-threads.html</guid>
        <description>&lt;div class='post'&gt;
Sometimes you'll be using Dbus with threads and notice intermittent segfaults with stack traces like this;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#0  0xb4d58d29 in _dbus_watch_invalidate (watch=0x0) at dbus-watch.c:147&lt;br /&gt;#1  0xb4d57066 in free_watches (transport=0x979c0d0) at dbus-transport-socket.c:82&lt;br /&gt;#2  0xb4d57e7e in socket_disconnect (transport=0x979c0d0) at dbus-transport-socket.c:908&lt;br /&gt;#3  0xb4d561e8 in _dbus_transport_disconnect (transport=0x979c0d0) at dbus-transport.c:494&lt;br /&gt;#4  0xb4d56c68 in _dbus_transport_queue_messages (transport=0x979c0d0) at dbus-transport.c:1137&lt;br /&gt;#5  0xb4d3dc24 in _dbus_connection_get_dispatch_status_unlocked (connection=0x979c4b0) at dbus-connection.c:3983&lt;br /&gt;#6  0xb4d3b695 in check_for_reply_and_update_dispatch_unlocked (connection=0x979c4b0, pending=0xb3c00550) at dbus-connection.c:2235&lt;br /&gt;#7  0xb4d3b883 in _dbus_connection_block_pending_call (pending=0xb3c00550) at dbus-connection.c:2337&lt;br /&gt;#8  0xb4d501c1 in dbus_pending_call_block (pending=0xb3c00550) at dbus-pending-call.c:707&lt;br /&gt;#9  0xb4d7aedf in dbus_g_proxy_end_call_internal (proxy=0x9776f90, call_id=30, error=0xb4d2d30c, first_arg_type=158972744, args=0xb4d2d2e4 &quot;&amp;#65533;&amp;#65533;&amp;#1204;&quot;) at dbus-gproxy.c:2256&lt;br /&gt;#10 0xb4d7b90e in dbus_g_proxy_call (proxy=0x9776f90, method=0xb4dca4bb &quot;Get&quot;, error=0xb4d2d30c, first_arg_type=64) at dbus-gproxy.c:2584&lt;br /&gt;&lt;/pre&gt;This is happening because DBus doesn't do locking by default. I presume this is for performance reasons. Luckily, the solution to this problem is very simple. Simply run &lt;tt&gt;&lt;a href=&quot;http://dbus.freedesktop.org/doc/api/html/group__DBusThreads.html#ge3f80916adb6d7fdfe613385e044f58a&quot;&gt;dbus_thread_init_default()&lt;/a&gt;&lt;/tt&gt; before you try accessing DBus.&lt;/div&gt;
</description>
      </item>
    
    
    
      <item>
        <title>Compiling D Source is Easy</title>
        <link>http://abandonedwig.info/blog/2009/01/18/compiling-d-source-is-easy.html</link>
        <pubDate>Sun, 18 Jan 2009 00:00:00 EST</pubDate>
        <name>Martin Robinson (Martin Robinson)</name>
        <guid>http://abandonedwig.info/blog/2009/01/18/compiling-d-source-is-easy.html</guid>
        <description>&lt;div class='post'&gt;
There are two compilers available for D. The original D compiler (the one written by Walter) is DMD. It has an open-source front-end (the part that generate the IL) and a proprietary, closed-source back-end (the part that converts the IL into machine code). Two other, fully open-source compilers exist, GDC and LDC, which use the &lt;a href=&quot;http://gcc.gnu.org/&quot;&gt;GCC&lt;/a&gt; and &lt;a href=&quot;http://llvm.org/&quot;&gt;LLVM&lt;/a&gt; back-ends respectively.&lt;br /&gt;&lt;br /&gt;I like using GDC, because it's open-source and has &lt;a href=&quot;http://www.digitalmars.com/d/archives/digitalmars/D/learn/How_to_create_a_shared_library_with_DMD_on_Linux_5740.html&quot;&gt;better support&lt;/a&gt; for shared library linking on Unices. It's fairly easy to switch between GDC and DMD, as GDC includes a &lt;tt&gt;gdmd&lt;/tt&gt; command which emulates the command-line behavior of DMD. &lt;br /&gt;&lt;br /&gt;Previously I was using &lt;a href=&quot;http://www.dsource.org/projects/dsss&quot;&gt;DSSS&lt;/a&gt; to build my D projects. While DSSS is very nice in many ways, it felt odd using a build tool that was really only popular in the D community. After we started using &lt;a href=&quot;http://www.scons.org/&quot;&gt;SCons&lt;/a&gt; at &lt;a href=&quot;http://appcelerator.org/&quot; title=&quot;More Tap, Less Foxtrot&quot;&gt;work&lt;/a&gt;, I was positively pickled to find that it supported building D code. SCons works just as easily for D code as it does for building other things.&lt;br /&gt;&lt;br /&gt;Say you have a source file containing your ground-breaking implementation of the Smash Mouth Optimization (see Computational Football vol. 23), SmashMouth.d. To build this with SCons, simply create a SConstruct file that looks like this:&lt;br /&gt;&lt;pre&gt;BuildDir('build', 'src')&lt;br /&gt;e = Environment()&lt;br /&gt;e.Program('build/SmashMouth.d')&lt;/pre&gt;This assumes that you have your source in a folder called &lt;tt&gt;src&lt;/tt&gt; and you want to build into a folder called &lt;tt&gt;build&lt;/tt&gt; (I know, I know...this is a pretty brazen assumption). Running &lt;tt&gt;scons&lt;/tt&gt; should produce something like this:&lt;br /&gt;&lt;pre&gt;scons: Reading SConscript files ...&lt;br /&gt;scons: done reading SConscript files.&lt;br /&gt;scons: Building targets ...&lt;br /&gt;gcc -o build/Test build/Test.o -lgphobos -lpthread -lm -lgphobos -lgphobos -lgphobos&lt;br /&gt;scons: done building targets.&lt;/pre&gt;You can see here that scons decided to build using GDC and Phobos. The SCons D scanner is pretty smart about what compilers you have on your system. It's also configurable. Okay, here comes the magical wonderland part.&lt;br /&gt;&lt;br /&gt;What happens when you decide that you want SmashMouthOptimizer to be a shared library? You have some options here.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;You could simply look through all the man pages of the D compilers you are using, hunt for all the relevant linking options, and finally write conditional code in your Makefile to use them.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;On the other hand, you could just change your SConstruct to look like this:&lt;br /&gt;&lt;pre&gt;BuildDir('build', 'src')&lt;br /&gt;e = Environment()&lt;br /&gt;e.SharedLibrary('build/SmashMouth.d')&lt;/pre&gt;Then let &lt;tt&gt;scons&lt;/tt&gt; do this:&lt;br /&gt;&lt;pre&gt;scons: Reading SConscript files ...&lt;br /&gt;scons: done reading SConscript files.&lt;br /&gt;scons: Building targets ...&lt;br /&gt;gdmd -I. -c -ofbuild/SmashMouth.os build/SmashMouth.d&lt;br /&gt;gcc -o build/libSmashMouth.so -shared build/SmashMouth.os&lt;br /&gt;scons: done building targets.&lt;/pre&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;
</description>
      </item>
    
    
    
      <item>
        <title>Different People</title>
        <link>http://abandonedwig.info/blog/2009/01/03/calm-down.html</link>
        <pubDate>Sat, 03 Jan 2009 00:00:00 EST</pubDate>
        <name>Martin Robinson (Martin Robinson)</name>
        <guid>http://abandonedwig.info/blog/2009/01/03/calm-down.html</guid>
        <description>&lt;div class='post'&gt;
&lt;a href=&quot;http://en.wikipedia.org/wiki/Being_There_(film)&quot;&gt;Being There&lt;/a&gt; warms my heart for several reasons. One of the most notable is that &lt;a href=&quot;http://en.wikipedia.org/wiki/Hal_Ashby&quot;&gt;Hal Ashby&lt;/a&gt; managed to turn&lt;a href=&quot;http://en.wikipedia.org/wiki/Basketball_jones&quot;&gt; a Cheech and Chong song&lt;/a&gt; into some kind of religious experience with umbrellas. There is also the unexpected vignette during the ending, which many people seem to hate. I have no idea why.&lt;br /&gt;&lt;br /&gt;One of the lesser known reasons though, is that it exposes you to some truly awesome music from somewhere you didn't expect. If I had to construct a rigid philosophical framework, I think this would be a major tenet. You might be asking, &quot;What is that unexpected source, Martin?&quot;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Sesame_street&quot;&gt;&lt;div style=&quot;margin: 0px auto; text-align:center;&quot;&gt;&lt;img title=&quot;Sesame Street&quot; alt=&quot;Sesame Street&quot;  src=&quot;http://abandonedwig.info/blog/uploaded_images/sesame_street_logo-798824.gif&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here's the rundown: &lt;a href=&quot;http://en.wikipedia.org/wiki/Buffy_Sainte-Marie&quot;&gt;Buffy Sainte-Marie&lt;/a&gt; is talking to Big Bird about some of their interpersonal problems. Big Bird, of course, is suffering unshakable angst, so Buffy is forced to crack it in typical Sesame Street fashion. The music starts at 2:05, by the way.&lt;br /&gt;&lt;br /&gt;&lt;div style=&quot;margin: 0px auto; text-align:center;&quot;&gt;&lt;br /&gt;&lt;object width=&quot;425&quot; height=&quot;344&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://www.youtube.com/v/4oNHAl_d4Y4&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en&amp;feature=player_embedded&amp;fs=1&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;&gt;&lt;/param&gt;&lt;embed src=&quot;http://www.youtube.com/v/4oNHAl_d4Y4&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en&amp;feature=player_embedded&amp;fs=1&quot; type=&quot;application/x-shockwave-flash&quot; allowfullscreen=&quot;true&quot; width=&quot;425&quot; height=&quot;344&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;
</description>
      </item>
    
    
    
      <item>
        <title>Embedding Python in D</title>
        <link>http://abandonedwig.info/blog/2009/01/01/embedding-python-in-d.html</link>
        <pubDate>Thu, 01 Jan 2009 00:00:00 EST</pubDate>
        <name>Martin Robinson (Martin Robinson)</name>
        <guid>http://abandonedwig.info/blog/2009/01/01/embedding-python-in-d.html</guid>
        <description>&lt;div class='post'&gt;
&lt;div style=&quot;float:right; margin: 0pt 0pt 10px 10px; &quot;&gt;&lt;img style=&quot;cursor: pointer; width: 200px; height: 200px;&quot; src=&quot;http://abandonedwig.info/blog/uploaded_images/python-758704.png&quot; alt=&quot;&quot; border=&quot;0&quot; /&gt;&lt;div style=&quot;font-size: small; width:100%; text-align:center;&quot;&gt;Oooooooooh.&lt;br/&gt;It's some snakes.&lt;br/&gt;It's some snakes.&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;A while back I began spending some time acquainting myself with D. For those who don't know, D is a relatively new &lt;a href=&quot;http://en.wikipedia.org/wiki/System_programming_language&quot;&gt;system programming language&lt;/a&gt; with all kinds of interesting features like very flexible garbage collection, mixins and an easy-to-use yet powerful template system. D was created by &lt;a href=&quot;http://en.wikipedia.org/wiki/Walter_Bright&quot;&gt;Walter Bright&lt;/a&gt;, who also created the first native C++ compiler and &lt;a href=&quot;http://en.wikipedia.org/wiki/Classic_Empire_%28computer_game%29&quot;&gt;Empire&lt;/a&gt; (of all things).&lt;br /&gt;&lt;br /&gt;Anyhow, one of the things that I really like about D is that it is maintains link compatibility with C &lt;sup&gt;1&lt;/sup&gt;. This means that D code can make calls into libraries like those from GTK in the same way that C++ code can. This mitigates the need or the desire to rewrite useful tools. Many times simple binding layers can be written to expose C-style APIs in D-style ways.&lt;br /&gt;&lt;br /&gt;In my case, I'm writing an application which uses the GTK bindings for D, &lt;a href=&quot;http://www.dsource.org/projects/gtkd&quot;&gt;GtkD&lt;/a&gt;, and embeds a Python interpreter. Creating the D header from Python.h turns out to be pretty easy with &lt;a href=&quot;http://www.dsource.org/projects/bcd/&quot;&gt;bcd&lt;/a&gt;, a tool which tries to automate most of the process &lt;sup&gt;2&lt;/sup&gt;.&lt;br /&gt;&lt;br /&gt;The first step is to run bcd against the header you want to use. For me this looked like:&lt;br /&gt;&lt;pre&gt;./bcdgen /usr/include/python2.5/Python.h Python -C -A&lt;/pre&gt;In this case &quot;-C&quot; means &quot;C-mode&quot; (as opposed to C++-mode) and &quot;-A&quot; tells bcdgen to continue working on all includes recursively (since Python.h is really a meta-header). Unfortunately this gives me:&lt;br /&gt;&lt;pre&gt;In file included from /usr/include/stdio.h:906,&lt;br /&gt;              from /usr/include/python2.5/Python.h:32:&lt;br /&gt;/usr/include/bits/stdio2.h: In function 'int sprintf(char*, const char*, ...)':&lt;br /&gt;/usr/include/bits/stdio2.h:35: error: '__builtin_va_arg_pack' was not declared in this scope&lt;br /&gt;/usr/include/bits/stdio2.h: In function 'int snprintf(char*, size_t, const char*, ...)':&lt;br /&gt;...&lt;/pre&gt;This is a &lt;a href=&quot;https://bugs.launchpad.net/ubuntu/+source/gccxml/+bug/293807&quot;&gt;bug&lt;/a&gt; with Intrepid Ibex's version of gccxml. Luckily there are &lt;a href=&quot;http://www.kloss-familie.de/moin/Root/PatchingGccXml&quot;&gt;workarounds&lt;/a&gt;. Once bcdgen finishes it's work, it should create a bcd/Python/Python.d, which is where all the Python.h definitions landed. If you open it up and take a look, you can see bcdgen has converted them to D definitions. Way to go automated software development tools!&lt;br /&gt;&lt;br /&gt;Generally some work is required before the D compiler accepts this file and the bcd page lists some general guidelines for this task. I'm familiar with Python's C interface, but definitely not intimate. This is a secret code that I'm using which means I spent a bit of time fixing weird D compiler errors. It wasn't bad though and I was was able to resolve most of the compile errors without much trouble. I'm my next post I'll write a little bit about that.&lt;br /&gt;&lt;hr /&gt;&lt;div style=&quot;font-size: small;&quot;&gt;&lt;ol&gt;&lt;li&gt;D does not have link compatibility with C++.  Many C++ projects have have external APIs which are C-compatible though. One example from recent memory is the KJS API from WebKit.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;There is a really great project called &lt;a href=&quot;http://pyd.dsource.org/celerid.html&quot;&gt;CeleriD&lt;/a&gt;, which has already done a lot of this work. CeleriD is really geared toward extending Python rather than embedding it though. I decided to strike out on my own as an educational gesture&lt;sup&gt;3&lt;/sup&gt; and to avoid depending on distutils for my build process.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;i&gt;Gesture&lt;/i&gt; because it's hard to believe this is can be considered larnin'&lt;sup&gt;4&lt;/sup&gt;, which is coincidentally the way I feel about most professional software training programs.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The best thing about the &amp;lt;sup&amp;gt; tag is that it's a formatting markup  &lt;i&gt;and&lt;/i&gt; a greeting. 'Sup &amp;lt;sup&amp;gt;?&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;
</description>
      </item>
    
    

  </channel>
</rss>

