<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-17722541</id><updated>2012-01-26T10:25:58.498+01:00</updated><category term='spotify'/><category term='funny'/><category term='comedy'/><category term='bugs'/><category term='ovi'/><category term='oslo'/><category term='puzzle'/><category term='plasma'/><category term='hamburg'/><category term='openstreetmap'/><category term='suse'/><category term='cebit'/><category term='sencha'/><category term='photoflow'/><category term='travel'/><category term='kinetic'/><category term='git'/><category term='windmill'/><category term='phantomjs'/><category term='vim'/><category term='soc'/><category term='marble'/><category term='san diego'/><category term='n900'/><category term='coverflow'/><category term='meego'/><category term='speedcrunch'/><category term='san francisco'/><category term='effect'/><category term='creator'/><category term='graphics'/><category term='grandcanaria'/><category term='bossaconf'/><category term='webgl'/><category term='kde4'/><category term='maemo'/><category term='mentorsummit'/><category term='radeon'/><category term='legacy-vs-lateral'/><category term='android'/><category term='photo'/><category term='paris'/><category term='geolocation'/><category term='svg'/><category term='dessert'/><category term='color'/><category term='redwood city'/><category term='coding'/><category term='optimization'/><category term='perfectspot'/><category term='accelerometer'/><category term='network'/><category term='indonesia'/><category term='berlin'/><category term='google'/><category term='virtualization'/><category term='technology'/><category term='podcast'/><category term='munich'/><category term='javascript'/><category term='koffice'/><category term='quote'/><category term='sdl'/><category term='musing'/><category term='gadget'/><category term='wpg'/><category term='pictureflow'/><category term='wine'/><category term='bremen'/><category term='screenie'/><category term='devdays'/><category term='lisbon'/><category term='fglrx'/><category term='webkit'/><category term='camp kde'/><category term='lazyweb'/><category term='opengl'/><category term='skia'/><category term='python'/><category term='sunspider'/><category term='chipmunk'/><category term='madrid'/><category term='script'/><category term='grancanaria'/><category term='x2'/><category term='qualcomm'/><category term='canvas'/><category term='physics'/><category term='code'/><category term='motorola'/><category term='amsterdam'/><category term='calligra'/><category term='hack'/><category term='leipzig'/><category term='linuxtag'/><category term='opensuse'/><category term='mentorsummit08'/><category term='vacation'/><category term='ofilabs'/><category term='qtwebkit'/><category term='htc'/><category term='manaus'/><category term='palo alto'/><category term='cupertino'/><category term='book'/><category term='kde'/><category term='brazil'/><category term='tip'/><category term='train station'/><category term='hacks'/><category term='food'/><category term='mapquest'/><category term='akademy'/><category term='chromium'/><category term='joke'/><category term='qemu'/><category term='colors'/><category term='s60'/><category term='film'/><category term='qt'/><category term='oding'/><title type='text'>don't code today what you can't debug tomorrow</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default?start-index=101&amp;max-results=100'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>516</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-17722541.post-1424915442762458788</id><published>2011-07-28T18:07:00.004+02:00</published><updated>2011-07-28T18:21:31.164+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='musing'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><title type='text'>open and freedom</title><content type='html'>&lt;p&gt;After almost 6 years, 500 blog posts, and over half a million visits, I decide to have a new playground for my (often crazy) experiments. From now on, if you want to follow my ramblings, check &lt;a href="http://ariya.ofilabs.com"&gt;ariya.ofilabs.com&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-1424915442762458788?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/1424915442762458788/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=1424915442762458788' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1424915442762458788'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1424915442762458788'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2011/07/open-and-freedom.html' title='open and freedom'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-3724259635857529394</id><published>2011-07-26T20:24:00.009+02:00</published><updated>2011-07-27T03:45:13.983+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='musing'/><category scheme='http://www.blogger.com/atom/ns#' term='gadget'/><category scheme='http://www.blogger.com/atom/ns#' term='optimization'/><title type='text'>tablets and web performance</title><content type='html'>&lt;p&gt;Benchmarks, and the results of running them, are attractive because they eliminate the need to digest an arbitrary complex machinery, reducing it into a meaningful and powerful number. Comparison is thereby made easier, as it is now a matter of playing &lt;i&gt;who has the biggest gun&lt;/i&gt; game.&lt;/p&gt;

&lt;p&gt;In the areas of web performance, every benchmark becomes more like &lt;a href="http://ariya.blogspot.com/2009/03/for-glorious-nation.html"&gt;durian&lt;/a&gt;, either you hate it or you love it. No matter how useful (or useless) a benchmark is, there are always folks who defend it and others who despise it. Signal-to-noise ratio changes dramatically when the discussion over some benchmark results is started.&lt;/p&gt;

&lt;p&gt;I still reckon that in the years to come, what makes a great experience while browsing the web depends on the performance of (surprise!) DOM access. Common JavaScript &lt;a href="http://www.ibm.com/developerworks/web/library/wa-jsframeworks/index.html"&gt;frameworks&lt;/a&gt; (like jQuery, Prototype, Ext JS, MooTools, YUI, Dojo, and many others) still form the basis for a lot of rich web sites and interactive web applications out there, at least for the time being and till the near future.&lt;/p&gt;

&lt;p&gt;While &lt;a href="http://www.webkit.org/perf/sunspider/sunspider.html"&gt;SunSpider&lt;/a&gt; and &lt;a href="http://code.google.com/apis/v8/benchmarks.html"&gt;V8&lt;/a&gt; benchmarks are geared towards pure JavaScript performance and &lt;a href="http://code.google.com/apis/v8/benchmarks.html"&gt;Kraken&lt;/a&gt; is better suited for future heavyweight applications, &lt;a href="https://wiki.mozilla.org/Dromaeo"&gt;Dromaeo&lt;/a&gt; becomes a solid candidate for DOM performance analysis. In particular, its set of &lt;a href="http://dromaeo.com/?dom|jslib|cssquery"&gt;DOM tests&lt;/a&gt; is very valuable because it presents a nice sample of the behavior of framework-based sites. In this context, butter-smooth DOM modification has a bigger impact than just blazing-fast trigonometric computation, at least for &lt;a href="http://trends.builtwith.com/javascript"&gt;gajillions web pages&lt;/a&gt; out there.&lt;/p&gt;

&lt;p&gt;Since more and &lt;a href="http://blog.nielsen.com/nielsenwire/?p=27570"&gt;more people&lt;/a&gt; are accessing the web through mobile platforms these days, I decided to test several popular tablets out there and summarize the result in one graph below (&lt;b&gt;updated&lt;/b&gt;):&lt;/p&gt;

&lt;p&gt;&lt;img src="https://lh4.googleusercontent.com/-hck5vmLmpJw/Ti9tLBmA88I/AAAAAAAACDE/8Tiqv7Ra0VY/s800/dromaeo-tablets.png" width="600" height="256"/&gt;&lt;/p&gt;

&lt;p&gt;For the detailed comparisons, check out the &lt;a href="http://dromaeo.com/?id=145513,145514,145584,145728"&gt;complete Dromaeo numbers&lt;/a&gt; of all tablets (left-to-right: Galaxy Tab, iPad 2, Playbook, TouchPad). If you find the above result is different that what you test yourself, shout out. I want to be careful not to propagate any discrepancies or misleading results. As usual, take the above beautiful collection of colored bars with a pinch of salt.&lt;/p&gt;

&lt;p&gt;Samsung Galaxy Tab 10.1 is powered by Android 3.1 (Honeycomb) Build HMJ37, iPad 2 is using iOS 4.3.3, RIM Playbook's firmware is 1.0.7.2670, which the HP TouchPad has webOS 3.0. The choice of the devices represent a variety of fresh ARM-based tablet operating systems in the market as of this writing.&lt;/p&gt;


&lt;p&gt;With Qt coming closer and closer to the become &lt;a href="http://labs.qt.nokia.com/2011/02/28/necessitas/"&gt;a good companion&lt;/a&gt; of the green robot, I wonder how would &lt;a href="http://developer.qt.nokia.com/wiki/QtWebKit"&gt;QtWebKit&lt;/a&gt; compete with those numbers. I think we will find out the answer in a couple of months, maybe even sooner.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-3724259635857529394?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/3724259635857529394/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=3724259635857529394' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/3724259635857529394'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/3724259635857529394'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2011/07/tablets-and-web-performance.html' title='tablets and web performance'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh4.googleusercontent.com/-hck5vmLmpJw/Ti9tLBmA88I/AAAAAAAACDE/8Tiqv7Ra0VY/s72-c/dromaeo-tablets.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-4148355704743531603</id><published>2011-07-06T09:10:00.003+02:00</published><updated>2011-07-06T20:42:38.041+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qtwebkit'/><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='optimization'/><category scheme='http://www.blogger.com/atom/ns#' term='effect'/><category scheme='http://www.blogger.com/atom/ns#' term='opengl'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>fluid animation with accelerated composition</title><content type='html'>&lt;p&gt;Those who work on web-based applications on mobile platforms often recall the advice, &amp;quot;Use translate3d to make sure it's hardware accelerated&amp;quot;. This advice seems magical at first, and I seldom find anyone who explains (or wants to explain) the actual machinery behind such a practical tip.&lt;p&gt;

&lt;p&gt;For a while, Safari (and Mobile Safari) was the only WebKit-based browser which supports hardware-accelerated CSS animation. Google Chrome caught up, QtWebKit-powered browser (like the one in Nokia N9) also finally supported it. Such a situation often gave the wrong impression that Apple kept the hardware-acceleration code for themselves.&lt;p&gt;

&lt;p&gt;The above two are basically the reasons for this blog post.&lt;p&gt;

&lt;p&gt;In case you miss it (before we dive in further), please read what I wrote before about &lt;a href="http://ariya.blogspot.com/2011/06/your-webkit-port-is-special-just-like.html"&gt;different WebKit ports&lt;/a&gt; (to get the idea of implementation + back-end approach) and &lt;a href="http://ariya.blogspot.com/2011/06/progressive-rendering-via-tiled-backing.html"&gt;tiled backing store&lt;/a&gt; (decoupling web page complexity with smooth UX). The GraphicsContext abstraction will be specially useful in this topic. In particular, because animation is tightly related to efficient graphics.&lt;/p&gt;

&lt;p&gt;Imagine if you have to move an image (of a unicorn, for example) from one position to another. The pseudo-code for doing it would be:&lt;/p&gt;

&lt;pre&gt;
  for pos = startPosition to endPosition
    draw unicorn at pos
&lt;/pre&gt;

&lt;p&gt;To ensure smooth 60fps, your inner loop has only 16 ms to draw that unicorn image. Usually this is a piece of cake because all the CPU does is sending the pixels of the unicorn image &lt;b&gt;once&lt;/b&gt; to the GPU (in the form of texture) and then just &lt;b&gt;refer&lt;/b&gt; the texture inside the animation loop. No heavy work is needed on the CPU and GPU sides.&lt;/p&gt;

&lt;p&gt;If, however, what you draw is very complicated, e.g. formatted text consisting of different font typefaces and sizes, this gets hairy. The &amp;quot;draw&amp;quot; part can take more than 16 ms and the animation is not butter-smooth anymore. Because your text does &lt;b&gt;not&lt;/b&gt; really change during the animation, &lt;b&gt;only the position&lt;/b&gt; changes, the usual trick is to cache the text, i.e. draw it onto a buffer and just move around the buffer as needed. Again, the CPU just needs to push the buffer the GPU once:&lt;/p&gt;

&lt;pre&gt;
    prepare a temporary buffer
    draw the text onto the buffer
    for pos = startPosition and endPosition
       set a new transformation matrix for the buffer
&lt;/pre&gt;

&lt;p&gt;As you can imagine, that's exactly what happens when WebKit performs CSS animation. Instead of drawing your div (or whatever you animate) multiple times in different position, it prepares a layer and redirect the drawing there. After that, animation is a simple matter of manipulating the layer, e.g. moving it around. WebKit term for this (useful if you comb the source code) is &lt;strike&gt;accelerated composition&lt;/strike&gt; &lt;b&gt;accelerated compositing&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;Side note: Mozilla has the &lt;a href="http://hacks.mozilla.org/2010/09/hardware-acceleration/"&gt;same concept&lt;/a&gt;, available since Firefox 4, called &lt;a href="http://www.basschouten.com/blog1.php/layers-cross-platform-acceleration"&gt;Layer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you understand immediate vs retain mode rendering, non-composited vs composited is just like that. The idea to treat the render tree more like &lt;a href="http://en.wikipedia.org/wiki/Scene_graph"&gt;a scene graph&lt;/a&gt;, a stack of layers with different depth value.&lt;/p&gt;

&lt;p&gt;Because composition reduces the computation burden (GPU can handle varying transformation matrix efficiently), the animation is smoother. This is not so noticeable if you have a modern machine. In the following video demo (&lt;a href="http://youtu.be/KujWTTRkPkM"&gt;http://youtu.be/KujWTTRkPkM&lt;/a&gt;), I have to use my slightly old Windows laptop to demonstrate the frames/second differences:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="640" height="510" src="http://www.youtube.com/embed/KujWTTRkPkM?rel=0" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt;

&lt;p&gt;The excellent &lt;a href="http://www.webkit.org/blog-files/leaves/"&gt;falling leaves&lt;/a&gt; animation is something you have seen before, back when &lt;a href="http://www.webkit.org/blog/324/css-animation-2/"&gt;WebKit support&lt;/a&gt; for CSS animation was announced. &lt;/p&gt;

&lt;p&gt;Accelerated composition does not magically turn every &lt;a href="http://trac.webkit.org/wiki#WebKitPorts"&gt;WebKit ports&lt;/a&gt; capable of doing fluid animation. Analog to my previous  &lt;a href="http://ariya.blogspot.com/2011/06/your-webkit-port-is-special-just-like.html"&gt;rounded corner example&lt;/a&gt;, composition requires the support from the underlying platform. On Mac OS X port of WebKit, composition is mapped into &lt;a href="http://developer.apple.com/graphicsimaging/coreanimation/"&gt;CoreAnimation&lt;/a&gt; (part of CoreGraphics), the official API to have animated user interface. Same goes for iOS WebKit. On Chromium, it is hooked into &lt;a href="https://sites.google.com/a/chromium.org/dev/developers/design-documents/gpu-accelerated-compositing-in-chrome
    "&gt;sandboxed GPU process&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With &lt;a href="http://developer.qt.nokia.com/wiki/QtWebKit"&gt;QtWebKit&lt;/a&gt;, composition is achieved via &lt;a href="http://doc.qt.nokia.com/4.7/graphicsview.html"&gt;Graphics View&lt;/a&gt; framework (read &lt;a href="http://labs.qt.nokia.com/2010/01/13/hardware-accelerated-css-animations-in-qtwebkit/"&gt;Noam's explanation&lt;/a&gt; for details). The previous video you have seen was created with QtWebKit, running without and with composition, i.e. &lt;a href="http://doc.qt.nokia.com/4.7/qgraphicswebview.html"&gt;QGraphicsWebView&lt;/a&gt; with different &lt;a href="http://doc.qt.nokia.com/4.7/qwebsettings.html#WebAttribute-enum"&gt;AcceleratedCompositingEnabled run-time setting&lt;/a&gt;. If you want to check out the code and try it yourself, head to the usual &lt;a href="https://github.com/ariya/X2"&gt;X2 repository&lt;/a&gt; and look under &lt;a href="https://github.com/ariya/X2/tree/master/webkit/composition"&gt;webkit/composition&lt;/a&gt;. Use spacebar (or mouse click) to switch between composited and non-composited mode. If there is no significant frame rate improvement, increase NUMBER_OF_LEAVES in leaves.js and rebuild. When compositing is active, press D to draw thin yellow border around each layer. Since it's all about Graphics View, this debugging is easy to implement. I just inject a custom BorderEffect, based on &lt;a href="http://doc.qt.nokia.com/4.7/qgraphicseffect.html"&gt;QGraphicsEffect&lt;/a&gt; (which &lt;a href="http://ariya.blogspot.com/2009/09/wanna-curve-away-its-such-perfect-day.html"&gt;I did prototype&lt;/a&gt; back when I was with Nokia):&lt;/p&gt;

&lt;p&gt;&lt;img src="https://lh6.googleusercontent.com/-cwB1wuJVBk0/ThLPu2iIeQI/AAAAAAAAB-Y/jKaWd-q4pUs/s800/leaves.png" /&gt;&lt;/p&gt;

&lt;p&gt;Thus, there is nothing like hidden secret with respect to Safari hardware-accelerated CSS support. In fact, Safari is not different than other Mac apps. If you compile WebKit yourself and build an application with it, you would definitely get the animation with hardware acceleration support.&lt;/p&gt;

&lt;p&gt;As the bonus, since Mac and iOS WebKit delegate the animation to CoreAnimation (CA), you can use various &lt;a href="http://lists.apple.com/archives/quartz-dev/2008/Oct/msg00048.html"&gt;CA tweaks to debug it&lt;/a&gt;. CA_COLOR_OPAQUE=1 will emphasize each layer with red color overlay (as in the demo). While this applies to any CA-based apps (not limited to WebKit or Safari), it's still very useful nevertheless. Chromium's similar feature is  &lt;a href="https://sites.google.com/a/chromium.org/dev/developers/design-documents/gpu-accelerated-compositing-in-chrome"&gt;--show-composited-layer-border command line option&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;How does WebKit determine what to composited? Since the goal is to fully take advantage of the GPU, there are few particular operations which are suitable for such a composition. Among others are transparency (opacity &amp;lt; 1.0) and transformation matrix. Ideally we would just use composition for the entire web page. However, composition implies a higher memory allocation and a quite capable graphics processor. On mobile platforms, these two translate into additional critical factor: power consumption. Thus, one just needs to draw a line somewhere and stick with it. Hence, that's why currently (on iOS) translate3d and scale3d are using composition and their 2-D counterparts are not. &lt;b&gt;Addendum&lt;/b&gt;: on the desktop WebKit, all transformed element is accelerated, regardless whether it's 2-D or 3-D.&lt;/p&gt;

&lt;p&gt;If you make it this far, here are few final twists.&lt;/p&gt;

&lt;p&gt;First of all, just like the &lt;a href="http://ariya.blogspot.com/2011/06/progressive-rendering-via-tiled-backing.html"&gt;tiled backing store&lt;/a&gt; approach I explained before, accelerated composition does not force you to use the graphics processor for &lt;b&gt;everything&lt;/b&gt;. For efficiency, your layer (backing store) might be mapped to GPU textures. However, you are &lt;b&gt;not&lt;/b&gt; obligated to prepare the layer, i.e. drawing onto it, using the GPU. As an example, you can use a software rasterizer to draw to a buffer which will be mapped to OpenGL texture.&lt;/p&gt;

&lt;p&gt;In fact, a further variation of this would be not to use the GPU at all. This may come as a surprise to you but Android 2.2 (Froyo) added composition support (see &lt;a href="http://android.git.kernel.org/?p=platform/external/webkit.git;a=commitdiff;h=f4cefb93"&gt;the commit&lt;/a&gt;), albeit doing everything with in software (via its &lt;a href="http://code.google.com/p/skia/"&gt;Skia graphics engine&lt;/a&gt;). The advantage is of course not that great (compared to using OpenGL ES entirely), however the improvement is really obvious. If you have two Android phones (of the same hardware specification), one still running the outdated 2.1 (Eclair) and the other with Froyo, just open the &lt;a href="http://www.webkit.org/blog-files/leaves/"&gt;Falling Leaves demo&lt;/a&gt; and watch the frame rate difference.&lt;/p&gt;

&lt;p&gt;With the non-GPU composition-based CSS animation in Froyo, translate3d and other similar tricks do not speed-up anything significantly. In fact, it may haunt you with bugs. For example, placing form elements in a div could wreck the touch events accuracy, mainly because the hit test procedures forget to take into account that the composited layer has moved. Things which seem to work just fine Eclair may start behaving weird under Froyo and Gingerbread. If that happens to you, check your CSS properties.&lt;/p&gt;

&lt;p&gt;Fortunately (or unfortunately, depending on your point of view), Android madness with accelerated composition is getting better with Honeycomb and further upcoming releases. Meanwhile, just take it for granted that your magical translate3d spell has no effect on the green robots.&lt;/p&gt;

&lt;p&gt;Last but not least, I'm pretty excited with the &lt;a href="http://labs.qt.nokia.com/2011/05/09/thoughts-about-qt-5/"&gt;lightweight scene graph&lt;/a&gt; direction in the upcoming Qt 5. If any, this will become a better match for QtWebKit accelerated composition compared to the current Graphics View solution. This would totally destroy the myth (or misconception) that &lt;i&gt;only native apps&lt;/i&gt; can take advantage of OpenGL (ES). Thus, if you decide to use web technologies via QtWebKit (possibly through the &lt;a href="http://ariya.blogspot.com/2011/05/meego-conf-2011.html"&gt;hybrid approach&lt;/a&gt;), your investment would be future-attractive!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-4148355704743531603?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/4148355704743531603/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=4148355704743531603' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/4148355704743531603'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/4148355704743531603'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2011/07/fluid-animation-with-accelerated.html' title='fluid animation with accelerated composition'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/KujWTTRkPkM/default.jpg' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-2277374854219614742</id><published>2011-07-03T06:56:00.001+02:00</published><updated>2011-07-03T06:57:08.967+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qtwebkit'/><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='phantomjs'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>birds of paradise</title><content type='html'>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/5896075342/" title="bird of paradise by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm6.static.flickr.com/5277/5896075342_9a3118666f.jpg" width="500" height="333" alt="bird of paradise" style="border: 1px solid #ccc; padding: 5px"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://phantomjs.org"&gt;PhantomJS&lt;/a&gt;, the headless &lt;a href="http://developer.qt.nokia.com/wiki/QtWebKit"&gt;QtWebKit&lt;/a&gt; tool, is now listed as &lt;a href="http://qt.nokia.com/qt-in-use/ambassadors/project?id=a0F20000006LfP2EAK"&gt;one of the Qt Ambassador&lt;/a&gt; show cases. There is also a growing list of &lt;a href="http://code.google.com/p/phantomjs/wiki/WhoUsesPhantomJS"&gt;projects using PhantomJS&lt;/a&gt; (let me know if you want to be listed). In fact, PhantomJS running in several Amazon EC2 instances is used as the primary tool in a web &lt;a href="http://williamhli.com/papers/li-shin.pdf"&gt;security analysis&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Few days ago, right during the summer solstice, I tagged and released PhantomJS 1.2, codenamed &lt;a href="http://code.google.com/p/phantomjs/wiki/ReleaseNames"&gt;Birds of Paradise&lt;/a&gt;. There are some exciting changes there that I will briefly outline as follows (for details, see the &lt;a href="http://code.google.com/p/phantomjs/wiki/ReleaseNotes"&gt;Release Notes&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Most important change is the fix to the security model. Your PhantomJS script now does not run in the context of the loaded &lt;a href="http://doc.qt.nokia.com/qwebpage.html"&gt;QWebPage&lt;/a&gt; anymore (more precisely, the main frame thereof). Rather, we have a new WebPage object that abstracts (surprise) the web page. This forces a major breakage in the API since there is no way to support 1.1 style of API with the same code. Again, check the Release Notes to find out how to migrate your script.&lt;/p&gt;

&lt;p&gt;The bonus with the above WebPage object abstraction is a bunch of external callbacks we can set up, most notably onLoadStarted and onLoadFinished, useful to trigger some actions upon &lt;a href="http://code.google.com/p/phantomjs/wiki/QuickStart#Loading"&gt;page loading&lt;/a&gt;. Speaking of JavaScript evaluation, &lt;a href="http://www.nczonline.net/blog/2009/06/23/loading-javascript-without-blocking/"&gt;dynamic script tag loading&lt;/a&gt; is a quite popular trick to asynchronously load external libraries, e.g. those part of &lt;a href="http://code.google.com/apis/libraries/"&gt;Google Libraries API&lt;/a&gt;. Rather than writing your own code, there is now easy-to-use &lt;a href="http://code.google.com/p/phantomjs/wiki/ServiceIntegration#External_Library"&gt;includeJS() function&lt;/a&gt; for that specific purpose.&lt;/p&gt;

&lt;p&gt;My personal #1 favorite feature is the simple &lt;a href="http://code.google.com/p/phantomjs/wiki/QuickStart#Network_traffic"&gt;network traffic analysis&lt;/a&gt;. I already demonstrated the technique before, i.e. by subclassing &lt;a href="http://doc.qt.nokia.com/qnetworkaccessmanager.html"&gt;QNetworkAccessManager&lt;/a&gt; and recording the major network activities (see &lt;a href="http://ariya.blogspot.com/2010/05/qnetworkaccessmanager-tracenet-speed.html"&gt;my previous blog post&lt;/a&gt; discussing this in details). The new PhantomJS example script netsniff.js shows the use of this feature: it logs network requests and responses and dumps them in &lt;a href="http://www.softwareishard.com/blog/firebug/http-archive-specification/"&gt;HTTP Archive&lt;/a&gt; (HAR) format. You can then use &lt;a href="http://www.softwareishard.com/har/viewer/"&gt;online HAR viewer&lt;/a&gt; to see the waterfall diagram, or post-process the data the way you like it. For example, here is what BBC News web site produced:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://lh6.googleusercontent.com/-xoooH5EB6EE/TgnyJ3r9sRI/AAAAAAAAB98/wYJ_VoWED34/s640/bbc-har.png"&gt;&lt;/p&gt;

&lt;p&gt;Since the entire traffic capture can be fully automated, you can have it checked against various rules. For example, you may want to ensure that KDE.org does not get significantly slower (in terms of page loading) every time someone changes the web site design. Perhaps you want to compare the resource loading with gnome.org just to confirm that it loads faster. Gathering the stats of the same site from different geographical locations might also reveal how the web page is perceived by some fans on the other side of the planet.&lt;/p&gt;

&lt;p&gt;The use of mobile devices for consuming information is exploding. It would be fun to see PhantomJS leveraged to get the metrics behind the data traffic. I haven't bothered yet to port and test PhantomJS on Qt-based Harmattan-powered phone like the new shiny &lt;a href="http://en.wikipedia.org/wiki/Nokia_N9"&gt;Nokia N9&lt;/a&gt;. Of course, if you a spare one, feel free to Fedex me :)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-2277374854219614742?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/2277374854219614742/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=2277374854219614742' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2277374854219614742'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2277374854219614742'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2011/07/birds-of-paradise.html' title='birds of paradise'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm6.static.flickr.com/5277/5896075342_9a3118666f_t.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-3643284936858998472</id><published>2011-06-30T18:03:00.003+02:00</published><updated>2011-06-30T18:19:24.807+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='webgl'/><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='sencha'/><category scheme='http://www.blogger.com/atom/ns#' term='musing'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='optimization'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>quaternion multiplication: two years later</title><content type='html'>&lt;p&gt;Sometime back &lt;a href="http://ariya.blogspot.com/2010/07/faster-quaternion-multiplication.html"&gt;I wrote&lt;/a&gt; (fun fact: it's Google first hit for &lt;a href="http://www.google.com/search?q=faster+quaternion+multiplication"&gt;faster quaternion multiplication&lt;/a&gt;) about my favorite commit I did exactly two years ago to Qt :&lt;/p&gt;

&lt;pre&gt;git show &lt;a href="http://qt.gitorious.org/qt/qt/commit/cbc22908"&gt;cbc22908&lt;/a&gt;
commit cbc229081a9df67a577b4bea61ad6aac52d470cb
Author: Ariya Hidayat 
Date:   Tue Jun 30 11:18:03 2009 +0200

    Faster quaternion multiplications.
    
    Use the known factorization trick to speed-up quaternion multiplication.
    Now we need only 9 floating-point multiplications, instead of 16 (but
    at the cost of extra additions and subtractions).
&lt;/pre&gt;

&lt;p&gt;Ages ago, during my &lt;a href="http://ariya.blogspot.com/2008/11/world-fastest-optical-polarization.html"&gt;Ph.D research&lt;/a&gt;, when I worked with a certain hardware platform (hint: it's not generalized CPU), minimizing the needed number of hardware multipliers with a very little impact in the computation speed makes a huge different. With today's advanced processor architecture armed with vectorized instructions and a really smart optimizing compiler, there is often no need to use the factorized version of the multiplication.&lt;/p&gt;

&lt;p&gt;Side note: if you want to like quaternion, see this simple &lt;a href="http://ariya.blogspot.com/2007/11/fun-with-rotations.html"&gt;rotatation quiz&lt;/a&gt; which can be solved quite easily once you know quaternion.&lt;/p&gt;

&lt;p&gt;I try to apply the same trick to &lt;a href="http://senchalabs.github.com/philogl"&gt;PhiloGL&lt;/a&gt;, an excellent WebGL framework from &lt;a href="http://philogb.github.com/"&gt;Nicolas&lt;/a&gt;. Recently, to my delight, he added &lt;a href="https://github.com/senchalabs/philogl/commit/65ba70df"&gt;quaternion support&lt;/a&gt; to the accompanying math library in PhiloGL. I think this is a nice chance to try the old trick, as I had the expectation that reducing the number of multiplications from 16 to just 9 could give some slight performance advantage.&lt;/p&gt;

&lt;p&gt;It turns out that it is not the case, at least based on the benchmark tests running on modern browsers with very capable JavaScript engine. You can try the test yourself at &lt;a href="http://jsperf.com/quaternion-multiplication"&gt;jsperf.com/quaternion-multiplication&lt;/a&gt;. I have no idea whether this is due to JSPerf (very unlikely) or it's simply because the longer construct of the factorized version does not really speed-up anything. If any, seems that the amount of executed instruction matters more than whether addition is much faster than multiplication. And of course, we're talking about modern CPU, the difference is then becoming more subtle.&lt;/p&gt;

&lt;p&gt;With the help of Nicolas, I tried various other tricks to help the JavaScript engine, mainly around different ways to prepare the persistent temporary variables: using normal properties, using Array, using Float32Array (at the cost of precision). Nothing leads to any significant improvement.&lt;/p&gt;

&lt;p&gt;Of course if you have other tricks in your sleeve, I welcome you to try it with the benchmark. Meanwhile, let's hope that someday some JavaScript engine will run the factorized version faster. It's just a much cooler way to multiply quaternions!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-3643284936858998472?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/3643284936858998472/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=3643284936858998472' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/3643284936858998472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/3643284936858998472'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2011/06/quaternion-multiplication-two-years.html' title='quaternion multiplication: two years later'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-1085124302545683434</id><published>2011-06-27T09:31:00.002+02:00</published><updated>2011-06-27T09:37:37.385+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qtwebkit'/><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='svg'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='optimization'/><category scheme='http://www.blogger.com/atom/ns#' term='opengl'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>progressive rendering via tiled backing store</title><content type='html'>&lt;p&gt;Imagine you have to create a CAD-grade application, e.g. drawing the entire wireframe of a space shuttle or showing the intricacies of 9-layer printed circuit board. Basically something that involves a heavy work to display the result on the screen. On top of that, the application is still expected to perform smoothly in case the user wants to pan/scroll around and zoom in/out.&lt;/p&gt;

&lt;p&gt;The usual known trick to achieve this is by employing a &lt;b&gt;backing store&lt;/b&gt;, i.e. &lt;a href="http://en.wikipedia.org/wiki/Screen_buffer"&gt;off-screen buffer&lt;/a&gt; that serves as the target for the drawing operations. The user interface then takes the &lt;a href="http://labs.qt.nokia.com/2007/08/09/qt-invaded-by-aliens-the-end-of-all-flicker/"&gt;backing store&lt;/a&gt; and displays it to the user. Now panning is a matter of translation and zooming is just scaling. The backing store can be updated asynchronously, thus making the user interaction decoupled from the complexity of the rendering. &lt;/p&gt;

&lt;p&gt;Moving to a higher ninja level, the backing store can be &lt;b&gt;tiled&lt;/b&gt;. Instead of just one giant snapshot of the rendering output, it is broken down to small tiles, say 128x128 pixels. The nice thing is because each tile can be mapped as a &lt;a href="http://www.opengl.org/resources/faq/technical/texture.htm"&gt;texture&lt;/a&gt; in the GPU, e.g. via glTexImage2D. &lt;a href="http://www.gamedev.net/page/resources/_/reference/programming/opengl/269/opengl-texture-mapping-an-introduction-r947"&gt;Drawing each textured tile&lt;/a&gt; is also a (tasty) piece of cake, GL_QUAD with &lt;a href="http://www.opengl.org/sdk/docs/man/xhtml/glBindTexture.xml"&gt;glBindTexture&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Another common use-case for tiling is for online maps. You probably use it every day without realizing it in Google Maps, OpenStreetMap, or other similar services. In this case, the reason is to use tiles is mainly to ease the network aspect. Instead of sending a huge image representing the area seen by the user in the viewport, actually lots of small images are transported and stitched together by the client code in the web browser.&lt;/p&gt;

&lt;p&gt;Here is an illustration of the concept. The border of each tile is emphasized. The faded area is what you don't see (outside the viewport). Of course every time you pan and zoom, new fresh tiles are fetched so as to cover the viewport as much as possible.&lt;/p&gt;

&lt;p&gt;&lt;img src="https://lh6.googleusercontent.com/-0ONkN3uPmiM/Tggb3aIIKjI/AAAAAAAAB9k/6UVPAoRNKes/s800/tiledmaps.png" width="600" height="400"/&gt;&lt;/p&gt;

&lt;p&gt;When I started to use the first generation iPhone years ago, I realized that the browser (or rather, its WebKit implementation) uses the very similar trick. Instead of drawing the web page straight to the screen, it uses a tiled backing store. Zooming (via pinching) becomes really cheap, it's a matter of scaling up and down. Flicking is the same case, translating textures does not bother any mobile GPU that much.&lt;/p&gt;

&lt;p&gt;Every iOS users know that if you manage to beat the browser and flick fast enough, it tries to catch up and fills the screen as fast as possible but every now and then you'll see some sort of &lt;b&gt;checkerboard pattern&lt;/b&gt;. That is actually the &lt;b&gt;placeholder&lt;/b&gt; for tiles which are not ready yet.&lt;/p&gt;

&lt;p&gt;Since all the geeks out there likely better understand the technique with a piece of code, I'll not waste more paragraphs and present you this week's X2 example: full-featured implementation of tiled backing store in &amp;lt; 500 lines of Qt and C++. You can get the code from the usual &lt;a href="https://github.com/ariya/X2"&gt;X2 git repository&lt;/a&gt;, look under &lt;a href="https://github.com/ariya/X2/tree/master/graphics/backingstore"&gt;graphics/backingstore&lt;/a&gt;. When you compile and launch it, use mouse dragging to pan around and mouse wheel to zoom in/out. For the impatient, see the following 50-second screencast (or &lt;a href="http://www.youtube.com/watch?v=xdLQl7d00Ak"&gt;watch directly&lt;/a&gt; on YouTube):&lt;/p&gt;

&lt;iframe width="640" height="390" src="http://www.youtube.com/embed/xdLQl7d00Ak?rel=0" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;For this particular trick, what you render actually does not matter much (it could be anything). To simplify the code, I do not use WebKit and instead just focus on SVG rendering, in particular of that famous &lt;a href="http://ariya.github.com/svg/tiger.svg"&gt;Tiger head&lt;/a&gt;. The code should be pretty self-explanatory, especially for the TextureBuffer class, but here is some random note for your pleasure.&lt;/p&gt;

&lt;p&gt;At the beginning, every tile is invalid (=0). Every time the program needs to draw a tile, it checks first if the tile is valid or not. If yes, it substitutes it with the checkerboard pattern instead (also called the &lt;i&gt;default texture&lt;/i&gt;) and triggers an &lt;i&gt;asynchronous update&lt;/i&gt; process. During the update, the program looks for the most important tile which needs to be updated (usually the one closes to the viewport center). What is a tile update? It's the actual rendering of the SVG, clipped exactly to the rectangular bounding box represented by the tile, into a texture.&lt;/p&gt;

&lt;p&gt;To show the mix-n-match, I actually use Qt built-in &lt;a href="http://labs.qt.nokia.com/2009/12/18/qt-graphics-and-performance-the-raster-engine/"&gt;software rasterizer&lt;/a&gt; to draw the SVG. That demonstrates that, even though each tile is essentially an OpenGL texture, you are not forced to use OpenGL to prepare the tile itself. This is essentially mixing &lt;b&gt;rasterization done by the CPU&lt;/b&gt; with the &lt;b&gt;texture management handled by the GPU&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;As I mentioned before, panning is a matter of adjusting the translation offset. Zooming is tricky, it involves scaling up (or down) the textures appropriately. At the same time, it also triggers an asynchronous refresh. The refresh function is nothing but to reset all the tiles to invalid again, which in turns would update each one by one. This gives the following effect (illustrated in the screenshot below). If suddenly you zoom in, you would see &lt;b&gt;pixelated&lt;/b&gt; rendering (left). After a certain refresh delay, the tile update makes the rendering &lt;b&gt;crisp&lt;/b&gt; again (right).&lt;/p&gt;

&lt;p&gt;&lt;img src="https://lh6.googleusercontent.com/-jD4rcrpqUu0/TgWBoEuAAKI/AAAAAAAAB9I/_t5KwA6Enhk/s800/gltiger_zoom.png" width="600" height="260" alt="Zooming GLTiger"/&gt;&lt;/p&gt;

&lt;p&gt;Because we still need to have the outdated tiles scaled up/down (those pixelated ones), we have to keep them around for a while until the refresh process is completed. This is why there is another texture buffer called the &lt;i&gt;secondary background buffer&lt;/i&gt;. Rest assured, when none of the tiles in the background buffer is needed anymore, the buffer is flushed.&lt;/p&gt;

&lt;p&gt;If you really want to follow the update and refresh, try to uncomment the debug compiler define. Beside showing the individual tiles better, that flag would also intentionally slows down both update and refresh so your eyes can have more time to trace them.&lt;/p&gt;

&lt;p&gt;BTW how would you determine the tile dimension in pixels? Unfortunately this can vary from one hardware to another. Ideally it's not too small because you'd enjoy the penalty of logical overdraw. If it's too large, you might not be progressive enough. Trial and error, that can be your enlightenment process.&lt;/p&gt;

&lt;p&gt;Being an example, this program has a lot of simplifications. First of all, usually you want the tile update to take place in a &lt;b&gt;separate thread&lt;/b&gt;, and probably updating few tiles at once. With a proper thread affinity, this helps improving the overall perceptive smoothness. Also, in case you know upfront that it does not impact the performance that much, using &lt;a href="http://gregs-blog.com/2008/01/17/opengl-texture-filter-parameters-explained/"&gt;texture filtering&lt;/a&gt; (instead of just GL_NEAREST) for the scaling would give a better zooming illusion.&lt;/p&gt;

&lt;p&gt;You might also see that I decided not to use the tile cache approach in the texture buffer. This is again done for simplicity. The continuous pruning of unused textures ensures that we actually don't grow the textures and kill the GPU. If you really insist on the absolutely minimal amount of overdraw and texture usage, then go for a slightly complicated cache system.&lt;/p&gt;

&lt;p&gt;Since I'm lazy, the example is using Open GL and quad drawing. If you want to run it on a mobile platform, you have patch it so that it works with Open GL ES. In all cases, converting it to use &lt;a href="http://stackoverflow.com/questions/1116376/opengl-quad-rendering-optimization"&gt;vertex and texture arrays&lt;/a&gt; is likely a wise initial step. While you are there, hook the &lt;a href="http://doc.qt.nokia.com/qtouchevent.html"&gt;touch events&lt;/a&gt; so you can also do the pinch-to-zoom effect.&lt;/p&gt;

&lt;p&gt;If you are brave enough, here is another nice final finish (as suggested by &lt;a href="http://blog.thejit.org/"&gt;Nicolas&lt;/a&gt; of InfoVis and PhiloGL fame). When you zoom in, the tiles in the center are prioritized. However, when you zoom out, the tiles nearby the viewport border should get the first priority, in order to fill the viewport as fast as possible.&lt;/p&gt;

&lt;p&gt;Progressive rendering via a tiled backing store is the easiest way to take advantage of graphics processor. It's of course just one form, probably the simplest one, of hardware acceleration.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-1085124302545683434?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/1085124302545683434/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=1085124302545683434' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1085124302545683434'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1085124302545683434'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2011/06/progressive-rendering-via-tiled-backing.html' title='progressive rendering via tiled backing store'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh6.googleusercontent.com/-0ONkN3uPmiM/Tggb3aIIKjI/AAAAAAAAB9k/6UVPAoRNKes/s72-c/tiledmaps.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-8222658530873639291</id><published>2011-06-10T10:07:00.002+02:00</published><updated>2011-06-10T18:07:36.962+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qtwebkit'/><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='musing'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><title type='text'>your webkit port is special (just like every other port)</title><content type='html'>&lt;p&gt;One of the most often question I got, &amp;quot;Since browser Foo and browser Bar are using the &lt;b&gt;same&lt;/b&gt; WebKit engine, why do I get &lt;b&gt;different&lt;/b&gt; feature set?&amp;quot;.&lt;/p&gt;

&lt;p&gt;Let's step aside a bit. Boeing 747, a very popular airliner, uses Pratt &amp; Whitney JT9D engine. So does Airbus A310. Do you expect both planes to have the same flight characteristics? Surely not, there are other bazillion factors which decide how that big piece of metal actually flies. In fact, you would not expect A310-certified pilot to just jump into 747 cockpit and land it.&lt;/p&gt;

&lt;p&gt;(Aviation fans, please forgive me if the above analogy is an oversimplification).&lt;/p&gt;

&lt;p&gt;WebKit, as a web rendering engine, is designed to use a lot of (semi)abstract &lt;b&gt;interfaces&lt;/b&gt;. These interfaces obviously require (surprise) some &lt;b&gt;implementation&lt;/b&gt;. Example of such interfaces are network stack, mouse + key handling, thread system, disk access, memory management, graphics pipeline, etc.&lt;/p&gt;

&lt;p&gt;What is the popular reference to WebKit is usually Apple's own flavor of WebKit which runs on Mac OS X (&lt;a href="http://lists.kde.org/?l=kfm-devel&amp;amp;m=104197092318639&amp;amp;w=2"&gt;the first and the original&lt;/a&gt; WebKit library). As you can guess, the various interfaces are implemented using different native libraries on Mac OS X, mostly centered around &lt;a href="http://developer.apple.com/corefoundation/
"&gt;CoreFoundation&lt;/a&gt;. For example, if you specify a flat colored button with specific border radius, well WebKit knows where and how to draw that button. However, the final actual responsibility of &lt;b&gt;drawing the button&lt;/b&gt; (as pixels on the user's monitor) falls into &lt;a href="http://developer.apple.com/library/ios/#documentation/CoreGraphics/Reference/CoreGraphics_Framework/_index.html"&gt;CoreGraphics&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With time, WebKit was &amp;quot;ported&amp;quot; into different platform, both desktop and mobile. Such flavor is often called "WebKit port". For Safari Windows, Apple themselves also ported WebKit to run on Windows, using the &lt;a href="http://developer.apple.com/opensource/internet/webkit_sptlib_agree.html"&gt;Windows version&lt;/a&gt; of its (limited implementation of) CoreFoundation library.&lt;/p&gt;

&lt;p&gt;Beside that, there were many other &amp;quot;ports&amp;quot; as well (see &lt;a href="http://trac.webkit.org/wiki#WebKitPorts"&gt;the full list&lt;/a&gt;). Via its Chrome browser (and the Chromium sister project), Google has created and continues to maintain its Chromium port. There is also WebKitGtk which is based on Gtk+. Nokia (through Trolltech, which it acquired) maintains the Qt port of WebKit, popular as its &lt;a href="http://doc.qt.nokia.com/qtwebkit.html"&gt;QtWebKit module&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;(This explains why any beginner scream like &amp;quot;Help! I can't build WebKit on platform FooBar&amp;quot; would likely get an &lt;a href="https://lists.webkit.org/pipermail/webkit-help/2009-August/000146.html"&gt;instant reply&lt;/a&gt; &amp;quot;Which port are you trying to build?&amp;quot;).&lt;/p&gt;

&lt;p&gt;Consider QtWebKit, it's even possible (through customized &lt;a href="http://doc.qt.nokia.com/qnetworkaccessmanager.html"&gt;QNetworkAccessManager&lt;/a&gt;, thanks to Qt network modularity) to hook a different network backend. This is for example what is being done for KDEWebKit module so that it becomes the Qt port of WebKit which actually uses KDE libraries to access the network.&lt;/p&gt;

&lt;p&gt;If we come back to the rounded button example, again the real drawing is carried out in the actual graphics library used by the said WebKit port. Here is a simplified diagram that shows the mapping:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://lh6.googleusercontent.com/--WfQB-Tr1sQ/TfHQSfY38FI/AAAAAAAAB8s/DSNAn8F71i8/s800/graphicscontext.png"&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://trac.webkit.org/browser/trunk/Source/WebCore/platform/graphics/GraphicsContext.h"&gt;GraphicsContext&lt;/a&gt; is the interface. All other code inside WebKit will not &amp;quot;speak&amp;quot; directly to e.g. CoreGraphics on Mac. In the above rounded button example, it will call GraphicsContext's fillRoundedRect() function.&lt;/p&gt;

&lt;p&gt;There are various implementation of GraphicsContext, depending on the port. For Qt, you can see how it is done in &lt;a href="http://trac.webkit.org/browser/trunk/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp#L744"&gt;GraphicsContextQt.cpp&lt;/a&gt; file.&lt;/p&gt;

&lt;p&gt;Should you know a little bit about graphics, you would realize that there are different methods and algorithms to &lt;a href="http://en.wikipedia.org/wiki/Rasterisation"&gt;rasterize&lt;/a&gt; a filled rounded rectangle. A certain approach is to convert it to a &lt;a href="http://doc.qt.nokia.com/qpainterpath.html#toFillPolygon"&gt;fill polygon&lt;/a&gt;, another one is to scanline-convert the rounded corner directly. A fully GPU-based system may prefer working with tessellated &lt;a href="http://en.wikipedia.org/wiki/Triangle_strip"&gt;triangle strips&lt;/a&gt;, or even with shader. Even the antialiasing level defines the outcome, too.&lt;/p&gt;

&lt;p&gt;In short, different graphic stacks with different algorithm may not produce the same result down to the exact pixel colors. It all depends various factors, including the complexity of the drawing itself.&lt;/p&gt;

&lt;p&gt;Now the same concept applies to other interfaces. For example, there is no HTTP stack inside WebKit code base. All network-aware code calls specific function to get resources off the server, post some data, etc. However, the actual implementation is in system libraries. Thus, don't bother trying to find SSL code inside WebKit.&lt;/p&gt;

&lt;p&gt;This gets us to this question, &amp;quot;If browser X is using WebKit, why it does not have feature Z?&amp;quot;. You may be able to deduce the reason. Imagine a certain graphic stack which glues GraphicsContext for that platform does not implement fillRoundedRect() function, what would happen? Yes, your rounded button suddenly becomes a &lt;b&gt;square&lt;/b&gt; button.&lt;/p&gt;

&lt;p&gt;As a matter of fact, when someone ports WebKit to a new platform, she will need to implement all these interfaces one by one. Until it is complete, of course not everything would work 100% and most likely only the basics are there. That should feel like putting a jet engine into an airframe that can't fly yet.&lt;/p&gt;

&lt;p&gt;&amp;quot;Can we have one de-facto graphics stack that powers WebKit so we always have pixel-perfect rendering expectation?&amp;quot; Technically yes, but practically no. In fact, while Boeing and Airbus may buy the same engine from Pratt &amp; Whitney, they may not want to have the exact same landing gears. Everyone of us wants to be &lt;b&gt;special&lt;/b&gt;. A certain system wants to use OpenGL ES, squeeze the best performance out of it and doesn't really care if the selling price goes up. Others want to sacrifice the speed, trim the silicon floor and make the device more affordable. More often, you just have to live with diversity.&lt;/p&gt;

&lt;p&gt;And if you want to put aside all the differences, two WebKit ports of the same revision share tons of stuff, especially if they use the same JavaScript engine. They will parse HTML and CSS in the same way, produce the same DOM, yield the same render tree, have the same JavaScript host objects, and so on.&lt;/p&gt;

&lt;p&gt;Thus, next time someone shouts &amp;quot;there is no two exact WebKit&amp;quot;, you know the story behind it.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-8222658530873639291?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/8222658530873639291/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=8222658530873639291' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8222658530873639291'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8222658530873639291'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2011/06/your-webkit-port-is-special-just-like.html' title='your webkit port is special (just like every other port)'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh6.googleusercontent.com/--WfQB-Tr1sQ/TfHQSfY38FI/AAAAAAAAB8s/DSNAn8F71i8/s72-c/graphicscontext.png' height='72' width='72'/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-2364383226613586538</id><published>2011-06-06T08:43:00.003+02:00</published><updated>2011-06-06T08:47:26.372+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='hacks'/><category scheme='http://www.blogger.com/atom/ns#' term='calligra'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>rectangular gradient</title><content type='html'>&lt;p&gt;Thorsten Zachmann, from &lt;a href="http://www.calligra-suite.org/"&gt;Calligra&lt;/a&gt; (and previously KOffice) fame, asked me once on how to draw a different kind of gradient: a rectangular one. While Qt itself has built-in supports for &lt;a href="http://doc.qt.nokia.com/4.7/demos-gradients.html"&gt;linear, radial, and conical&lt;/a&gt; gradient types, apparently for office apps we may need more than that. In short, the goal is creating the following:&lt;/p&gt;

&lt;p&gt;&lt;img src="https://lh3.googleusercontent.com/-nUN9avs8l7E/Tex2KRy5LRI/AAAAAAAAB8M/aNIefbebAgI/s800/gradient.png" width="400" height="150"/&gt;&lt;/p&gt;

&lt;p&gt;It turns out that this is not so difficult at all, about 50 lines of code. Check it out at the usual &lt;a href="http://gitorious.org/ofi-labs/X2"&gt;X2 repository&lt;/a&gt; and find it under &lt;a href="http://gitorious.org/ofi-labs/x2/trees/master/graphics/rectgradient"&gt;graphics/rectgradient&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Basically it boils down to a two-step process, as illustrated below. The first one is easy, just create a linear gradient from the center going north and south. The second one is similar, but now we are going east and west &lt;b&gt;and&lt;/b&gt; clip it to two triangles. Once we combined both, we get the rectangular gradient.&lt;/p&gt;

&lt;p&gt;&lt;img src="https://lh4.googleusercontent.com/-WZuxeN2yuGE/Tex2NDA3ZpI/AAAAAAAAB8Q/mSIC-JP6nsc/s800/rectgradient-steps.png" width="436" height="396"/&gt;&lt;/p&gt;

&lt;p&gt;Have fun with the gradient!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-2364383226613586538?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/2364383226613586538/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=2364383226613586538' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2364383226613586538'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2364383226613586538'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2011/06/rectangular-gradient.html' title='rectangular gradient'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh3.googleusercontent.com/-nUN9avs8l7E/Tex2KRy5LRI/AAAAAAAAB8M/aNIefbebAgI/s72-c/gradient.png' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-2149416898849778081</id><published>2011-05-31T00:45:00.001+02:00</published><updated>2011-05-31T00:48:02.241+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='chromium'/><category scheme='http://www.blogger.com/atom/ns#' term='musing'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='kde'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>on the story of browser names</title><content type='html'>&lt;p&gt;
&lt;a href="http://www.flickr.com/photos/ariyahidayat/5774109003/" title="future = browser? by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3014/5774109003_1fbff9bca2.jpg" width="500" height="333" alt="future = browser?" style="border: 1px solid #ddd; padding: 5px"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of the early graphical web browser that got really popular was &lt;a href="http://en.wikipedia.org/wiki/Mosaic_(web_browser)"&gt;Mosaic&lt;/a&gt;, developed at &lt;a href="http://en.wikipedia.org/wiki/National_Center_for_Supercomputing_Applications"&gt;National Center for Supercomputing Applications&lt;/a&gt; (NCSA). Some folks from the team, along with SGI founder &lt;a href="http://en.wikipedia.org/wiki/James_H._Clark"&gt;Jim Clark&lt;/a&gt;, decided that it's worth a venture and formed a company, originally called Mosaic Communication and then later renamed to &lt;a href="http://en.wikipedia.org/wiki/Netscape#History"&gt;Netscape Communication&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Netscape's flagship desktop product was a much more advanced web browser than Mosaic. Jamie Zawinski &lt;a href="http://www.jwz.org/gruntle/nscpdorm.html"&gt;coined the name&lt;/a&gt; "Mozilla", as it was supposed to be Mosaic Killer (Mozilla = Mosaic + Godzilla). At the later stage, the final browser was widely known as &lt;a href="http://en.wikipedia.org/wiki/Netscape_Navigator"&gt;Netscape Navigator&lt;/a&gt;. For &lt;b&gt;browsing the web&lt;/b&gt;, obviously you need a &lt;b&gt;navigator&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;Parallel to that, another company called Spyglass &lt;a href="http://www.ericsink.com/Browser_Wars.html"&gt;licensed the technology&lt;/a&gt; from NCSA and produced a web browser, Spyglass Mosaic. It is fun to see the same theme here (probably even slightly coincidental), typical Hollywood movies always portray the naval ship's &lt;b&gt;navigator&lt;/b&gt; using his &lt;b&gt;spyglass&lt;/b&gt; for some sort of observations.&lt;/p&gt;

&lt;p&gt;Then came along Microsoft. It &lt;a href="http://en.wikipedia.org/wiki/History_of_Internet_Explorer#1994.E2.80.931997:_Beginnings_.26_Spyglass"&gt;licensed&lt;/a&gt; Spyglass Mosaic, called it Internet Explorer, and distributed with Windows. The browser war has just started. I mean of course, the name war. Why would you stop at &lt;b&gt;navigating&lt;/b&gt; (and using spyglass) if you can continue &lt;b&gt;exploring&lt;/b&gt;?&lt;/p&gt;

&lt;p&gt;On the other side of the planet, KDE slowly emerged as the &lt;a href="http://en.wikipedia.org/wiki/KDE#Origins"&gt;attractive supplement&lt;/a&gt; to the otherwise boring Unix desktop. Internet technologies became the centerpiece of the early version of KDE, thus its developers grew a set of applications from e-mail program, newsgroup reader, IRC client, and (surprise) a web browser. There was no free-software-friendly modern and capable web rendering engine back then, thus a bunch of brave young hackers initiated &lt;a href="http://lists.kde.org/?l=kfm-devel&amp;m=93489518402924"&gt;the adventure&lt;/a&gt; of (re)writing one, under the name KHTML (which was itself a replacement of the original attempt, khtmlw).&lt;/p&gt;

&lt;p&gt;From this KDE camp, the ultimate web browser (which actually could serve other tasks as well, e.g. file manager and document viewer) was popular as &lt;a href="http://www.konqueror.org/"&gt;Konqueror&lt;/a&gt; (indeed, those were the days where KDE stuff was named K-this or K-that). History showed how Age of Discovery was not about &lt;b&gt;navigation&lt;/b&gt; and &lt;b&gt;exploration&lt;/b&gt; only. After all, who would not want to repeat the glory of "I came, I saw, &lt;b&gt;I conquered&lt;/b&gt;"?&lt;/p&gt;

&lt;p&gt;When Apple decided that it must give the best browsing experience for Mac (and could not just rely on Microsoft for its Internet Explorer), &lt;a href="http://lists.kde.org/?l=kfm-devel&amp;amp;m=104197092318639&amp;amp;w=2"&gt;they took KHTML&lt;/a&gt;, ported it to Mac, improved it, and &lt;a href="http://dot.kde.org/2005/06/07/apple-opens-webkit-cvs-and-bug-database"&gt;later released it&lt;/a&gt; as an open-source project called &lt;a href="http://www.webkit.org"&gt;WebKit&lt;/a&gt;. Apple's proprietary web browser, which is powered by WebKit (till today), was &lt;a href="http://en.wikipedia.org/wiki/Safari_(web_browser)#History_and_development"&gt;announced by Steve Jobs&lt;/a&gt; as Safari. Already &lt;b&gt;conquered&lt;/b&gt; a land? Might as well enjoy it with a little bit of &lt;b&gt;safari&lt;/b&gt; and collect exotic pictures. Shall we?&lt;/p&gt;

&lt;p&gt;Just like in your favorite comic books, the world is however multiverse. Netscape &lt;a href="http://en.wikipedia.org/wiki/Netscape_Navigator#The_fall_of_Netscape"&gt;lost&lt;/a&gt; the browser war, &lt;a href="http://en.wikipedia.org/wiki/Mozilla"&gt;Mozilla&lt;/a&gt; became an open-source project and its &lt;a href="http://en.wikipedia.org/wiki/History_of_Firefox"&gt;Firefox browser&lt;/a&gt; (formerly Firebird, and formerly Phoenix) remains as the icon of freedom, independence, and community. &lt;a href="http://www.opera.com"&gt;Opera&lt;/a&gt;, originally a Telenor research project, was something that came all the way from Norway, has loyal followers and remains dominant in the embedded space. Google even &lt;a href="http://googleblog.blogspot.com/2008/09/fresh-take-on-browser.html"&gt;joined the fun&lt;/a&gt; and launched WebKit-based Chrome (and Chromium). All these three are excellent web browsers, they just don't have the names which fit the story of navigation, exploration, and so on.&lt;/p&gt;

&lt;p&gt;As the closing, here is a side twist. In its early WebKit days, how did Apple engineers name the code branch of its ported Konqueror's KHTML? &lt;b&gt;&lt;a href="http://trac.webkit.org/browser/tags/old/Alexander-1"&gt;Alexander&lt;/a&gt;&lt;/b&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-2149416898849778081?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/2149416898849778081/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=2149416898849778081' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2149416898849778081'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2149416898849778081'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2011/05/on-story-of-browser-names.html' title='on the story of browser names'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3014/5774109003_1fbff9bca2_t.jpg' height='72' width='72'/><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-8293304296204790793</id><published>2011-05-29T01:54:00.001+02:00</published><updated>2011-05-29T01:56:32.648+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qtwebkit'/><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='meego'/><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='san francisco'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><title type='text'>meego conf 2011 impressions</title><content type='html'>&lt;p&gt;
&lt;a href="http://www.flickr.com/photos/ariyahidayat/5769851666/" title="meegoconf 2011 by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3639/5769851666_0f0516430a.jpg" width="500" height="333" alt="meegoconf 2011" style="border: 1px solid #ddd; padding: 5px"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;It's a mixed feeling. Personally it was (always) fun to meet my former coworkers from &lt;a href="http://qt.nokia.com"&gt;Qt, Nokia&lt;/a&gt; and other KDE folks and catch up and exchange tech gossips. I am also excited to get to know &lt;a href="http://appdeveloper.intel.com/meego"&gt;MeeGo team&lt;/a&gt; from Intel side as well. The conference itself is professionally organized. The &lt;a href="http://www.flickr.com/search/?q=meegoconf%20hacker%20lounge"&gt;Hacker Lounge&lt;/a&gt; idea is perfect, a basement to hang out 24 hours with free cold drinks, lots of games (from fussball to pingpong), superfast and reliable WiFi, and of course a bunch of comfy couches. &lt;a href="http://www.sanfranciscoregency.hyatt.com/hyatt/hotels/index.jsp"&gt;Hyatt Regency&lt;/a&gt; itself proves to be a really really nice venue from such a developer conference.&lt;/p&gt;

&lt;p&gt;The three-day &lt;a href="http://sf2011.meego.com/program/session-schedule"&gt;program&lt;/a&gt; was packed with tons of sessions, anything from Qt 5, Wayland, Scene Graph, Media and IVI, and various other BoFs. Lots of exciting new technologies coming to the next version of MeeGo! Oh BTW, the releases will be every 6 months, expect MeeGo 1.3 in October 2011, along with its experimental Wayland support.&lt;/p&gt;

&lt;p&gt;From the device-give-away perspective, Intel threw a lot of &lt;a href="http://www.techonia.com/meego-tablet-exopc-1-2"&gt;ExoPC tablets&lt;/a&gt; (flashed with MeeGo 1.2 preview), as part of its &lt;a href="http://appup.com"&gt;AppUp program&lt;/a&gt;. I got one for a while, it's really easy to port your existing Qt apps using its SDK (but that's a separate blog post).&lt;/p&gt;

&lt;p&gt;But that's about it. LG was supposed to showcase its &lt;a href="http://www.engadget.com/2010/02/16/lg-gw990-to-be-among-first-meego-phones/"&gt;MeeGo-based LG GW990&lt;/a&gt; (based on &lt;a href="http://en.wikipedia.org/wiki/Moorestown_(computing_platform)"&gt;Intel Moorestown&lt;/a&gt;). There was even rumor that LG has also a tablet product, instead of only just a smartphone. And of course Nokia has &lt;a href="http://www.engadget.com/2011/05/17/nokia-n9-gets-teaser-video-rick-springfield-soundtrack-video/"&gt;its own N9 phone&lt;/a&gt; in the pipeline. None of this happened.&lt;/p&gt;

&lt;p&gt;When I remember back at &lt;a href="http://ariya.blogspot.com/2009/09/maemo-summit-2009-amsterdam-9-11-oct.html"&gt;Maemo Summit 2009 in Amsterdam&lt;/a&gt;, there was an accelerated momentum just because Nokia gave &lt;a href="http://en.wikipedia.org/wiki/Nokia_N900"&gt;N900&lt;/a&gt; to everyone. It was a top-of-the-line phone at that time, I still even use it for &lt;a href="http://ariya.blogspot.com/search/label/n900"&gt;various demos&lt;/a&gt;. Back then I was still with Nokia and after all these years, it's not funny to see that everyone is still using it. It's fine and dandy to have millions of cars using MeeGo for its infotainment, smart TVs based on MeeGo, and so on. A refresh in this smartphone party however would have made a much more dramatic impact with respect to the momentum in the development community.&lt;/p&gt;

&lt;p&gt;Seems I still need to wait until I can use a MeeGo phone as my primary phone. Meanwhile, I'll stick with ExoPC tablet to learn various bits of MeeGo. And hopefully nothing would exhaust my patience.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-8293304296204790793?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/8293304296204790793/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=8293304296204790793' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8293304296204790793'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8293304296204790793'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2011/05/meego-conf-2011-impressions.html' title='meego conf 2011 impressions'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3639/5769851666_0f0516430a_t.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-388415110000286107</id><published>2011-05-22T11:15:00.004+02:00</published><updated>2011-05-22T11:22:08.455+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qtwebkit'/><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='meego'/><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='san francisco'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><title type='text'>meego conf 2011</title><content type='html'>&lt;p&gt;It's MeeGo time! &lt;a href="http://sf2011.meego.com/"&gt;2011 conference&lt;/a&gt; will be held in Hyatt Regency, San Francisco.

&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-7k1zUW_W9l0/TdjUnIPM-6I/AAAAAAAAB7I/lfFsNR3BO24/s1600/meegoconf-2011.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 600px; height: 180px;" src="http://3.bp.blogspot.com/-7k1zUW_W9l0/TdjUnIPM-6I/AAAAAAAAB7I/lfFsNR3BO24/s1600/meegoconf-2011.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5609467104581188514" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;a href="http://sf2011.meego.com/program/session-schedule"&gt;complete program&lt;/a&gt; has been published. For topics related to Qt (among others), check what &lt;a href="http://labs.qt.nokia.com/2011/05/13/qt-5-at-the-meego-conference/"&gt;Thiago listed&lt;/a&gt;. In particular, of course yours truly be there, talking about &lt;a href="http://sf2011.meego.com/program/sessions/hybrid-apps-native-web-using-webkit"&gt;Hybrid Apps (Native + Web) using WebKit&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you will be around, see you there!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-388415110000286107?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/388415110000286107/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=388415110000286107' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/388415110000286107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/388415110000286107'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2011/05/meego-conf-2011.html' title='meego conf 2011'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-7k1zUW_W9l0/TdjUnIPM-6I/AAAAAAAAB7I/lfFsNR3BO24/s72-c/meegoconf-2011.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-7381964925723052103</id><published>2011-04-28T01:22:00.005+02:00</published><updated>2011-04-28T01:36:41.799+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qtwebkit'/><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='cupertino'/><category scheme='http://www.blogger.com/atom/ns#' term='travel'/><category scheme='http://www.blogger.com/atom/ns#' term='vacation'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='phantomjs'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>tango papa echo, charlie golf kilo</title><content type='html'>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/5662354301/" title="journey by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm6.static.flickr.com/5225/5662354301_c0273ddc6f.jpg" width="500" height="375" alt="journey" style="padding: 5px; border: 1px solid #ddd"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Currently stranded at TPE. Few minutes before leaving SFO I managed to tag 1.1.0 release for &lt;a href="http://www.phantomjs.org"&gt;PhantomJS&lt;/a&gt; (lesson learned: never attempt a release few hours before boarding). Thanks to &lt;a href="http://blog.ivandemarino.me/"&gt;Ivan&lt;/a&gt; and &lt;a href="http://casaportale.de/"&gt;Alessandro&lt;/a&gt;, few source tarballs and binaries are now ready.&lt;/p&gt;

&lt;p&gt;It's been hectic days. &lt;a href="https://www.webkit.org/meeting/"&gt;2011 WebKit Contributors Meeting&lt;/a&gt; was just over, it was fantastic and I got to meet and talk to a lot of WebKit rockstars. Parallel to that, my fellow brave Sencha lads finally &lt;a href="http://www.sencha.com/blog/ext-js-4-final/"&gt;unleashed The Quattro&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Next stop, also the final destination: CGK. Bracing for the impact of reverse culture shock...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-7381964925723052103?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/7381964925723052103/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=7381964925723052103' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/7381964925723052103'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/7381964925723052103'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2011/04/tango-papa-echo-charlie-golf-kilo.html' title='tango papa echo, charlie golf kilo'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm6.static.flickr.com/5225/5662354301_c0273ddc6f_t.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-8708145245391505168</id><published>2011-04-23T02:57:00.001+02:00</published><updated>2011-04-23T02:59:23.710+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='san francisco'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='kde'/><category scheme='http://www.blogger.com/atom/ns#' term='camp kde'/><title type='text'>camp kde 2011</title><content type='html'>&lt;p&gt;&lt;a href="http://dot.kde.org/2011/04/13/re-live-camp-kde-experience"&gt;Camp KDE 2011&lt;/a&gt; was a fabulous experience. First of all, there is definitely something with me and Camp KDE. The &lt;a href="http://ariya.blogspot.com/2010/01/camp-kde-day-one-saturday.html"&gt;previous one&lt;/a&gt; was in San Diego and at that time I was there working for &lt;a href="http://ariya.blogspot.com/2009/12/i-for-innovate.html"&gt;Qualcomm&lt;/a&gt;. This year it is San Francisco, right after &lt;a href="http://ariya.blogspot.com/2010/08/adventure-to-land-of-green-tea.html"&gt;I moved&lt;/a&gt; to the Bay Area.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.youtube.com/kdepromo#p/c/8F2C1C44C7A746C4"&gt;Videos of the sessions&lt;/a&gt; have been published. I contributed two talks there, one is about the (usual) graphics stuff with Qt (&lt;a href="http://www.youtube.com/watch?v=V8aDAhNUkHk"&gt;video&lt;/a&gt;, &lt;a href="http://www.slideshare.net/ariyahidayat/efficient-graphics-with-qt"&gt;slides&lt;/a&gt;). The other one is a series of demos of web technologies (&lt;a href="http://www.youtube.com/watch?v=hbyhja50Koc"&gt;video&lt;/a&gt;, &lt;a href="http://www.slideshare.net/ariyahidayat/introduction-to-qtwebkit"&gt;slides&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;There are some &lt;a href="http://www.youtube.com/kdepromo#p/c/7B49761F58C947C7"&gt;interview videos&lt;/a&gt; as well. If you watch &lt;a href="http://www.youtube.com/watch?v=upXor4kcBzc"&gt;Wade and me&lt;/a&gt;, you can spot a little guy there. Pay attention to his shirt :)&lt;/p&gt;

&lt;p&gt;The venue can't be better, it's in the center of Japantown. Even better, the weekend after is the &lt;a href="http://nccbf.org"&gt;Cherry Blossom Festival&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/5607810834/" title="cherry blossoms by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm6.static.flickr.com/5030/5607810834_3220056f56.jpg" width="500" height="333" alt="cherry blossoms" style="padding: 5px; border: 1px solid #ddd"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since I don't live in a big city anymore, it's also fascinating to be able to spot a cozy cafe right between all the big buildings. Right in Japantown, we found YakiniQ which serves a must-try sweet potato latte!&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/5605610658/" title="latte &amp;amp; croissant by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm6.static.flickr.com/5184/5605610658_59025e030a.jpg" width="333" height="500" alt="latte &amp;amp; croissant" style="padding: 5px; border: 1px solid #ddd"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All in all, it was a blast for me. Beside catching up with the people I met before, finally I got to meet folks I only know through our online interaction.&lt;/p&gt;

&lt;p&gt;Kudos to the Camp KDE organizers! See you in 2012.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-8708145245391505168?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/8708145245391505168/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=8708145245391505168' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8708145245391505168'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8708145245391505168'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2011/04/camp-kde-2011.html' title='camp kde 2011'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm6.static.flickr.com/5030/5607810834_3220056f56_t.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-7309878579683230489</id><published>2011-03-19T07:25:00.000+01:00</published><updated>2011-03-19T07:26:03.062+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qtwebkit'/><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='san francisco'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='kde'/><category scheme='http://www.blogger.com/atom/ns#' term='camp kde'/><title type='text'>camp kde in 2 weeks</title><content type='html'>&lt;p&gt;My first Camp KDE experience was when &lt;a href="http://ariya.blogspot.com/2010/01/camp-kde-day-one-saturday.html"&gt;it was held&lt;/a&gt; in San Diego, which was also interesting since at that time, &lt;a href="http://ariya.blogspot.com/2009/12/i-for-innovate.html"&gt;I just moved there&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Just like the planets align themselves, apparent &lt;a href="http://ariya.blogspot.com/2010/08/even-lost-has-its-season-finale.html"&gt;my move&lt;/a&gt; to the Bay Area is matched with &lt;a href="http://dot.kde.org/2011/02/05/camp-kde-2011-announced"&gt;this year Camp KDE&lt;/a&gt; in San Francisco. This time, it is co-located with Linux Foundation Collaboration Summit. For more info, just check the official site: &lt;a href="http://camp.kde.org"&gt;camp.kde.org&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://camp.kde.org/#schedule"&gt;The schedule&lt;/a&gt; for the tracks has been finalized, there will be various talks around KDE on Mobile, PIM, and of course Qt. I myself will have two presentations: &lt;b&gt;Introduction to QtWebKit&lt;/b&gt; and &lt;b&gt;Efficient Graphics with Qt: Beautiful and Blazing Fast&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;See you there!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-7309878579683230489?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/7309878579683230489/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=7309878579683230489' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/7309878579683230489'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/7309878579683230489'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2011/03/camp-kde-in-2-weeks.html' title='camp kde in 2 weeks'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-1343761214439078482</id><published>2011-03-12T17:47:00.001+01:00</published><updated>2011-03-12T17:48:43.564+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qtwebkit'/><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='sencha'/><category scheme='http://www.blogger.com/atom/ns#' term='san francisco'/><title type='text'>SenchaCon 2010</title><content type='html'>&lt;p&gt;At the last successful, sold-out &lt;a href="http://www.sencha.com/blog/senchacon-2010-recap/"&gt;Sencha Conference 2010&lt;/a&gt;, I did two introductory talks about JavaScript and WebKit, mainly targeted for web application developers. Since a few weeks ago, the videos for these talks have been available for you to watch.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;JavaScript Engines: Under the Hood&lt;/b&gt; is 10,000-foot overview on how a typical JavaScript engine works. Watch it below or at &lt;a href="http://vimeo.com/18783283"&gt;vimeo.com/18783283&lt;/a&gt;, with the accompanying slides at &lt;a href="http://slidesha.re/gGx9aA"&gt;http://slidesha.re/gGx9aA&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="http://player.vimeo.com/video/18783283?byline=0" width="400" height="225" frameborder="0"&gt;&lt;/iframe&gt;&lt;/p&gt;

&lt;p&gt;The other talk &lt;b&gt;Compiling and Optimizing Your Own Browser with WebKit&lt;/b&gt; (&lt;a href="http://vimeo.com/18780399"&gt;vimeo.com/18780399&lt;/a&gt; for the video, &lt;a href="http://slidesha.re/fPSvXX"&gt;http://slidesha.re/fPSvXX&lt;/a&gt; for the slide deck), mostly showing few tricks you can leverage to understand how your web applications work. For example, by using QtWebKit and capturing all the drawing commands and the corresponding timestamp, it is very easy to have a slow-motion rendering of your web page. As I showed it in the talk, it is even possible to go back in time, i.e. rendering your web page backwards.&lt;/p&gt;


&lt;p&gt;&lt;iframe src="http://player.vimeo.com/video/18780399?byline=0" width="400" height="225" frameborder="0"&gt;&lt;/iframe&gt;&lt;/p&gt;

&lt;p&gt;Many other &lt;a href="http://www.sencha.com/conference/videos/"&gt;videos from SenchaCon 2010&lt;/a&gt; have been published as well. Make sure you check them out.&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-1343761214439078482?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/1343761214439078482/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=1343761214439078482' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1343761214439078482'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1343761214439078482'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2011/03/senchacon-2010.html' title='SenchaCon 2010'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-1141746436428822729</id><published>2011-03-11T16:56:00.000+01:00</published><updated>2011-03-11T16:57:43.749+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qtwebkit'/><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='sencha'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='phantomjs'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>PhantomJS meets CoffeeScript</title><content type='html'>&lt;p&gt;&lt;a href="https://picasaweb.google.com/lh/photo/3HlWy19-53zRQ15OcGdRZA?feat=embedwebsite"&gt;&lt;img src="https://lh5.googleusercontent.com/_Oijhf1ZPv-4/TXj5nePD6aI/AAAAAAAAB4c/zmaDW2G7biU/s640/phantomjs-coffeescript.png" height="532" width="640" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I did something related to CoffeeScript before, namely &lt;a href="http://ariya.blogspot.com/2011/01/command-line-coffeescript.html"&gt;simple command-line compiler&lt;/a&gt;. For those who are not aware of CoffeeScript, it's basically (&lt;a href="http://en.wikipedia.org/wiki/CoffeeScript"&gt;from Wikipedia&lt;/a&gt;) JavaScript with &amp;quot;syntactic sugar inspired by Ruby and Python&amp;quot;.&lt;/p&gt;

&lt;p&gt;On the hand, surprisingly &lt;a href="http://phantomjs.org"&gt;PhantomJS&lt;/a&gt; generates &lt;a href="http://twitter.com/search/phantomjs"&gt;more&lt;/a&gt; &lt;a href="http://news.ycombinator.com/item?id=2142104"&gt;interest&lt;/a&gt; &lt;a href="http://www.reddit.com/r/javascript/comments/f8xbh/phantomjs_minimalistic_headless_webkitbased/"&gt;than&lt;/a&gt; I &lt;a href="http://dailyjs.com/2011/01/28/phantoms/"&gt;ever&lt;/a&gt; imagined before (with over 240 watching &lt;a href="https://github.com/ariya/phantomjs"&gt;its repository&lt;/a&gt;), prompting me not to abandon it too soon :) In fact, I decided to dump my tought on &lt;a href="http://code.google.com/p/phantomjs/wiki/Roadmap"&gt;its roadmap&lt;/a&gt; since more and more people are willing to help.&lt;/p&gt;

&lt;p&gt;My secret feature, which is &lt;a href="http://twitter.com/#!/ariyahidayat/status/42876638437982208"&gt;not secret anymore&lt;/a&gt;, for the &lt;a href="http://code.google.com/p/phantomjs/issues/list?can=1&amp;amp;q=status%3AFixed+Milestone%3DRelease1.1"&gt;upcoming 1.1 release&lt;/a&gt; is to incorporate the CoffeeScript compiler so that PhantomJS scripts can be written in CoffeeScript. Since the intention of PhantomJS is for &lt;a href="http://code.google.com/p/phantomjs/wiki/QuickStart"&gt;various scripting purpose&lt;/a&gt; utilizing headless QtWebKit, this is a perfect match.&lt;/p&gt;

&lt;p&gt;Gone are the curly braces...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-1141746436428822729?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/1141746436428822729/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=1141746436428822729' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1141746436428822729'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1141746436428822729'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2011/03/phantomjs-meets-coffeescript.html' title='PhantomJS meets CoffeeScript'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh5.googleusercontent.com/_Oijhf1ZPv-4/TXj5nePD6aI/AAAAAAAAB4c/zmaDW2G7biU/s72-c/phantomjs-coffeescript.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-2030507258038652881</id><published>2011-02-22T19:17:00.001+01:00</published><updated>2011-02-22T19:20:37.650+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>vim: fast file navigation with Command-T</title><content type='html'>&lt;p&gt;Judging from the hits, my blog post on &lt;a href="http://ariya.blogspot.com/2008/07/vim-lightning-fast-navigation-in-large.html"&gt;lightning-fast project navigation in vim&lt;/a&gt; seems to be still popular. While the &lt;a href="http://www.vim.org/scripts/script.php?script_id=69"&gt;Project script&lt;/a&gt; is still my favorite these days, especially when dealing with hundreds of files, let me show you here another gem: &lt;a href="http://www.vim.org/scripts/script.php?script_id=3025"&gt;Command-T script&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://wincent.com/blog/bringing-textmate-style-command-t-to-vim"&gt;Similar&lt;/a&gt;  to Command-T in TextMate, basically this Command-T script allows quick and incremental search for files. This works very well. The &lt;a href="https://wincent.com/products/command-t"&gt;official site&lt;/a&gt; for Command-T has several good screencasts which demonstrate how to install and set it up.&lt;/p&gt;

&lt;a href="https://picasaweb.google.com/lh/photo/95rxoCNdSf77ro3S2oqf8A?feat=embedwebsite"&gt;&lt;img src="https://lh4.googleusercontent.com/_Oijhf1ZPv-4/TWKzVMWx4lI/AAAAAAAAB2s/-7JZVzC1XAc/s640/command-t.png" height="480" width="640" /&gt;&lt;/a&gt;

&lt;p&gt;Manual installation is fairly simple. In fact, if you use &lt;a href="https://github.com/carlhuda/janus"&gt;Janus&lt;/a&gt; (which what I strongly do recommend these days for vim lovers), you are already set.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://git.wincent.com/command-t.git/blob_plain/HEAD:/README.txt"&gt;Command-T's documentation&lt;/a&gt; is quite extensive, make sure you read it. For the impatient, here are three important tidbits.&lt;/p&gt;

&lt;p&gt;(1) Command-T requires vim with Ruby support. One way to find this is:&lt;/p&gt;
&lt;pre&gt;vim --version | grep '\+ruby'&lt;/pre&gt;

&lt;p&gt;(2) The default binding is Leader-t. For &lt;a href="http://code.google.com/p/macvim/"&gt;MacVim&lt;/a&gt; (or other GUI-based vim on Mac) and you'd like to have it on your Command-t (or D-T, in vim's terminology), just insert the following in your &lt;tt&gt;.vimrc&lt;/tt&gt;:&lt;/p&gt;

&lt;pre&gt;
  if has("gui_macvim")
    macmenu &amp;File.New\ Tab key=&lt;nop&gt;
    map &lt;D-t&gt; :CommandT&lt;CR&gt;
  endif
&lt;/pre&gt;

&lt;p&gt;(3) If you like to open the selected file in a new tab, hit Ctrl+T instead of just Enter.&lt;/p&gt;

&lt;p&gt;One side note: if you have MacVim but don't have the &lt;tt&gt;mvim&lt;/tt&gt; shortcut, add this to your &lt;tt&gt;.profile&lt;/tt&gt; (or &lt;tt&gt;.bash_profile&lt;/tt&gt;):&lt;/p&gt;
&lt;pre&gt;alias mvim='/Applications/MacVim.app/Contents/MacOS/Vim -g'&lt;/pre&gt;

&lt;p&gt;This way, you can launch MacVim from terminal, e.g. &lt;tt&gt;mvim code.js&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;And in case you still want to use TextMate, why don't you check out &lt;a href="http://textmate2.org/"&gt;TextMate2&lt;/a&gt; instead?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-2030507258038652881?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/2030507258038652881/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=2030507258038652881' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2030507258038652881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2030507258038652881'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2011/02/vim-fast-file-navigation-with-command-t.html' title='vim: fast file navigation with Command-T'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh4.googleusercontent.com/_Oijhf1ZPv-4/TWKzVMWx4lI/AAAAAAAAB2s/-7JZVzC1XAc/s72-c/command-t.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-5042767666533646012</id><published>2011-02-21T17:16:00.000+01:00</published><updated>2011-02-21T17:17:02.634+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qtwebkit'/><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='sencha'/><category scheme='http://www.blogger.com/atom/ns#' term='color'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='canvas'/><category scheme='http://www.blogger.com/atom/ns#' term='phantomjs'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>color wheel on Canvas</title><content type='html'>&lt;p&gt;&lt;a href="https://picasaweb.google.com/lh/photo/Ekyst64aYP_k5Prn_-bQCw?feat=embedwebsite"&gt;&lt;img src="https://lh3.googleusercontent.com/_Oijhf1ZPv-4/TVzeP4NPMDI/AAAAAAAAB10/FhFzcvQLXLw/s800/colorwheel.png" height="400" width="400" /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;While I played with &lt;a href="http://labs.qt.nokia.com/2008/07/05/let-there-be-color/"&gt;HSV pie&lt;/a&gt; and &lt;a href="http://ariya.blogspot.com/2009/04/still-about-color-wheel.html"&gt;color wheel&lt;/a&gt; before, usually I just use the excellent &lt;a href="http://doc.qt.nokia.com/4.7/paintsystem.html"&gt;Qt graphics stack&lt;/a&gt; to try out various things. This days, I lean towards using web technologies and for that purpose, &lt;a href=""&gt;HTML Canvas&lt;/a&gt; suits me just fine. With &lt;a href="http://ariya.blogspot.com/2011/01/phantomjs-minimalistic-headless-webkit.html"&gt;PhantomJS&lt;/a&gt;, I even got the result rendered as PNG image. &lt;/p&gt;

&lt;p&gt;The new example &lt;a href="https://github.com/ariya/phantomjs/commit/e1583452"&gt;I added&lt;/a&gt; to PhantomJS is &lt;a href="http://code.google.com/p/phantomjs/wiki/QuickStart#Canvas"&gt;colorwheel.js&lt;/a&gt; which produces the above screenshot. The entire script code is as follows (if some parts look cryptic, read about &lt;a href="http://en.wikipedia.org/wiki/HSL_and_HSV"&gt;HSL and HSV color space&lt;/a&gt;):&lt;/p&gt;


&lt;pre class="brush: js"&gt;
if (phantom.state.length === 0) {
    phantom.state = 1;
    phantom.viewportSize = { width: 400, height : 400 };
    phantom.content = '&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;&amp;lt;canvas id="surface"&amp;gt;' +
        '&amp;lt;/canvas&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;';
} else {
    var el = document.getElementById('surface'),
        context = el.getContext('2d'),
        width = window.innerWidth,
        height = window.innerHeight,
        cx = width / 2,
        cy = height / 2,
        radius = width  / 2.3,
        imageData,
        pixels,
        hue, sat, value,
        i = 0, x, y, rx, ry, d,
        f, g, p, u, v, w, rgb;

    el.width = width;
    el.height = height;
    imageData = context.createImageData(width, height);
    pixels = imageData.data;

    for (y = 0; y &amp;lt; height; y = y + 1) {
        for (x = 0; x &amp;lt; width; x = x + 1, i = i + 4) {
            rx = x - cx;
            ry = y - cy;
            d = rx * rx + ry * ry;
            if (d &amp;lt; radius * radius) {
                hue = 6 * (Math.atan2(ry, rx) + Math.PI) / (2 * Math.PI);
                sat = Math.sqrt(d) / radius;
                g = Math.floor(hue);
                f = hue - g;
                u = 255 * (1 - sat);
                v = 255 * (1 - sat * f);
                w = 255 * (1 - sat * (1 - f));
                pixels[i] = [255, v, u, u, w, 255, 255][g];
                pixels[i + 1] = [w, 255, 255, v, u, u, w][g];
                pixels[i + 2] = [u, u, w, 255, 255, v, u][g];
                pixels[i + 3] = 255;
            }
        }
    }

    context.putImageData(imageData, 0, 0);
    document.body.style.backgroundColor = 'white';
    document.body.style.margin = '0px';

    phantom.render('colorwheel.png');
    phantom.exit();
}&lt;/pre&gt;

&lt;p&gt;Beside the above example, there are &lt;a href="http://code.google.com/p/phantomjs/issues/list?can=1&amp;q=Status:Fixed+Milestone%3DRelease1.1"&gt;few other things&lt;/a&gt; which you'll get in the upcoming PhantomJS 1.1 release, among others support for &lt;a href="http://code.google.com/p/phantomjs/issues/detail?id=9"&gt;Unix shebang&lt;/a&gt;, &lt;a href="http://code.google.com/p/phantomjs/issues/detail?id=7"&gt;file upload&lt;/a&gt; for form submission, disable/enable &lt;a href="http://code.google.com/p/phantomjs/issues/detail?id=35"&gt;images loading&lt;/a&gt; and &lt;a href="http://code.google.com/p/phantomjs/issues/detail?id=14"&gt;plugins&lt;/a&gt;, as well as support for &lt;a href="http://code.google.com/p/phantomjs/wiki/ServiceIntegration#QUnit_Driver"&gt;QUnit integration&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-5042767666533646012?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/5042767666533646012/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=5042767666533646012' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/5042767666533646012'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/5042767666533646012'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2011/02/color-wheel-on-canvas.html' title='color wheel on Canvas'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh3.googleusercontent.com/_Oijhf1ZPv-4/TVzeP4NPMDI/AAAAAAAAB10/FhFzcvQLXLw/s72-c/colorwheel.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-2634487964408721948</id><published>2011-02-04T06:43:00.003+01:00</published><updated>2011-02-04T06:50:50.828+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='webgl'/><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='chromium'/><category scheme='http://www.blogger.com/atom/ns#' term='openstreetmap'/><category scheme='http://www.blogger.com/atom/ns#' term='marble'/><category scheme='http://www.blogger.com/atom/ns#' term='opengl'/><title type='text'>virtual globe in the browser</title><content type='html'>&lt;p&gt;Latest stable version of &lt;a href="http://chrome.blogspot.com/2011/02/dash-of-speed-3d-and-apps.html"&gt;Chrome 9&lt;/a&gt; now has built-in support for &lt;a href="http://www.khronos.org/webgl/"&gt;WebGL&lt;/a&gt;. Hopefully this would increase the amount of people trying out various cool 3-D stuff, from the infamous &lt;a href="http://webglsamples.googlecode.com/hg/aquarium/aquarium.html"&gt;Aquarium demo&lt;/a&gt; to the fancy &lt;a href="http://aleksandarrodic.com/p/jellyfish/"&gt;Jelly Fish animation&lt;/a&gt;, and &lt;a href="http://planet-webgl.org/"&gt;many others&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;What excites me is the following: &lt;a href="http://www.webglearth.org/"&gt;WebGL Earth&lt;/a&gt;, a free and open-source implementation of a virtual globe using WebGL. The &lt;a href="http://www.webglearth.com"&gt;live demo&lt;/a&gt; supports showing the map tiles from OpenStreetMap, MapQuest, and Bing. Just awesome!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://picasaweb.google.com/lh/photo/DMG7VajYctTGRCvDS69zYg?feat=embedwebsite"&gt;&lt;img src="https://lh6.googleusercontent.com/_Oijhf1ZPv-4/TUuR2hPwO_I/AAAAAAAAB0g/DsJXMnZOfkI/s640/webgl-earth.png" height="480" width="640" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-2634487964408721948?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/2634487964408721948/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=2634487964408721948' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2634487964408721948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2634487964408721948'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2011/02/virtual-globe-in-browser.html' title='virtual globe in the browser'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh6.googleusercontent.com/_Oijhf1ZPv-4/TUuR2hPwO_I/AAAAAAAAB0g/DsJXMnZOfkI/s72-c/webgl-earth.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-4256956271098944361</id><published>2011-01-23T07:07:00.001+01:00</published><updated>2011-01-23T07:09:21.981+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qtwebkit'/><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='svg'/><category scheme='http://www.blogger.com/atom/ns#' term='sencha'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='phantomjs'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>PhantomJS: minimalistic headless WebKit-based JavaScript-driven tool</title><content type='html'>&lt;p&gt;&lt;a href="http://phantomjs.googlecode.com/"&gt;PhantomJS&lt;/a&gt; is a headless WebKit packaged as a JavaScript-driven tool. It can be used in command-line utilities which requires web stack, or even as the basis for testing rich web application. It uses WebKit in a headless mode, so you get access to the real native and fast implementation (not a simulated environment) of various standards such as DOM, CSS selector, Canvas, SVG, and many others.&lt;/p&gt;

&lt;p&gt;The project page contains a bunch of examples, from &lt;a href="http://code.google.com/p/phantomjs/wiki/QuickStart"&gt;easy ones&lt;/a&gt; to some more &lt;a href="http://code.google.com/p/phantomjs/wiki/ServiceIntegration"&gt;complicated uses&lt;/a&gt;. Feel free to contribute more examples!&lt;/p&gt;

&lt;p&gt;Let's look at one of the examples, the &lt;a href="http://code.google.com/p/phantomjs/wiki/QuickStart#Rendering"&gt;page rasterizer&lt;/a&gt; (yes, it's only 16 lines!):&lt;/p&gt;

&lt;pre class="brush: js"&gt;
if (phantom.state.length === 0) {
    if (phantom.args.length !== 2) {
        console.log('Usage: rasterize.js URL filename');
        phantom.exit();
    } else {
        var address = phantom.args[0];
        phantom.state = 'rasterize';
        phantom.viewportSize = { width: 600, height: 600 };
        phantom.open(address);
    }
} else {
    var output = phantom.args[1];
    phantom.sleep(200);
    phantom.render(output);
    phantom.exit();
}&lt;/pre&gt;

&lt;p&gt;If I want to have the famous PostScript tiger from its SVG source, all I have to do is to run:&lt;/p&gt;

&lt;pre&gt;phantomjs rasterize.js http://ariya.github.com/svg/tiger.svg tiger.png&lt;/pre&gt;

&lt;p&gt;But static vector graphic is boring. Replacing the above with&lt;/p&gt;

&lt;pre&gt;phantomjs rasterize.js http://raphaeljs.com/polar-clock.html clock.png&lt;/pre&gt;

&lt;p&gt;gives me &lt;a href="http://raphaeljs.com/polar-clock.html"&gt;Polar Clock&lt;/a&gt;, one notable example from &lt;a href="http://raphaeljs.com/"&gt;RaphaelJS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/kywDYDmQS2nk834ep5OFMQ?feat=embedwebsite"&gt;&lt;img src="http://lh6.ggpht.com/_Oijhf1ZPv-4/TR6jVcbiUoI/AAAAAAAABzA/N4r3IgBoYWY/s400/polar-clock.png" height="400" width="399" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Should you need to deal with JSONP, process XML, and integrate with YQL, that's all easily done. Again, refer to the various &lt;a href="http://code.google.com/p/phantomjs/wiki/ServiceIntegration"&gt;service integration examples&lt;/a&gt;. Let me show one example, which is actually my favorite:&lt;/p&gt;

&lt;pre class="brush: js"&gt;
if (phantom.state.length === 0) {
    var origin, dest;
    if (phantom.args.length &amp;lt; 2) {
        console.log('Usage: direction.js origin destination');
        console.log('Example: direction.js "San Diego" "Palo Alto"');
        phantom.exit(1);
    }
    origin = phantom.args[0];
    dest = phantom.args[1];
    phantom.state = origin + ' to ' + dest;
    phantom.open(encodeURI('http://maps.googleapis.com/maps/api/directions/xml?origin='
        + origin +  '&amp;amp;destination=' + dest + 
        '&amp;amp;units=imperial&amp;amp;mode=driving&amp;amp;sensor=false'));
} else {
    if (phantom.loadStatus === 'fail') {
        console.log('Unable to access network');
    } else {
        var steps;
        steps = phantom.content.match(/&amp;lt;html_instructions&amp;gt;(.*)&amp;lt;\/html_instructions&amp;gt;/ig);
        if (steps == null) {
            console.log('No data available for ' + phantom.state);
        } else {
            steps.forEach(function (ins) {
                ins = ins.replace(/\&amp;amp;lt;/ig, '&amp;lt;').replace(/\&amp;amp;gt;/ig, '&amp;gt;');
                ins = ins.replace(/\&amp;lt;div/ig, '\n&amp;lt;div');
                ins = ins.replace(/&amp;lt;.*?&amp;gt;/g, '');
                console.log(ins);
            });
        }
    }
    phantom.exit();
}&lt;/pre&gt;

&lt;p&gt;If I run it like the following:&lt;/p&gt;
&lt;pre&gt;phantomjs direction.js 'Redwood City' 'Sunnyvale'&lt;/pre&gt;

&lt;p&gt;what I got is the complete driving direction:&lt;/p&gt;

&lt;pre&gt;
Head east on Broadway toward El Camino Real
Take the 1st left onto El Camino Real
Turn right at Whipple Ave
Slight right to merge onto US-101 S toward San Jose
Take exit 398B to merge onto CA-85 S toward Santa Cruz/Cupertino
Take exit 22A to merge onto CA-82 S/E El Camino Real toward Sunnyvale
Destination will be on the right

Map data ©2011 Google
&lt;/pre&gt;

&lt;p&gt;Make sure you check out other examples, such as getting weather forecast conditions, finding pizza in New York, looking up approximate location based on IP address, pulling the list of seasonal food, displaying tweets, and many others.&lt;/p&gt;

&lt;p&gt;Headless execution of any web content also enables fast unit testing. Obviously, the goal is not to replace comprehensive, cross-browser framework such as &lt;a href="http://seleniumhq.org/"&gt;Selenium&lt;/a&gt; or &lt;a href="http://www.froglogic.com/products/squish/web.php"&gt;Squish for Web&lt;/a&gt;. Rather, it serves a quick sanity check just before you check in some changes.&lt;/p&gt;

&lt;p&gt;Since this can happen automatically and does not need to launch any browser, even better, you can hook the test so that it executes right before a commit and actually prevents the commit if any of the test fails. It is easily done using git via &lt;a href="http://progit.org/book/ch7-3.html"&gt;its hook support&lt;/a&gt;. This is something I have &lt;a href="http://www.sencha.com/blog/2011/01/14/headless-testing-for-continuous-integration-with-git-and-jasmine/"&gt;written at Sencha blog&lt;/a&gt;. It demonstrated precommit hook with &lt;a href="http://pivotal.github.com/jasmine/"&gt;Jasmine&lt;/a&gt;, but technically it can work with any test framework.&lt;/p&gt;

&lt;p&gt;I have been working on and off on PhantomJS for the past few years. You may be already familiar with some of its inspiration (also involving headless WebKit): &lt;a href="http://labs.qt.nokia.com/2008/08/06/webkit-based-svg-rasterizer/"&gt;SVG rasterizer&lt;/a&gt;, &lt;a href="http://labs.qt.nokia.com/2009/01/15/capturing-web-pages/"&gt;page capture&lt;/a&gt;, &lt;a href="http://labs.qt.nokia.com/2008/11/04/search-with-thumbnail-preview/"&gt;visual Google&lt;/a&gt;, etc.
Finally I managed to overcome my laziness, cleaned up the code, and published it for your pleasure. Obviously it's not a surprise if you find out that PhantomJS uses &lt;a href="http://www.blogger.com/doc.qt.nokia.com/qtwebkit.html"&gt;QtWebKit&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I got a few tasks for next &lt;a href="http://code.google.com/p/phantomjs/issues/list?can=2&amp;amp;q=Milestone%3DRelease1.1"&gt;PhantomJS version 1.1&lt;/a&gt;. You are encouraged to file bugs and feature requests in the said issue tracker.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://code.google.com/p/phantomjs/wiki/SourceCode"&gt;Get it&lt;/a&gt; while it is hot!&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-4256956271098944361?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/4256956271098944361/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=4256956271098944361' title='16 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/4256956271098944361'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/4256956271098944361'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2011/01/phantomjs-minimalistic-headless-webkit.html' title='PhantomJS: minimalistic headless WebKit-based JavaScript-driven tool'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_Oijhf1ZPv-4/TR6jVcbiUoI/AAAAAAAABzA/N4r3IgBoYWY/s72-c/polar-clock.png' height='72' width='72'/><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-504273141802979693</id><published>2011-01-08T07:52:00.000+01:00</published><updated>2011-01-08T07:53:23.972+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='script'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>command line CoffeeScript</title><content type='html'>&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/CoffeeScript"&gt;CoffeeScript&lt;/a&gt; seems to be picking up some momentum these days. No doubt, it is very valuable to help writing cleaner code.&lt;/p&gt;

&lt;p&gt;The command-line choices to run CoffeeScript compiler right now are either using Rhino (&lt;a href="https://github.com/yeungda/jcoffeescript"&gt;jcoffeescript&lt;/a&gt;) or using &lt;a href="http://nodejs.org"&gt;NodeJS&lt;/a&gt;. While I love NodeJS, seems that it is an overkill to require the entire NodeJS stack/infrastructure/package manager to invoke CoffeeScript compiler.&lt;/p&gt;

&lt;p&gt;The solution is to use &lt;a href="http://en.wikipedia.org/wiki/V8_(JavaScript_engine)"&gt;V8&lt;/a&gt;, the powerful JavaScript engine, with a little binding so that it can access file system. This is exactly &lt;b&gt;filejs&lt;/b&gt;, something I have &lt;a href="http://ariya.blogspot.com/2010/11/v8-jslint-vim.html"&gt;shown before&lt;/a&gt;, e.g. to invoke &lt;a href="http://www.jslint.com"&gt;JSLint&lt;/a&gt; from command line.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/9eGGrc9Oa7M7rrwm4ZHYlg?feat=embedwebsite"&gt;&lt;img src="http://lh4.ggpht.com/_Oijhf1ZPv-4/TSgIdVByoXI/AAAAAAAABzc/57F_m1zxcp0/s800/coffeejs.png" height="285" width="554" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Combining filejs and CoffeeScript is terribly easy. Just follow these steps.&lt;/p&gt;

&lt;p&gt;Note: filejs does not support Windows yet. Sorry.&lt;/p&gt;

&lt;p&gt;First of all, if you have not done it, build filejs. Go to the &lt;a href="http://gitorious.org/ofi-labs/X2"&gt;X2 repository&lt;/a&gt;, it is under the &lt;a href="http://gitorious.org/ofi-labs/x2/trees/master/javascript/filejs"&gt;javascript/filejs&lt;/a&gt; folder. Open the included README.TXT and follow the instructions on how to build V8 and filejs.&lt;/p&gt;

&lt;p&gt;After you build it, copy both &lt;tt&gt;filejs&lt;/tt&gt; executable and &lt;tt&gt;coffee.js&lt;/tt&gt; to somewhere in your PATH. Usually I stash that kind of stuff in &lt;tt&gt;~/bin&lt;/tt&gt; and ensure that &lt;tt&gt;~/bin&lt;/tt&gt; is in my PATH.&lt;/p&gt;

&lt;p&gt;Now get &lt;a href="https://github.com/jashkenas/coffee-script/raw/master/extras/coffee-script.js"&gt;coffee-script.js&lt;/a&gt; (the CoffeeScript to JavaScript compiler) and store it somewhere, e.g. &lt;tt&gt;~/bin&lt;/tt&gt; again.&lt;/p&gt;

&lt;p&gt;Create a new file called &lt;tt&gt;coffee&lt;/tt&gt;, which has the following one-line content:&lt;/p&gt;

&lt;pre&gt;filejs ~/bin/coffee.js $1&lt;/pre&gt;

&lt;p&gt;Make that file executable and then save it to &lt;tt&gt;~/bin&lt;/tt&gt; (again).&lt;/p&gt;

&lt;p&gt;Open &lt;tt&gt;coffee.js&lt;/tt&gt; and modify the value of the compiler variable to point to your &lt;tt&gt;coffee-script.js&lt;/tt&gt;. Note: this must use the absolute path name.&lt;/p&gt;

&lt;p&gt;Now you can do the following:&lt;/p&gt;

&lt;pre&gt;coffee hello.coffee&lt;/pre&gt;

&lt;p&gt;If &lt;tt&gt;hello.coffee&lt;/tt&gt; is your script written in CoffeeScript, the converted JavaScript version will be dumped to the standard output.&lt;/p&gt;

&lt;p&gt;Feel free to tweak &lt;tt&gt;coffee.js&lt;/tt&gt; so that it understands and passes various CoffeeScript compiler options!&lt;/p&gt;

&lt;p&gt;Fun, isn't it?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-504273141802979693?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/504273141802979693/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=504273141802979693' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/504273141802979693'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/504273141802979693'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2011/01/command-line-coffeescript.html' title='command line CoffeeScript'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_Oijhf1ZPv-4/TSgIdVByoXI/AAAAAAAABzc/57F_m1zxcp0/s72-c/coffeejs.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-4776791712514671390</id><published>2011-01-01T06:00:00.001+01:00</published><updated>2011-01-01T06:02:20.614+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='qtwebkit'/><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='kde'/><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='sencha'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='accelerometer'/><category scheme='http://www.blogger.com/atom/ns#' term='effect'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>X2 from Ofi Labs: wrap-up 2010</title><content type='html'>&lt;p&gt;&lt;img src="http://lh6.ggpht.com/_Oijhf1ZPv-4/S5kAq13tZAI/AAAAAAAABiU/YvRNu2rIjFY/s144/x2-logo.png" alt="X2" align="right"&gt;It got started when I needed &lt;a href="http://ariya.blogspot.com/2010/02/introducing-x2.html"&gt;a new home&lt;/a&gt; for my examples. It has even &lt;a href="http://ariya.blogspot.com/2010/03/new-x2-logo.html"&gt;a nice logo&lt;/a&gt;.

&lt;p&gt;&lt;b&gt;sensor&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ariya.blogspot.com/2010/03/n900-and-its-accelerometer.html"&gt;accelerometer viewer&lt;/a&gt; for Maemo 5 (Nokia N900).&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ariya.blogspot.com/2010/08/bouncing-ball-with-accelerometer-on.html"&gt;bouncing ball&lt;/a&gt;, where the gravity affects the movement of the ball.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ariya.blogspot.com/2010/08/box-of-marbles_10.html"&gt;box of marbles&lt;/a&gt;, where the gravity affects a bunch of colored marbles.&lt;/p&gt;

&lt;p&gt;combining accelerometer and network to do &lt;a href="http://ariya.blogspot.com/2010/08/box-of-marbles-redux.html"&gt;inter-device marbles transfer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ariya.blogspot.com/2010/12/motion-vs-orientation.html"&gt;motion and orientation&lt;/a&gt; for web applications.&lt;/p&gt;

&lt;p&gt;web-based version of &lt;a href="http://ariya.blogspot.com/2010/11/box-of-marbles-meets-device-orientation.html"&gt;marble box&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;widgets&lt;/b&gt;&lt;p&gt;

&lt;p&gt;&lt;a href="http://ariya.blogspot.com/2010/03/morphing-clock.html"&gt;morphing clock&lt;/a&gt;, where the transition between the digital and analog version is a kind of morphing effect.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ariya.blogspot.com/2010/02/qpalette-viewer.html"&gt;qpalette viewer&lt;/a&gt; so you know which color is which one.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;graphics&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ariya.blogspot.com/2010/09/art-of-blurring-shadow.html"&gt;fast approximation of Gaussian blur&lt;/a&gt; to create a blurry drop shadow.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ariya.blogspot.com/2010/09/capture-openstreetmap-and-mapquest-and.html"&gt;command-line capture tool&lt;/a&gt; to save maps from OpenStreetMap, MapQuest and Ovi Maps.&lt;/p&gt;

&lt;p&gt;simple tool to &lt;a href="http://ariya.blogspot.com/2010/11/chunks-inside-png.html"&gt;list all chunks&lt;/a&gt; inside a PNG image.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;webkit &amp;amp; javascript&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ariya.blogspot.com/2010/11/v8-jslint-vim.html"&gt;file processing&lt;/a&gt;, including using jslint, in command-line using JavaScript.&lt;/p&gt;

&lt;p&gt;play &lt;a href="http://ariya.blogspot.com/2010/09/invade-destroy.html"&gt;Canvas-based game&lt;/a&gt; as normal desktop app.&lt;/p&gt;

&lt;p&gt;offline, command line &lt;a href="http://ariya.blogspot.com/2010/09/offline-command-line-beautifier-for.html"&gt;beautifier&lt;/a&gt; for JavaScript code, utilizing Qt Script.&lt;/p&gt;

&lt;p&gt;another &lt;a href="http://ariya.blogspot.com/2010/10/yet-another-command-line-javascript.html"&gt;variant of the beautifier&lt;/a&gt;, this time using V8.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ariya.blogspot.com/2010/09/minimalistic-javascript-editing-widget.html"&gt;minimalistic editing widget&lt;/a&gt; for JavaScript code, with custom syntax highlighting.&lt;/p&gt;

&lt;p&gt;white background is boring? just try some &lt;a href="http://ariya.blogspot.com/2010/10/color-inversion-for-web-pages.html"&gt;color inverted web pages&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ariya.blogspot.com/2010/02/web-browser-and-touch-device-problem.html"&gt;detect the closest link&lt;/a&gt; to ease following it on a touch device.&lt;/p&gt;

&lt;p&gt;Canvas pixel manipulation for &lt;a href="http://helderfoo.blogspot.com/2010/10/pixel-manipulation-qt-vs-html5-canvas.html"&gt;plasma effect&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;network&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ariya.blogspot.com/2010/04/simple-http-proxy-server-in-100-lines.html"&gt;simple proxy server&lt;/a&gt; for HTTP, in 100 lines.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ariya.blogspot.com/2010/05/qnetworkaccessmanager-tracenet-speed.html"&gt;tracenet&lt;/a&gt;: trap all network requests+replies to show them with Speed Tracer.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ariya.blogspot.com/2010/06/proxy-server-with-filtering-feature.html"&gt;filterproxy&lt;/a&gt;: another variant of the proxy server with added URL filtering feature.&lt;p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-4776791712514671390?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/4776791712514671390/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=4776791712514671390' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/4776791712514671390'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/4776791712514671390'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2011/01/x2-from-ofi-labs-wrap-up-2010.html' title='X2 from Ofi Labs: wrap-up 2010'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_Oijhf1ZPv-4/S5kAq13tZAI/AAAAAAAABiU/YvRNu2rIjFY/s72-c/x2-logo.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-3054351815926499228</id><published>2010-12-16T17:15:00.001+01:00</published><updated>2010-12-16T17:20:35.141+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qtwebkit'/><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='sencha'/><category scheme='http://www.blogger.com/atom/ns#' term='gadget'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='accelerometer'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>motion vs orientation</title><content type='html'>&lt;p&gt;I already showed the use of device orientation in a fun game called &lt;a href="http://ariya.blogspot.com/2010/11/box-of-marbles-meets-device-orientation.html"&gt;Box of Marbles&lt;/a&gt;. Based on my experience trying out this &lt;a href="http://dev.w3.org/geo/api/spec-source-orientation.html"&gt;API implementation&lt;/a&gt;, often it is easy to get confused by &lt;a href="http://dev.w3.org/geo/api/spec-source-orientation.html#motion_event"&gt;device motion&lt;/a&gt; vs &lt;a href="http://dev.w3.org/geo/api/spec-source-orientation.html#device_orientation_event"&gt;device orientation&lt;/a&gt;. Thus, I created two web-based applications (using on &lt;a href="http://www.sencha.com/products/touch/"&gt;Sencha Touch&lt;/a&gt;): &lt;a href="http://ariya.github.com/js/devicemotion"&gt;Device Motion&lt;/a&gt; and &lt;a href="http://ariya.github.com/js/deviceorientation"&gt;Device Orientation&lt;/a&gt;. Each basically just visualizes the values of the data in a bunch of sliders:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/ZZD-yBxOHTcnQKxwBcYAqA?feat=embedwebsite"&gt;&lt;img src="http://lh5.ggpht.com/_Oijhf1ZPv-4/TQgTRvIKcKI/AAAAAAAAByU/gC0RxNkxGDI/s640/devicemotion.png" height="465" width="640" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can find the code in the &lt;a href="http://gitorious.org/ofi-labs/X2"&gt;usual X2 repository&lt;/a&gt;, under the subdirectory &lt;a href="http://gitorious.org/ofi-labs/x2/trees/master/javascript/devicemotion"&gt;javascript/devicemotion&lt;/a&gt; and &lt;a href="http://gitorious.org/ofi-labs/x2/trees/master/javascript/deviceorientation"&gt;javascript/deviceorientation&lt;/a&gt;, respectively. Obviously, the rest of Sencha Touch library is needed before you can deploy and run the examples. For the lazy, just run the live demo for &lt;a href="http://ariya.github.com/js/devicemotion"&gt;Device Motion&lt;/a&gt; and &lt;a href="http://ariya.github.com/js/deviceorientation"&gt;Device Orientation&lt;/a&gt; (they support &lt;a href="http://diveintohtml5.org/offline.html"&gt;offline mode&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;While right now only iOS 4.2 on iPhone/iPad/iPod Touch implements this API, I have a strong hope that Android (post Gingerbread) and Nokia (thanks to &lt;a href="http://trac.webkit.org/changeset/69313"&gt;QtWebKit and Qt Mobility&lt;/a&gt;) will support this cool API in the near future. Well, at least I do plan to revive my Symbian setup to custom compile QtWebKit and test it on Nokia N8.&lt;/p&gt;

&lt;p&gt;Side note: from my limited understanding, seems that both accelerometer and gyroscope are needed in order to supply the accurate data, much like in an inertial navigation system (&amp;quot;Inertial Phone&amp;quot;, anyone?).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-3054351815926499228?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/3054351815926499228/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=3054351815926499228' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/3054351815926499228'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/3054351815926499228'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/12/motion-vs-orientation.html' title='motion vs orientation'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_Oijhf1ZPv-4/TQgTRvIKcKI/AAAAAAAAByU/gC0RxNkxGDI/s72-c/devicemotion.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-4971737531415735885</id><published>2010-12-13T08:19:00.001+01:00</published><updated>2010-12-13T08:22:59.286+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='musing'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='kde'/><title type='text'>the art of repository access</title><content type='html'>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/5255057959/" title="team by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm6.static.flickr.com/5123/5255057959_4bcc4220ac.jpg" width="500" height="333" alt="team" style="border: 1px solid #ccc; padding: 5px"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What will occur when &lt;a href="http://en.wikipedia.org/wiki/Software_development"&gt;a software team&lt;/a&gt; is working on a project? How to tackle the &lt;a href="http://en.wikipedia.org/wiki/Change_control"&gt;change control&lt;/a&gt;?&lt;/p&gt;

&lt;p&gt;The first and foremost obvious approach is simply giving &lt;b&gt;full access for everyone&lt;/b&gt;. This is what typically happens in a group of friends working together on a cool project, a school assignment, &lt;a href="http://en.wikipedia.org/wiki/Hackathon"&gt;a short hackathon&lt;/a&gt;, an early prototype, or any other &lt;a href="http://en.wikipedia.org/wiki/Source_control"&gt;collaborative efforts&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;While this approach is very democratic (&lt;a href="http://en.wikipedia.org/wiki/All_men_are_created_equal"&gt;all developers are created equal&lt;/a&gt;), it is not very scalable. It works on a small and agile team, mainly because everyone knows each other. Once the team grows beyond a certain limit, &lt;a href="http://en.wikipedia.org/wiki/Brooks's_law"&gt;the overhead of the communication&lt;/a&gt; makes it impossible to continuously get a full picture of what is being work on by whom.&lt;/p&gt;

&lt;p&gt;Usually this problem is minimized by having somebody responsible for each module, essentially putting some &lt;a href="http://en.wikipedia.org/wiki/Organizational_hierarchy"&gt;organizational hierarchy&lt;/a&gt; in the project. However, a slight problem in the communication (which happens quickly, we're talking about engineers here) is enough to provoke a situation where conflict occurs due to a certain check in which carries over the problems and bugs from one module to another (&lt;a href="http://en.wikipedia.org/wiki/Law_of_Unintended_Consequences"&gt;Law of Unintended Consequences&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Another approach, certainly an evolution from the first one, is &lt;b&gt;limited commit access&lt;/b&gt;. This particularly works well if there is a dedicated army of &lt;a href="http://en.wikipedia.org/wiki/Software_maintainer"&gt;maintainers&lt;/a&gt;, whose job is to review incoming patches, give feedback, check them in. Usually this approach is very beneficial for the new members of the team, because they can learn what works and what does not work (since they are indirectly guided by the maintainer).&lt;/p&gt;

&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Software_quality_assurance"&gt;Quality control&lt;/a&gt; is definitely easier since all patches will be always filtered. Limiting the damage due to a broken commit is also not difficult since the repository can be frozen while &lt;a href="http://en.wikipedia.org/wiki/Software_testing"&gt;the disaster mitigation team&lt;/a&gt; carries out the work.&lt;/p&gt;

&lt;p&gt;This approach however falls apart if there is not enough maintainers and/or the rate of submitted patches increases. The symptoms are easy to spot: patches stay far too long in the queue, a maintainer has no time to do his own development, bad patches sneak in due to the time pressure, etc.&lt;/p&gt;

&lt;p&gt;Keep in mind that due to its implicit (often also explicit) &lt;a href="http://en.wikipedia.org/wiki/Social_stratification"&gt;social stratification&lt;/a&gt;, it is important to take into account what everyone thinks about the approach. There should not be someone who feels &lt;a href="http://en.wikipedia.org/wiki/Second-class_citizen"&gt;left behind&lt;/a&gt; because only certain chosen guardians have the ultimate privilege access the repository. When such a situation is not tackled early on, it would &lt;a href="http://en.wikipedia.org/wiki/Social_conflict"&gt;grow latently and explode&lt;/a&gt; at some point in the future.&lt;/p&gt;

&lt;p&gt;If there is a worry like that, then another (slightly reversal) evolution is inevitable: &lt;b&gt;full access to everyone, as long as the patch is reviewed&lt;/b&gt;. The gut of this approach is basically &amp;quot;Let's trust each other, but let's also watch each other's back&amp;quot;. Thus, inherent &lt;a href="http://en.wikipedia.org/wiki/Code_review"&gt;code review&lt;/a&gt; becomes mandated as well. Everyone is free to check in his patch directly to the repository, as long as &lt;a href="http://en.wikipedia.org/wiki/Pair_programming"&gt;some other competent fellow&lt;/a&gt; has looked at it and gave the green light. In fact, this should be called &amp;quot;brotherhood repository access&amp;quot; except that it may sound too exclusive and mystical.&lt;/p&gt;

&lt;p&gt;Sometimes the system is also setup as far as rejecting the commit (e.g. &lt;a href="http://svnbook.red-bean.com/en/1.5/svn.reposadmin.create.html#svn.reposadmin.create.hooks"&gt;from the server-side&lt;/a&gt;) when the log does not contained something like &lt;i&gt;Reviewed by: Joe Sixpack&lt;/i&gt;. This is of course not always necessary, it may even require a consensus from everyone, under the pretext of &lt;a href="http://en.wikipedia.org/wiki/Human_reliability#Human_error"&gt;preventing accidental check in&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This last approach may still not work in some situations. For example, if the team is global and located in different time zones, then coordinating the review becomes challenging (distributed control system&lt;a href="http://benjamin-meyer.blogspot.com/2008/08/code-review-should-be-free.html"&gt; may alleviate the problem&lt;/a&gt;). When code review is not a encouraged culture, counterproductive dead lock can be depressing. Also, because it is based on &lt;a href="http://en.wikipedia.org/wiki/The_Toyota_Way#Respect_for_People"&gt;mutual trust&lt;/a&gt;, it breaks down when some people do not play by the same rule. In short, the approach depends heavily on the strong and committed communication between the team members.&lt;/p&gt;

&lt;p&gt;In the end, the repository access approach must be evaluated on &lt;a href="http://en.wikipedia.org/wiki/No_Silver_Bullet"&gt;a case by case basis&lt;/a&gt;. Of course, in some places, no approach will work to satisfy everyone. In that case, consider again that &lt;i&gt;technology can't and won't solve every social problem&lt;/i&gt;.&lt;/p&gt;

&lt;p&gt;What kind of repository access do you have in your group? Which one do you prefer and why?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-4971737531415735885?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/4971737531415735885/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=4971737531415735885' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/4971737531415735885'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/4971737531415735885'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/12/art-of-repository-access.html' title='the art of repository access'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm6.static.flickr.com/5123/5255057959_4bcc4220ac_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-8933873523808250945</id><published>2010-12-11T20:04:00.004+01:00</published><updated>2010-12-11T20:33:23.016+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='musing'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='devdays'/><title type='text'>ubiQt</title><content type='html'>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/5251560029/" title="devdays by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm6.static.flickr.com/5049/5251560029_d5e791b95d_z.jpg" width="640" height="482" alt="devdays" style="border: 1px solid #ccc; padding: 5px;"/&gt;&lt;/a&gt;&lt;p&gt;

&lt;p&gt;Since coming back from Qt Developer Days 2010 &lt;a href="http://qt.nokia.com/about/events/qt-developer-days-2010-sf/"&gt;in San Francisco&lt;/a&gt; (more precisely in &lt;a href="http://en.wikipedia.org/wiki/Burlingame,_California"&gt;Burlingame&lt;/a&gt;, near SF airport), one thought really bothered my mind: &amp;quot;when will Qt become ubiquitous?&amp;quot;.&lt;/p&gt;

&lt;p&gt;Now, if you are active in the &lt;a href="http://techbase.kde.org/"&gt;KDE&lt;/a&gt; and &lt;a href="http://developer.qt.nokia.com/"&gt;Qt community&lt;/a&gt;, this seems like a strange question. But ubiquitous means &lt;a href="http://en.wikipedia.org/wiki/Omnipresence"&gt;omnipresence&lt;/a&gt;, in particular for the whole developer community.&lt;/p&gt;

&lt;p&gt;Flash back to ages ago. You wrote a cool Python script (could be also in Ruby, or Lua, pick your battle) to do FooBar, everyone you know was impressed, you wanted to share the love with the world and then some fellow hacker noticed, &amp;quot;That's cool, man. But I don't want to install Python, can you give me the executable?&amp;quot;. What would you think?&lt;/p&gt;

&lt;p&gt;The situation is similar with Qt these days. You write a nice Qt-based utility, running on different platforms, somebody spots it and the first thing he asks is "Where is the binary?"; never mind he has just grabbed and installed hundreds MB worth of utilities.&lt;/p&gt;

&lt;p&gt;These days, when you are developing some software, the first thing you'd do on a fresh machine is to download and install a gazillion tools (Xcode with iOS SDK weighs around 3.8 GB). With the initiative towards &lt;a href="http://labs.qt.nokia.com/2010/06/03/qt-and-open-governance//"&gt;open governance&lt;/a&gt;, I hope Nokia and others will be able to steward Qt in that direction: being included in the &lt;i&gt;de-facto&lt;/i&gt; standard of development tool sets. The most interesting challenge is to overcome the doubt, &amp;quot;Why do I need to install some Nokia SDK to use your cool app?&amp;quot;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-8933873523808250945?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/8933873523808250945/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=8933873523808250945' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8933873523808250945'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8933873523808250945'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/12/ubiqt.html' title='ubiQt'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm6.static.flickr.com/5049/5251560029_d5e791b95d_t.jpg' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-6598490520692364709</id><published>2010-12-07T18:07:00.001+01:00</published><updated>2010-12-07T18:09:14.383+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='calligra'/><category scheme='http://www.blogger.com/atom/ns#' term='kde'/><category scheme='http://www.blogger.com/atom/ns#' term='koffice'/><title type='text'>calligra</title><content type='html'>&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/qmvthbbAhDxQ6VC3xVl6tg?feat=embedwebsite"&gt;&lt;img src="http://lh4.ggpht.com/_Oijhf1ZPv-4/TP5pv-K-GoI/AAAAAAAAByE/S9fruFLIdik/s800/calligra.png" height="249" width="600" /  style="border: none"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Long live &lt;a href="http://www.calligra-suite.org/"&gt;Calligra Suite&lt;/a&gt;!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-6598490520692364709?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/6598490520692364709/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=6598490520692364709' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/6598490520692364709'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/6598490520692364709'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/12/calligra.html' title='calligra'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_Oijhf1ZPv-4/TP5pv-K-GoI/AAAAAAAAByE/S9fruFLIdik/s72-c/calligra.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-6391817311925831463</id><published>2010-11-27T01:02:00.002+01:00</published><updated>2010-11-27T01:10:49.159+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qtwebkit'/><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='accelerometer'/><category scheme='http://www.blogger.com/atom/ns#' term='physics'/><title type='text'>Box of Marbles meets Device Orientation</title><content type='html'>&lt;p&gt;Remember &lt;a href="http://ariya.blogspot.com/2010/08/box-of-marbles_10.html"&gt;my Box of Marble demo?&lt;/a&gt;. It was a native Qt/C++ application running on Maemo-powered Nokia N900.&lt;/p&gt;

&lt;p&gt;With the wave of &lt;a href="http://dev.w3.org/geo/api/spec-source-orientation.html"&gt;DeviceOrientation Event Specification&lt;/a&gt; implementation, now it's possible to have the demo as a &lt;a href="http://en.wikipedia.org/wiki/Web_application"&gt;web app&lt;/a&gt;, running just inside the web browser. In fact, this is what you can see from this demo: &lt;a href="http://ariya.github.com/js/marblebox"&gt;ariya.github.com/js/marblebox.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Right now, it works with iPhone or iPad or iPod Touch running the new iOS 4.2, due to the brand new &lt;a href="http://developer.apple.com/library/safari/#documentation/SafariDOMAdditions/Reference/DeviceMotionEventClassRef/DeviceMotionEvent/DeviceMotionEvent.html"&gt;DeviceMotionEvent support&lt;/a&gt;. If you own a MacBook with accelerometer and you use Google Chrome, that works as well (tilt your laptop to see the gravity effect). But fear not, with &lt;a href="http://trac.webkit.org/changeset/69313"&gt;the recent support&lt;/a&gt; to hook the acceleration data from &lt;a href="http://qt.gitorious.org/qt-mobility"&gt;Qt Mobilty&lt;/a&gt; to &lt;a href="doc.qt.nokia.com/qtwebkit.html"&gt;QtWebKit&lt;/a&gt;, don't be shocked if the next Nokia phone with built-in QtWebKit sports this feature as well.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/4PxpeB07VjCy2dd_2OBbVQ?feat=embedwebsite"&gt;&lt;img src="http://lh3.ggpht.com/_Oijhf1ZPv-4/TPBJKx1j3aI/AAAAAAAABxo/I83qidUwWxE/s800/webmarble.png" height="300" width="400" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While my &lt;a href="http://ariya.blogspot.com/2010/08/box-of-marbles_10.html"&gt;previous demo&lt;/a&gt; uses &lt;a href="http://howlingmoonsoftware.com/chipmunk.php"&gt;Chipmunk physics engine&lt;/a&gt;, this web version relies on &lt;a href="http://box2d-js.sourceforge.net/"&gt;box2d-js&lt;/a&gt; instead, mostly because I am too lazy to port Chipmunk to JavaScript and also I want to try something else. If you are curious about the code, check the &lt;a href="http://gitorious.org/ofi-labs/X2"&gt;usual X2 repository&lt;/a&gt; under &lt;a href="http://gitorious.org/ofi-labs/x2/trees/master/javascript/marblebox"&gt;javascript/marblebox&lt;/a&gt; directory. Enjoy!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-6391817311925831463?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/6391817311925831463/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=6391817311925831463' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/6391817311925831463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/6391817311925831463'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/11/box-of-marbles-meets-device-orientation.html' title='Box of Marbles meets Device Orientation'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_Oijhf1ZPv-4/TPBJKx1j3aI/AAAAAAAABxo/I83qidUwWxE/s72-c/webmarble.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-6242500578762207111</id><published>2010-11-10T05:18:00.001+01:00</published><updated>2010-11-10T05:22:05.394+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='vim'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='sencha'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='script'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>V8 + jslint + vim</title><content type='html'>&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/2wvgP57gvrN_maLMUBlxZg?feat=embedwebsite"&gt;&lt;img src="http://lh4.ggpht.com/_Oijhf1ZPv-4/TNnqUUZNq1I/AAAAAAAABw0/cNK2IR9VIsI/s800/vim-jslint.png" height="447" width="600" style="border: 0px none; -webkit-box-shadow: none;"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Usually, you would want to use scripting solution, e.g. Perl/Python/whatever, to manipulate file contents. Somehow,  it's also fun to use JavaScript instead. After I did the &lt;a href="http://ariya.blogspot.com/2010/10/yet-another-command-line-javascript.html"&gt;V8-based jsbeautify&lt;/a&gt;, I was doing V8-based jslint as well. Then I realized, let's just extend it to be generic. With API loosely modelled after &lt;a href="http://wiki.commonjs.org/wiki/CommonJS"&gt;CommonJS&lt;/a&gt;, &lt;b&gt;filejs&lt;/b&gt; was born. Find it in the usual &lt;a href="http://gitorious.org/ofi-labs/X2"&gt;X2 repository&lt;/a&gt; under the &lt;a href="http://gitorious.org/ofi-labs/x2/trees/master/javascript/filejs"&gt;javascript/filejs&lt;/a&gt;. There are two examples so far, ROT-13 and line counter. If you write more examples, feel free to pass them to me!&lt;/p&gt;

&lt;p&gt;Of course, the twist is: use filejs to drive a command-line jslint. This is one way to do it. First build filejs (follow the instructions in the included README), then place the executable in your PATH. Create a simple shell script, which contains one line &lt;tt&gt;filejs /path/to/filejs/jslint.js $1&lt;/tt&gt; and make it executable. That's it! If you also store this shell script in your PATH, then you just need to run:&lt;/p&gt;

&lt;pre&gt;jslint source-code.js&lt;/pre&gt;

&lt;p&gt;If you use &lt;a href="http://www.vim.org"&gt;vim&lt;/a&gt;, jslint can be combined with &lt;a href="http://vimdoc.sourceforge.net/htmldoc/quickfix.html"&gt;Quickfix&lt;/a&gt;. First of all, associate *.js with the tool by putting this line in your personal &lt;tt&gt;.vimrc&lt;/tt&gt;:&lt;/p&gt;

&lt;pre&gt;au FileType javascript set makeprg=jslint\ %&lt;/pre&gt;

&lt;p&gt;Now open a JavaScript file and run &lt;tt&gt;:make&lt;/tt&gt; (or whatever shortcut you map this into), which will launch jslint with the current file. After a while, use &lt;tt&gt;:cope&lt;/tt&gt; to open the quickfix little &lt;a href="http://vimdoc.sourceforge.net/htmldoc/quickfix.html#errorformats"&gt;window&lt;/a&gt;, move up and down, and press Enter to bring you back to the main editor and set the cursor at the specified problem. Use standard window navigation, e.g. Ctrl+W W to switch to quickfix pane again. Check the &lt;a href="http://vimdoc.sourceforge.net/htmldoc/quickfix.html"&gt;quickfix documentation&lt;/a&gt; for details. All in all, you may want to &lt;a href="http://vimdoc.sourceforge.net/htmldoc/map.html#mapping"&gt;map&lt;/a&gt; mostly used commands to some shortcuts for faster access.&lt;/p&gt;

&lt;p&gt;Note that since this is dynamic JavaScript, rather than matching &lt;a href="http://vimdoc.sourceforge.net/htmldoc/quickfix.html#errorformats"&gt;errorformat&lt;/a&gt;, technically I just tweaked the tool to spit something similar to what a C/C++ compiler would do. Also, if you need different &lt;a href="http://www.jslint.com/#JSLINT_OPTIONS"&gt;jslint options&lt;/a&gt;, simply edit the invocation to suit your needs.&lt;/p&gt;

&lt;p&gt;It's been a while since I blogged about vim. The last one was about &lt;a href="http://ariya.blogspot.com/2008/07/vim-lightning-fast-navigation-in-large.html"&gt;the project plugin&lt;/a&gt;, which is surprisingly still &lt;a href="http://www.google.com/search?q=vim+large+project"&gt;quite popular&lt;/a&gt;. Hopefully this one also teaches you a trick or two, especially if you &lt;a href="http://www.sencha.com"&gt;work a lot&lt;/a&gt; with JavaScript code.&lt;/p&gt;

&lt;p&gt;Note 1: It does not work on Windows yet. No idea if I would have the time to do it, patch is welcomed.&lt;/p&gt;
&lt;p&gt;Note 2: This is not a replacement for &lt;a href="http://www.nodejs.org"&gt;NodeJS&lt;/a&gt;, nor would it grow to include more functions.&lt;/p&gt;
&lt;p&gt;Note 3: For the sake of completeness, let me mention that there are already other &lt;a href="http://www.google.com/search?q=command+line+jslint"&gt;countless solutions&lt;/a&gt; for command-line jslint (using Rhino, SpiderMonkey, JSC, etc), even &lt;a href="http://www.vim.org/scripts/script.php?script_id=2729"&gt;with vim integration&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-6242500578762207111?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/6242500578762207111/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=6242500578762207111' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/6242500578762207111'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/6242500578762207111'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/11/v8-jslint-vim.html' title='V8 + jslint + vim'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_Oijhf1ZPv-4/TNnqUUZNq1I/AAAAAAAABw0/cNK2IR9VIsI/s72-c/vim-jslint.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-2557204568567415108</id><published>2010-11-09T07:14:00.001+01:00</published><updated>2010-11-09T07:15:31.807+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>chunks inside PNG</title><content type='html'>&lt;p&gt;Here is a few minutes of hack which would hopefully help someone else:&lt;/p&gt;

&lt;pre&gt;pngchunks logo.png
File size: 5967 byte(s)

Offset    Chunk    Size
      8    IHDR      13
     33    iCCP    2627
   2672    IDAT    3271
   5955    IEND       0
&lt;/pre&gt;

&lt;p&gt;Useful to quickly find out if we can further strip unnecessary chunks from the &lt;a href="http://www.w3.org/TR/2003/REC-PNG-20031110/"&gt;PNG image&lt;/a&gt;. Or even as a warming up before you fire your favorite hex viewer/editor.&lt;/p&gt;

&lt;p&gt;It's pure, stand-alone, self-contained C code (i.e. compile using &lt;tt&gt;gcc -o pngchunks pngchunks.c&lt;/tt&gt;), available at the &lt;a href="http://gitorious.org/ofi-labs/X2"&gt;usual X2 repository&lt;/a&gt;, find it under &lt;a href="http://gitorious.org/ofi-labs/x2/trees/master/graphics/pngchunks"&gt;graphics/pngchunks&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-2557204568567415108?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/2557204568567415108/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=2557204568567415108' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2557204568567415108'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2557204568567415108'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/11/chunks-inside-png.html' title='chunks inside PNG'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-1941670561340330065</id><published>2010-11-05T20:44:00.005+01:00</published><updated>2010-11-05T21:02:28.785+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='sencha'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>the fun of remote JavaScript debugging</title><content type='html'>&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Oijhf1ZPv-4/TNRetdYdI4I/AAAAAAAABwE/TnZ8Jl9ysoY/s1600/RemoteJS-desktop.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 311px;" src="http://1.bp.blogspot.com/_Oijhf1ZPv-4/TNRetdYdI4I/AAAAAAAABwE/TnZ8Jl9ysoY/s400/RemoteJS-desktop.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5536153977019507586" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remote feature of &lt;a href="http://trac.webkit.org/wiki/WebInspector"&gt;Web Inspector&lt;/a&gt;, whereby you use an instance of WebKit and debug another one in different machine, is one important feature (that is being worked on) of WebKit I can't wait to start using. Till that day, remote debugging is always a challenge. There are of course assorted workarounds out there. At &lt;a href="http://www.sencha.com"&gt;Sencha&lt;/a&gt; we decide to have and share with you a little tool that helps &lt;a href="http://www.sencha.com/blog/2010/11/05/remote-javascript-debugging-on-android/"&gt;JavaScript remote debugging&lt;/a&gt;. It is available in two flavors: GUI-based (using Qt obviously) and Python-based for scripts and automation. Right now, the target is Android WebKit but there is no reason why we should not march to other platforms as well (e.g. QtWebKit on Symbian and MeeGo). &lt;a href="https://github.com/senchalabs/android-tools"&gt;Get it&lt;/a&gt; while it's hot!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-1941670561340330065?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/1941670561340330065/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=1941670561340330065' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1941670561340330065'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1941670561340330065'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/11/fun-of-remote-javascript-debugging.html' title='the fun of remote JavaScript debugging'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_Oijhf1ZPv-4/TNRetdYdI4I/AAAAAAAABwE/TnZ8Jl9ysoY/s72-c/RemoteJS-desktop.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-4602631942194293919</id><published>2010-10-28T22:22:00.005+02:00</published><updated>2010-10-31T07:18:49.389+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='effect'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>morphing clock revisited</title><content type='html'>&lt;p&gt;If you can't see the clock below, visit the &lt;a href="http://ariya.github.com/clock.htm"&gt;stand alone demo&lt;/a&gt;.&lt;/p&gt;

&lt;iframe src="http://ariya.github.com/clock.htm" style="border:none;width:500px;height:600px"&gt;&lt;/iframe&gt;

&lt;p&gt;Technically, I had wanted to wait till it can display the actual time and perhaps ask some designer to polish it. But rather than keeping this lunch-break hack in a safe deposit box forever, let me just release this ugly clock transition (since everyone is on the &lt;a href="http://www.sencha.com/products/animator/"&gt;animation frenzy&lt;/a&gt;). So far it works only if you use latest version of Safari, Chrome, Opera, Firefox.  Canvas and/or VML fallback (which sadly will require JavaScript) for other browser are in the pipeline.&lt;/p&gt;

&lt;p&gt;Basically it is another version of my previous &lt;a href="http://ariya.blogspot.com/2010/03/morphing-clock.html"&gt;morphing clock attempt&lt;/a&gt; (see &lt;a href=http://www.youtube.com/watch?v=mo8PZb_iPAI""&gt;the video&lt;/a&gt;). The principle is the same, except now I modified that C++ program to also output an HTML which renders the clock as above.&lt;p&gt;

&lt;p&gt;Also it morphs only once. Reload the page to enjoy the morphing once more. Maybe I'll find the time (in another lunch break) to toggle the two clock modes. &lt;b&gt;Update:&lt;/b&gt; morphing from/to both analog and digital mode is implemented.&lt;/p&gt;

&lt;p&gt;Like I said, it's a creepy, machine-generated, ugly looking clock. You've been warned, but feel free to write me anything (should you need to vent your anger).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-4602631942194293919?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/4602631942194293919/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=4602631942194293919' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/4602631942194293919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/4602631942194293919'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/10/morphing-clock-revisited.html' title='morphing clock revisited'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-950955088999958783</id><published>2010-10-27T07:07:00.002+02:00</published><updated>2010-10-29T08:48:23.054+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qtwebkit'/><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='palo alto'/><category scheme='http://www.blogger.com/atom/ns#' term='sencha'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='effect'/><title type='text'>Look ma, no JavaScript!</title><content type='html'>&lt;p&gt;Take a look at the following CSS 3 demo. No Flash. No JavaScript. No image.&lt;/p&gt;

&lt;iframe src="http://ariya.github.com/bonding.htm" style="border:none;width:320px;height:320px"&gt;&lt;/iframe&gt;


&lt;p&gt;Hungry for more? Enjoy &lt;a href="http://www.sencha.com/products/animator/"&gt;some other demos&lt;/a&gt; created using Sencha Animator.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-950955088999958783?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/950955088999958783/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=950955088999958783' title='19 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/950955088999958783'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/950955088999958783'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/10/look-ma-no-javascript.html' title='Look ma, no JavaScript!'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><thr:total>19</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-3295524084584122273</id><published>2010-10-18T19:24:00.001+02:00</published><updated>2010-10-18T19:26:04.937+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='palo alto'/><category scheme='http://www.blogger.com/atom/ns#' term='sencha'/><category scheme='http://www.blogger.com/atom/ns#' term='musing'/><category scheme='http://www.blogger.com/atom/ns#' term='san francisco'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='devdays'/><title type='text'>Qt Developer Days, Bay Area Mobile meetup</title><content type='html'>&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Oijhf1ZPv-4/TJTVgwjGGkI/AAAAAAAABuY/un4Wzvj1i2o/s1600/qtdd2010.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 178px; height: 136px;" src="http://4.bp.blogspot.com/_Oijhf1ZPv-4/TJTVgwjGGkI/AAAAAAAABuY/un4Wzvj1i2o/s400/qtdd2010.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5518270202200332866" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We heard that &lt;a href="http://blog.qt.nokia.com/2010/10/15/developer-days-munich-2010-the-best-qt-event-ever/"&gt;Munich Qt Developer Days&lt;/a&gt; was an awesome event, which is why I look forward to the San Francisco Qt Developer Days, which will be held November 1-3.&lt;/p&gt;

&lt;p&gt;Now, if you are from outside US, drop me an email in case you fancy some quality tea/coffee time. Even better, on the next day (November 4), &lt;a href="http://www.sencha.com/"&gt;Sencha&lt;/a&gt; will host the first &lt;a href="http://www.meetup.com/BayAreaMobile/calendar/15142674/"&gt;Meet the Sencha Team&lt;/a&gt;, the first &lt;a href="http://www.meetup.com/BayAreaMobile/"&gt;Bay Area Mobile&lt;/a&gt; meetup.  Our team will give an overview of Sencha and the mobile technologies we are developing. RSVP and drop by!&lt;/p&gt;

&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Oijhf1ZPv-4/TLyC6mcP8NI/AAAAAAAABv8/XzSfMuGoveQ/s1600/global_18372261.jpeg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 180px; height: 180px;" src="http://4.bp.blogspot.com/_Oijhf1ZPv-4/TLyC6mcP8NI/AAAAAAAABv8/XzSfMuGoveQ/s400/global_18372261.jpeg" border="0" alt=""id="BLOGGER_PHOTO_ID_5529438385767182546" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-3295524084584122273?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/3295524084584122273/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=3295524084584122273' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/3295524084584122273'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/3295524084584122273'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/10/qt-developer-days-bay-area-mobile.html' title='Qt Developer Days, Bay Area Mobile meetup'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_Oijhf1ZPv-4/TJTVgwjGGkI/AAAAAAAABuY/un4Wzvj1i2o/s72-c/qtdd2010.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-9109786711939988530</id><published>2010-10-14T20:37:00.001+02:00</published><updated>2010-10-14T20:39:53.491+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='palo alto'/><category scheme='http://www.blogger.com/atom/ns#' term='sencha'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>sencha touch hackathon</title><content type='html'>&lt;p&gt;&lt;img src="http://lh3.ggpht.com/_Oijhf1ZPv-4/TGJKVQA3TXI/AAAAAAAABrM/gkaRF85wbAY/s800/sencha_logo.png" border="0"&gt;&lt;/p&gt; 

&lt;p&gt;Are you in the Bay Area? Don't miss our &lt;a href="http://www.sencha.com/blog/2010/10/13/sencha-touch-dev-contest-hackathon/"&gt;Sencha Touch Hackathon&lt;/a&gt; this Saturday (Oct 16) in our &lt;a href="http://maps.google.com/maps?f=q&amp;source=s_q&amp;hl=en&amp;geocode=&amp;q=525+University+Ave,+Palo+Alto,+CA+94301&amp;sll=37.448896,-122.159338&amp;sspn=0.008211,0.006899&amp;ie=UTF8&amp;hq=&amp;hnear=525+University+Ave,+Palo+Alto,+Santa+Clara,+California+94301&amp;t=h&amp;z=17&amp;iwloc=A"&gt;Palo Alto Office&lt;/a&gt;, 1pm to 5pm. There will be food and drinks as well.&lt;/p&gt;

&lt;p&gt;Drop by and upgrade your Sencha Touch kungfu!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-9109786711939988530?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/9109786711939988530/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=9109786711939988530' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/9109786711939988530'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/9109786711939988530'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/10/sencha-touch-hackathon.html' title='sencha touch hackathon'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_Oijhf1ZPv-4/TGJKVQA3TXI/AAAAAAAABrM/gkaRF85wbAY/s72-c/sencha_logo.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-4254995443414662187</id><published>2010-10-14T07:48:00.002+02:00</published><updated>2010-10-18T12:19:00.709+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='sencha'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>yet another command-line JavaScript beautifier (based on V8)</title><content type='html'>&lt;p&gt;While we're still on &lt;a href="http://ariya.blogspot.com/2010/10/on-javascript-engines.html"&gt;the topic of JavaScript&lt;/a&gt;, I took the afternoon break to create a command-line runner for &lt;a href="http://jsbeautifier.org/"&gt;jsbeautifier.org&lt;/a&gt; . In case you miss it, I did the similar thing &lt;a href="http://ariya.blogspot.com/2010/09/offline-command-line-beautifier-for.html"&gt;using Qt Script module&lt;/a&gt;. This time however, the command-line tool uses and exploits &lt;a href="http://v8.googlecode.com"&gt;Google V8&lt;/a&gt; instead.&lt;/p&gt;

&lt;p&gt;If you update your clone of &lt;a href="http://github.com/einars/js-beautify"&gt;js-beautify repository&lt;/a&gt;, check out the fresh v8 subdirectory. I also mirror the code in the usual &lt;a href="http://gitorious.org/ofi-labs/X2"&gt;X2 repository&lt;/a&gt;, under the &lt;a href="http://gitorious.org/ofi-labs/x2/trees/master/javascript/jsbeautify8"&gt;javascript/jsbeautify8&lt;/a&gt; subdirectory. Also, grok the included README.txt first.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Update&lt;/b&gt;: I added &lt;a href="http://github.com/einars/js-beautify/commit/10384df6"&gt;--overwrite option&lt;/a&gt; which (surprise!) will overwrite the original source file (and thus, use it with care). This is useful if you invoke the beautifier tool from your text editor. Nicolas also implemented &lt;a href="http://github.com/einars/js-beautify/commit/31c3c10b"&gt;various settings support&lt;/a&gt; so you can specify the indentation level, braces placement, etc. &lt;/p&gt;

&lt;p&gt;This is probably the last thing the world needs now, but hey, it was a fun break.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-4254995443414662187?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/4254995443414662187/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=4254995443414662187' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/4254995443414662187'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/4254995443414662187'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/10/yet-another-command-line-javascript.html' title='yet another command-line JavaScript beautifier (based on V8)'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-8964181569060936191</id><published>2010-10-13T18:33:00.001+02:00</published><updated>2010-10-13T18:39:05.936+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='kde'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='script'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><category scheme='http://www.blogger.com/atom/ns#' term='n900'/><title type='text'>on JavaScript engines</title><content type='html'>&lt;p&gt;If you are using a modern browser, likely you already have the (arguably) most widely deployed scripting environment: &lt;a href="http://en.wikipedia.org/wiki/JavaScript_engine"&gt;JavaScript engine&lt;/a&gt; (or ECMAScript, if you insist). There are many things you can do with it (just look at tons of cool web apps out there). However, since it is contained in the browser, there are also things the embedded JavaScript engine can not do for you.&lt;/p&gt;

&lt;p&gt;If you are using KDE, you also have two excellent JavaScript engines: &lt;a href="http://api.kde.org/4.x-api/kdelibs-apidocs/kjs/html/"&gt;KJS&lt;/a&gt; and &lt;a href="http://doc.qt.nokia.com/4.7/qtscript.html"&gt;Qt Script&lt;/a&gt;. You can embed either of them (i.e. &lt;a href="http://api.kde.org/4.x-api/kdelibs-apidocs/kjsembed/html/"&gt;KJSEmbed&lt;/a&gt;) and make your application scriptable. In a not-so-strange twist, they both relate (distantly) to each other via JavaScriptCore, WebKit's default JavaScript engine, because 
long time ago Apple &lt;a href="http://web.archive.org/web/20070310215550/www.opendarwin.org/pipermail/kde-darwin/2002-June/000034.html"&gt;forked KJS&lt;/a&gt; and used it as the base for JavaScriptCore, and Qt Script (for version 4.6 and 4.7) also &lt;a href="http://labs.qt.nokia.com/2009/06/16/using-javascriptcore-as-the-qtscript-back-end/"&gt;uses JavaScriptCore&lt;/a&gt; as the back-end.&lt;/p&gt;

&lt;p&gt;If you are interested in learning, using, and/or dissecting other open-source JavaScript engines, have a look at &lt;a href="http://www.sencha.com/blog/2010/10/12/javascript-engines-how-to-compile-them/"&gt;JavaScript Engines: How to Compile Them&lt;/a&gt; I wrote for our Sencha blog, which covers Mozilla's SpiderMonkey, WebKit's JavaScriptCore, and Google V8. The instructions should work on the supported platforms, including ARM, in case (just like me) you want to have and carry around every JavaScript engines in this planet on your Maemo-powered Nokia N900. That is fun.&lt;p&gt;

&lt;p&gt;As the closing, just remember, &amp;quot;Ask not what the JavaScript engine can do for you — ask what you can do for the JavaScript engine&amp;quot;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-8964181569060936191?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/8964181569060936191/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=8964181569060936191' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8964181569060936191'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8964181569060936191'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/10/on-javascript-engines.html' title='on JavaScript engines'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-5254108315920421937</id><published>2010-10-08T19:35:00.003+02:00</published><updated>2010-10-08T19:38:50.247+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='sencha'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>cinquantamila</title><content type='html'>&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Oijhf1ZPv-4/TK9WZCTa04I/AAAAAAAABvk/af8QvE7AovE/s1600/sencha_contest.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 400px;" src="http://4.bp.blogspot.com/_Oijhf1ZPv-4/TK9WZCTa04I/AAAAAAAABvk/af8QvE7AovE/s400/sencha_contest.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5525730255921927042" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;'nuff said, head to &lt;a href="http://www.sencha.com/contest/"&gt;www.sencha.com/contest&lt;/a&gt;!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-5254108315920421937?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/5254108315920421937/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=5254108315920421937' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/5254108315920421937'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/5254108315920421937'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/10/cinquantamila.html' title='cinquantamila'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_Oijhf1ZPv-4/TK9WZCTa04I/AAAAAAAABvk/af8QvE7AovE/s72-c/sencha_contest.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-5973316664066832332</id><published>2010-10-06T09:47:00.001+02:00</published><updated>2010-10-06T09:51:52.988+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qtwebkit'/><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='qualcomm'/><category scheme='http://www.blogger.com/atom/ns#' term='colors'/><category scheme='http://www.blogger.com/atom/ns#' term='skia'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><title type='text'>color inversion for web pages</title><content type='html'>&lt;p&gt;Something I worked on during my &lt;a href="http://ariya.blogspot.com/2010/08/even-lost-has-its-season-finale.html"&gt;last few weeks with Qualcomm&lt;/a&gt; was color inversion for the web browser in Android. The patch was then integrated by Enrico (see &lt;a href="https://www.codeaurora.org/gitweb/quic/la/?p=platform/external/webkit.git;a=commitdiff;h=eba28144"&gt;the diff&lt;/a&gt;) because &lt;a href="http://ariya.blogspot.com/2010/08/adventure-to-land-of-green-tea.html"&gt;I switched job&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Later on this feature was also &lt;a href="http://github.com/CyanogenMod/android_external_webkit/commit/7d65dc46"&gt;pulled into CyanogenMod&lt;/a&gt;. Thus, if you are running &lt;a href="http://www.cyanogenmod.com/"&gt;CyanogenMod 6&lt;/a&gt; on your shiny Android device, you can try this feature already! In the web browser, just pick the &lt;i&gt;Settings&lt;/i&gt; menu and then scroll a bit until you see a checkbox for &lt;i&gt;Invert Color&lt;/i&gt;. You should get something like the captured screens below:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/1M-X6DbgGBAqIQdObnas9w?feat=embedwebsite"&gt;&lt;img src="http://lh5.ggpht.com/_Oijhf1ZPv-4/TKwh7JR4JVI/AAAAAAAABvU/NGDrGfqBuBY/s800/android_nightmode.png" height="480" width="600" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The idea behind this is to reduce the power consumption of &lt;a href="http://en.wikipedia.org/wiki/Organic_LED"&gt;Organic LED display&lt;/a&gt;, because on mostly-white web page, it hungrily &lt;a href="http://en.wikipedia.org/wiki/Organic_LED#Disadvantages"&gt;grabs to 3x more power&lt;/a&gt; compared to LCD.  This is similar to Jeff's trick of applying &lt;a href="http://jsharkey.org/blog/2010/07/01/android-surfaceflinger-tricks-for-fun-and-profit/"&gt;color filter in SurfaceFlinger&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Doing it at the user-space level gives one advantage: we can keep the embedded images non-inverted. Blindly inverting the entire screen would result in web pages look rather funky, especially those new sites with photos to accompany the articles. Of course, this hackish approach will not work 100%, (hint: double XOR?) since the web designer likely never intend the page to be color inverted. However it seems to work most of the time, at least with pages which do not have ueberartistic look-and-feel.&lt;/p&gt;

&lt;p&gt;Faithful followers of my blog know that I already &lt;a href="http://ariya.blogspot.com/2009/07/save-me-from-being-confused-show-me.html"&gt;played with the color inversion&lt;/a&gt; ages ago, in the form of giving &lt;i&gt;night mode&lt;/i&gt; appearance for QWebView. Thus, it happened that in one afternoon break I played with QtWebKit to do something similar to this selective color inversion.&lt;/p&gt;

&lt;p&gt;Now, in the case of Android WebKit, the effect was rather easy to achieve. This is because Skia's &lt;a href="http://code.google.com/p/skia/wiki/SkCanvas"&gt;SkCanvas&lt;/a&gt; is basically an interface which can be subclassed easily, while none of the functions in &lt;a href="http://doc.qt.nokia.com/4.7/qpainter.html"&gt;QPainter&lt;/a&gt; is virtual. The trick using Skia was to use a proxy canvas (a slight variation of Skia's built-in SkProxyCanvas) which I invented for this purpose but somehow also &lt;a href="https://www.codeaurora.org/gitweb/quic/la/?p=platform/external/webkit.git;a=commitdiff;h=ec1ce8d8"&gt;useful for another feature&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For QtWebKit however, we need to tweak it with some &lt;a href="doc.qt.nokia.com/qpaintengine.html"&gt;QPaintEngine&lt;/a&gt; voodoo. Check out the code at the &lt;a href="http://gitorious.org/ofi-labs/X2"&gt;usual X2 repository&lt;/a&gt;, find it under &lt;a href="http://gitorious.org/ofi-labs/x2/trees/master/webkit/nightcapture"&gt;webkit/nightcapture&lt;/a&gt; (it still has some rooms for improvement, left as exercises for the adventurous readers). For simplicity, I made it as capturing tool so you need to pass a URL and the output filename. Unless you do something wrong, expect to get something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/RiZ8tOtu6f9YxhQ1CDlZPA?feat=embedwebsite"&gt;&lt;img src="http://lh3.ggpht.com/_Oijhf1ZPv-4/TKwjvnbgHNI/AAAAAAAABvc/z-mf88Gs_YY/s800/qtwebkit_nightmode.png" height="445" width="600" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The trick is the same as my approach for the Android patch: invert the colors of each image before drawing it, at the end invert the entire viewport. This seems like slow, but it's the best compromise I found out working with most sites. Note how we skip inverting any brush pixmap as usually brush is for the tiled background (and thus we want to keep it that way, i.e. not inverted). You can do some fancy magic with clipping and whatnot, but I doubt the end result is much better. Again, this whole stuff is a hack anyway and there will be always corner cases which will not work, &lt;i&gt;no matter&lt;/i&gt; what approach you pick, thus there is no need to make it more complicated that it should be. &lt;/p&gt;

&lt;p&gt;Just like they say, we code for life, i.e. the &lt;i&gt;battery life&lt;/i&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-5973316664066832332?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/5973316664066832332/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=5973316664066832332' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/5973316664066832332'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/5973316664066832332'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/10/color-inversion-for-web-pages.html' title='color inversion for web pages'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_Oijhf1ZPv-4/TKwh7JR4JVI/AAAAAAAABvU/NGDrGfqBuBY/s72-c/android_nightmode.png' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-7694388795961101576</id><published>2010-10-03T21:41:00.001+02:00</published><updated>2010-10-03T21:43:02.551+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='musing'/><title type='text'>quattroporte and hummingbird</title><content type='html'>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/5048450998/" title="time is money by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm5.static.flickr.com/4110/5048450998_33a004b9f3_z.jpg" width="640" height="427" alt="time is money" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fermi problem of the day, anyone?&lt;/p&gt;

&lt;p&gt;Assume there is this large organization, say with over ten thousands employees. For some (legal) reason, each employee needs to write down what she has been doing for the week, usually by Friday afternoon. Some record everything in details (down to the hours), some prefer to just express &amp;quot;8 hours doing FooBar&amp;quot; for every working day.&lt;/p&gt;

&lt;p&gt;Since this is 2010, usually the system is web-based. To prevent abuse, some login/credential check and anti-bot system are also in place. It is often unheard that people use their beloved smartphones to do the job.&lt;/p&gt;

&lt;p&gt;Let us say it takes one minute to do this. With a really conservative $30/hour rate, this is worth 50 cents. Assume ten thousands do that, so it's worth $5,000. This translates to $260,000 per year.&lt;/p&gt;

&lt;p&gt;Of course this is just &lt;a href="http://en.wikipedia.org/wiki/Fermi_problem"&gt;a gross approximation&lt;/a&gt;. It does not even include/exclude the extra time the managers spend to double-check their staff's entries, typically (much) higher hourly rates, non-working (also known as vacation time), wasted effort to setup (and forget) the reminders, occasional weekend shock at times you forgot it, and other similar (intangible) overhead. Or if you just need 5 seconds to accomplish the task. But you get the idea.&lt;/p&gt;

&lt;p&gt;Now, $260,000 is a lot of money. You can buy a decent house in San Diego. Or two shiny Maserati Quattroporte. Or several hundreds Hummingbird-powered phones. Or, in some parts of the world, access to fresh water for the entire city all year long.&lt;/p&gt;

&lt;p&gt;Surely for a quarter million per year some smart people will figure something out?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-7694388795961101576?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/7694388795961101576/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=7694388795961101576' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/7694388795961101576'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/7694388795961101576'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/10/quattroporte-and-hummingbird.html' title='quattroporte and hummingbird'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm5.static.flickr.com/4110/5048450998_33a004b9f3_t.jpg' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-2584941213235277585</id><published>2010-09-24T07:52:00.001+02:00</published><updated>2010-09-24T07:55:33.234+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qtwebkit'/><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='sencha'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>invade &amp; destroy</title><content type='html'>&lt;p&gt;Developing &lt;a href="http://www.canvasdemos.com/type/games/"&gt;games using HTML5 Canvas&lt;/a&gt; and JavaScript is simply the future. Something classic like Egor Balishev's &lt;a href="http://10k.aneventapart.com/Entry/392"&gt;RGB Invader&lt;/a&gt;, an entry in the &lt;a href="http://10k.aneventapart.com/"&gt;10K Apart&lt;/a&gt;, is usually my favorite.&lt;/p&gt;

&lt;p&gt;If for some reasons (which I would not elaborate in this post) you need to deploy the game as a desktop or a mobile application, using Canvas and JavaScript gives another advantage: just package it with WebKit, for example QtWebKit if you do not mind using Qt.&lt;/p&gt;

&lt;p&gt;However, since usually it is just about Canvas, often it is enough to run the game logic with a JavaScript interpreter and use some Canvas implementation for the display. This was something that &lt;a href="http://ariya.blogspot.com/2009/05/chrome-experiments-flash-killer-monster.html"&gt;I demonstrated before&lt;/a&gt;, i.e. running the Monster Evolution demo via JavaScriptCore and V8. Applying the same technique, and adjusting the shim so that it layers whatever RGB Invader requires, gives the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/EuT3Yzq5ApO63p3WmSONHA?feat=embedwebsite"&gt;&lt;img src="http://lh3.ggpht.com/_Oijhf1ZPv-4/TJwc8JOeF8I/AAAAAAAABu0/H_Q3Fv3Qcuc/s800/invader.png" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Basically it is using &lt;a href="http://doc.qt.nokia.com/4.6/qtscript.html"&gt;Qt Script&lt;/a&gt; (also in attempt &lt;a href="http://ariya.blogspot.com/2010/09/offline-command-line-beautifier-for.html"&gt;to popularize it&lt;/a&gt; even more) along with a mix of C++/QObject and JavaScript machinery to fool the game code to think it's running in a browser environment. It was a nice afternoon fun project.&lt;/p&gt;

&lt;p&gt;The code is in the &lt;a href="http://gitorious.org/ofi-labs/X2"&gt;X2 repository&lt;/a&gt;, find it under the &lt;a href="http://gitorious.org/ofi-labs/x2/trees/master/javascript/invader"&gt;javascript/invader&lt;/a&gt; directory. Get it while it's hot, and save our Earth!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-2584941213235277585?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/2584941213235277585/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=2584941213235277585' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2584941213235277585'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2584941213235277585'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/09/invade-destroy.html' title='invade &amp; destroy'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_Oijhf1ZPv-4/TJwc8JOeF8I/AAAAAAAABu0/H_Q3Fv3Qcuc/s72-c/invader.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-7945501154811476847</id><published>2010-09-20T20:28:00.002+02:00</published><updated>2010-09-20T20:36:28.532+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='sencha'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>offline, command-line beautifier for JavaScript code</title><content type='html'>&lt;p&gt;There are many different ways to autoformat JavaScript code, my favorite is always &lt;a href="http://jsbeautifier.org/"&gt;jsbeautifier.org&lt;/a&gt;. Apparently, you can also use it locally without a web browser since &lt;a href="http://github.com/einars/js-beautify"&gt;it supports&lt;/a&gt; running it with &lt;a href="http://www.mozilla.org/rhino/"&gt;Rhino&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It took me just few minutes to reimplement the same functionality, but using &lt;a href="http://doc.qt.nokia.com/4.6/qtscript.html"&gt;Qt Script&lt;/a&gt;, the fantastic &lt;a href="http://en.wikipedia.org/wiki/ECMAScript"&gt;ECMAScript&lt;/a&gt; support built into Qt.&lt;/p&gt;

&lt;p&gt;The code is in the usual &lt;a href="http://gitorious.org/ofi-labs/X2"&gt;X2 repository&lt;/a&gt;, under the &lt;a href="http://gitorious.org/ofi-labs/x2/trees/master/javascript/jsbeautify"&gt;javascript/jsbeautify&lt;/a&gt;. Note that this is just a convenient mirror as &lt;a href="http://github.com/einars/js-beautify"&gt;Einar's js-beautify repository&lt;/a&gt; already includes this Qt Script driver.&lt;/p&gt;

&lt;p&gt;With the rise of server-side JavaScript and desktop-esque JavaScript tools, I hope Qt Script will become more popular. It is sadly still &amp;quot;underrated&amp;quot; right now.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-7945501154811476847?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/7945501154811476847/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=7945501154811476847' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/7945501154811476847'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/7945501154811476847'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/09/offline-command-line-beautifier-for.html' title='offline, command-line beautifier for JavaScript code'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-1961702450454326042</id><published>2010-09-18T17:05:00.003+02:00</published><updated>2010-09-18T17:13:45.605+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='musing'/><category scheme='http://www.blogger.com/atom/ns#' term='san francisco'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='devdays'/><title type='text'>san francisco</title><content type='html'>&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Oijhf1ZPv-4/TJTVgwjGGkI/AAAAAAAABuY/un4Wzvj1i2o/s1600/qtdd2010.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 178px; height: 136px;" src="http://4.bp.blogspot.com/_Oijhf1ZPv-4/TJTVgwjGGkI/AAAAAAAABuY/un4Wzvj1i2o/s400/qtdd2010.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5518270202200332866" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have been in &lt;a href="http://ariya.blogspot.com/search/label/devdays"&gt;Qt Developer Days&lt;/a&gt; twice, in the previous two years. This year I am still going there, but only the &lt;a href="http://qt.nokia.com/about/events/qt-developer-days-2010-sf/"&gt;San Francisco event&lt;/a&gt;, for the first time as a participant (as opposed to as a speaker). I'll bring other &lt;a hrref="http://www.sencha.com/company/team.php"&gt;new engineers&lt;/a&gt; at Sencha, too.&lt;/p&gt;

&lt;p&gt;Since I live in the Bay Area these days, feel free to email me should you want to meet for coffee/lunch/dinner. See you there!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-1961702450454326042?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/1961702450454326042/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=1961702450454326042' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1961702450454326042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1961702450454326042'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/09/san-francisco.html' title='san francisco'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_Oijhf1ZPv-4/TJTVgwjGGkI/AAAAAAAABuY/un4Wzvj1i2o/s72-c/qtdd2010.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-2894194216477873024</id><published>2010-09-13T22:17:00.001+02:00</published><updated>2010-09-13T22:18:26.801+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='geolocation'/><category scheme='http://www.blogger.com/atom/ns#' term='openstreetmap'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='mapquest'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><category scheme='http://www.blogger.com/atom/ns#' term='n900'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>geocoding based on IP address</title><content type='html'>&lt;p&gt;Given an IP address, there are different ways to obtain the approximate location: online web service or offline database. It is far from perfect, but it is very useful to give some initial guess before locking into GPS signals or using WiFi-based tracking.&lt;/p&gt;

&lt;p&gt;Today's example for X2 is actually an old code lying around which does the former: relying on &lt;a href="http://ipinfodb.com/my_ip_location.php"&gt;IpInfoDB web service&lt;/a&gt; to guess where your computer is. Combined with the previous example, &lt;a href="http://ariya.blogspot.com/2010/09/capture-openstreetmap-and-mapquest-and.html"&gt;MapSnap&lt;/a&gt;, the guessed position is used to center the shown map (OpenStreetMap, of course).&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/aNW_ou2U_9nDVM3l5wt0SA?feat=embedwebsite"&gt;&lt;img src="http://lh4.ggpht.com/_Oijhf1ZPv-4/TI5H7UiovTI/AAAAAAAABuQ/yYXDvF6YA1Y/s800/ipgeocoder.png" style="padding: 0; border: 1px solid black;"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, as with &lt;a href="http://ariya.blogspot.com/search/label/maemo"&gt;other examples&lt;/a&gt;, it works fine on &lt;a href="http://www.maemo.org"&gt;Maemo&lt;/a&gt;-powered &lt;a href="http://en.wikipedia.org/wiki/Nokia_N900"&gt;Nokia N900&lt;/a&gt; as well. Feel free to give it a try on Symbian or other supported Qt platforms.&lt;/p&gt;

&lt;p&gt;The code is found in the usual &lt;a href="http://gitorious.org/ofi-labs/X2"&gt;X2 repository&lt;/a&gt;, under the &lt;a href="http://gitorious.org/ofi-labs/x2/trees/master/sensor/ipgeocoder"&gt;sensor/ipgeocoder&lt;/a&gt; subdirectory.&lt;/p&gt;

&lt;p&gt;For completeness' sake, let me mention also that Matteo &lt;a href="http://th30z.netsons.org/2009/06/qt4-geo-ip-location/"&gt;did something similar&lt;/a&gt;, using &lt;a href="http://www.hostip.info"&gt;hostip.info&lt;/a&gt; and &lt;a href="http://maps.google.com"&gt;Google Maps&lt;/a&gt; via &lt;a href="http://doc.qt.nokia.com/4.6/webintegration.html"&gt;QtWebKit&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-2894194216477873024?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/2894194216477873024/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=2894194216477873024' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2894194216477873024'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2894194216477873024'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/09/geocoding-based-on-ip-address.html' title='geocoding based on IP address'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_Oijhf1ZPv-4/TI5H7UiovTI/AAAAAAAABuQ/yYXDvF6YA1Y/s72-c/ipgeocoder.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-3459806421306622299</id><published>2010-09-13T03:52:00.001+02:00</published><updated>2010-09-13T03:53:45.123+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='openstreetmap'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='ovi'/><category scheme='http://www.blogger.com/atom/ns#' term='mapquest'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>capture OpenStreetMap and MapQuest (and Ovi Maps)</title><content type='html'>&lt;p&gt;Over a year ago, I showed &lt;a href="http://labs.trolltech.com/blogs/2009/08/04/openstreetmap-and-qt-and-s60/"&gt;how to render OpenStreetMap&lt;/a&gt; on your Qt application. While there were few follow-ups after that, I never found some time to clean it up. But worry no more, here is one &lt;a href="http://www.openstreetmap.org"&gt;OpenStreetMap-related&lt;/a&gt; example (at roughly 250 lines of code) I just made public, freshly available from &lt;a href="http://gitorious.org/ofi-labs/X2"&gt;X2 repository&lt;/a&gt; under the &lt;a href="http://gitorious.org/ofi-labs/x2/trees/master/graphics/mapsnap"&gt;graphics/mapsnap&lt;/a&gt;. It's operated from command line, basically you pass the center latitude and longitude, zoom level (1..17, with 17 is the detailed, street-level zoom), output filename (e.g. mymap.png), and the size.&lt;/p&gt;

&lt;p&gt;The following image is the result of running:&lt;/p&gt;

&lt;pre&gt;mapsnap 37.45108 -122.15917 12 sample.png 600 450&lt;/pre&gt;

&lt;p&gt;The tool will grab the tiles, more precisely &lt;a href="http://wiki.openstreetmap.org/wiki/Slippy_Map#Mapnik_tile_rendering"&gt;Mapnik-rendered tile images&lt;/a&gt;, and stitch them for the final outcome:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/HqUqxBIYVEdcMjF4AFCeZw?feat=embedwebsite"&gt;&lt;img src="http://lh3.ggpht.com/_Oijhf1ZPv-4/TIyPQkKE_tI/AAAAAAAABuA/vNNG4DXXqwg/s800/mapsnap_osm.png" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Few weeks ago &lt;a href="http://ariya.blogspot.com/2010/08/crowdsourcing-for-win.html"&gt;I wrote about MapQuest embracing OpenStreetMap&lt;/a&gt;. One positive impact of this awesome move is that you can show OpenStreetMap-based &lt;a href="http://wiki.openstreetmap.org/wiki/Mapquest"&gt;MapQuest tiles&lt;/a&gt; in your application. It's just the same map data but rendered using different styles. Running the previous example but with MapQuest flavor gives the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/UI5gXiA79AEKcnjo6k7Edw?feat=embedwebsite"&gt;&lt;img src="http://lh4.ggpht.com/_Oijhf1ZPv-4/TIyPRPk_UiI/AAAAAAAABuE/g9bdN6AJC94/s800/mapsnap_mapquest.png" border="0"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When checking out Qt Mobility after its &lt;a href="labs.qt.nokia.com/blogs/2010/07/27/qt-mobility-110-technology-preview/"&gt;1.1 TP announcement&lt;/a&gt;, I found out that &lt;a href="http://developer.qt.nokia.com/wiki/MapsNavigationAPI"&gt;its Maps/Navigation API&lt;/a&gt; actually uses the tile data from &lt;a href="http://maps.ovi.com"&gt;Ovi Maps&lt;/a&gt;. If you read the source code, the tile server encoding scheme is pretty obvious. Since it is also based on &lt;a href="http://en.wikipedia.org/wiki/Mercator_projection"&gt;Mercator projection&lt;/a&gt;, changing this MapSnap example to use tiles from Ovi Maps is a breeze: it's a matter of setting up the correct tileURL.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/5NbojoK0Y_VFEmr0Ei2X0A?feat=embedwebsite"&gt;&lt;img src="http://lh5.ggpht.com/_Oijhf1ZPv-4/TIyPRRlb-OI/AAAAAAAABuI/pG_D9cV4w8A/s800/mapsnap_ovimaps.png" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;I'm curious about the terms of such Ovi Maps tile usage, though. Although it is more or less &amp;quot;exposed&amp;quot; via Qt Mobility and there is no API key whatsoever, surely it should not mean the tiles are free for everyone, should it? As a comparison, &lt;a href="http://code.google.com/apis/maps/faq.html#mapsformobile"&gt;Google Static Maps API&lt;/a&gt; specifically allows &lt;a href="http://wiki.forum.nokia.com/index.php/Talk:How_to_use_Google_Maps_data_in_mobile_applications"&gt;only browser-based application&lt;/a&gt;. Feel free to share your investigation!&lt;p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-3459806421306622299?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/3459806421306622299/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=3459806421306622299' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/3459806421306622299'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/3459806421306622299'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/09/capture-openstreetmap-and-mapquest-and.html' title='capture OpenStreetMap and MapQuest (and Ovi Maps)'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_Oijhf1ZPv-4/TIyPQkKE_tI/AAAAAAAABuA/vNNG4DXXqwg/s72-c/mapsnap_osm.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-7857327886134977873</id><published>2010-09-11T16:57:00.001+02:00</published><updated>2010-09-11T17:05:29.664+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='sencha'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>minimalistic JavaScript editing widget</title><content type='html'>&lt;p&gt;In the spirit of clean-up-and-publish, here is another code example of X2: a subclass of &lt;a href="http://doc.qt.nokia.com/4.6/qplaintextedit.html"&gt;QPlainTextEdit&lt;/a&gt; which acts as a nice and minimalistic JavaScript editor. Basically it just adds a sidebar for the line number and a syntax highlighter. Thanks to &lt;a href="http://doc.qt.nokia.com/4.6/qplaintextedit.html"&gt;QPlainTextEdit&lt;/a&gt; and &lt;a href="http://doc.qt.nokia.com/4.6/qsyntaxhighlighter.html"&gt;QSyntaxHighlighter&lt;/a&gt;, this editing widget is quite performant. At just about 500 lines, think about it as another example on how to use these two classes.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/fB0RnabIWG42eNrE4kvdyA?feat=embedwebsite"&gt;&lt;img src="http://lh3.ggpht.com/_Oijhf1ZPv-4/TImgKo_TI4I/AAAAAAAABtc/SdJtm-0kD2M/s800/jsedit-light.png" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It does support specifying different colors so you can have funky color scheme if you want:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/X5d7zVm_F765Q7yRr9QAhA?feat=embedwebsite"&gt;&lt;img src="http://lh6.ggpht.com/_Oijhf1ZPv-4/TImr8xaBK2I/AAAAAAAABtk/81inxQzxF3g/s800/jsedit-dark.png"  border="0"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The widget is BSD licensed. Find it out in the &lt;a href="http://gitorious.org/ofi-labs/X2"&gt;X2 repository&lt;/a&gt; under the &lt;a href="http://gitorious.org/ofi-labs/x2/trees/master/javascript/jsedit"&gt;javascript/jsedit&lt;/a&gt; subdirectory.&lt;/p&gt;

&lt;p&gt;It does not have fancy features such as code folding or autocomplete (not sure I would have time to add them, so patches are welcomed!), but if you want feature packed editor, use &lt;a href="http://www.riverbankcomputing.com/software/qscintilla/"&gt;QScintilla&lt;/a&gt;, &lt;a href="http://kate-editor.org/about/"&gt;KDE's Kate&lt;/a&gt;, &lt;a href="http://doc.qt.nokia.com/qtcreator-2.0/creator-editor-using.html"&gt;Qt Creator's editor&lt;/a&gt;, or grab something else or even write your own.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-7857327886134977873?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/7857327886134977873/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=7857327886134977873' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/7857327886134977873'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/7857327886134977873'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/09/minimalistic-javascript-editing-widget.html' title='minimalistic JavaScript editing widget'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_Oijhf1ZPv-4/TImgKo_TI4I/AAAAAAAABtc/SdJtm-0kD2M/s72-c/jsedit-light.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-8096724309979647684</id><published>2010-09-10T08:30:00.000+02:00</published><updated>2010-09-10T08:31:22.689+02:00</updated><title type='text'>Eid Mubarak</title><content type='html'>&lt;p&gt;Happy Eid Al-Fitr to all!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-8096724309979647684?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/8096724309979647684/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=8096724309979647684' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8096724309979647684'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8096724309979647684'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/09/eid-mubarak.html' title='Eid Mubarak'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-2751001393631801862</id><published>2010-09-09T08:53:00.001+02:00</published><updated>2010-09-09T08:53:30.940+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qtwebkit'/><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><category scheme='http://www.blogger.com/atom/ns#' term='n900'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>the art of blurring the shadow</title><content type='html'>&lt;p&gt;In the recent weeks, sporadically I have been working on QtWebKit to fix the missing blur support for Canvas and CSS shadow (see the tracking &lt;a href="https://bugs.webkit.org/show_bug.cgi?id=34479"&gt;bug 34479&lt;/a&gt;). This brings some good memory; before I &lt;a href="http://ariya.blogspot.com/2009/10/even-qpainter-has-qpainterend.html"&gt;left Nokia&lt;/a&gt;, I was involved in prototyping the &lt;a href="http://www.slideshare.net/qtbynokia/special-effects-with-qt-graphics-view"&gt;special effect&lt;/a&gt; stuff, both for the low-level (non-public) QPixmapFilter and the high-level &lt;a href="http://doc.qt.nokia.com/4.6/qgraphicseffect.html"&gt;QGraphicsEffect&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Usually blurring drop shadow for a shape is a very typical: grab the alpha channel of the shape, apply the blur filter, and finally tint it with the intended shadow color. The last step is trivial using the &lt;a href="http://doc.trolltech.com/qq/qq17-compositionmodes.html#sourceinanddestinationin"&gt;SourceIn composition mode&lt;/a&gt;. The blur filter is supposed to follow the SVG specification on &lt;a href="http://www.w3.org/TR/SVG/filters.html#feGaussianBlur"&gt;feGaussianBlur&lt;/a&gt;. The said specification mentions one possible way to approximate the perfect Gaussian blur: three successive &lt;a href="http://en.wikipedia.org/wiki/Box_blur"&gt;box blurs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since QPixmapFilter is private anyway and QGraphicsEffect is not suitable for this task, an attempt to implement what the specification outlines became my hobby for a few evenings. This is basically what emerges as the shadow blur implementation in QtWebKit. For the sake of code reuse, I pushed the implementation to the &lt;a href="http://gitorious.org/ofi-labs/X2"&gt;X2 repository&lt;/a&gt; under the &lt;a href="http://gitorious.org/ofi-labs/x2/trees/master/graphics/shadowblur"&gt;graphics/shadowblur&lt;/a&gt; subdirectory. The shadowBlur() function itself is BSD licensed, there is a demo program included for your pleasure:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/Csvih9efyp7zDX7mJVKfOQ?feat=embedwebsite"&gt;&lt;img src="http://lh5.ggpht.com/_Oijhf1ZPv-4/TIdRZdhEb1I/AAAAAAAABso/m16m0smbZxg/s800/shadowdemo.png" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Performance-wise, the code is as satisfactory (for such a portable implementation). Another good approach is to use &lt;a href="http://incubator.quasimondo.com/processing/fast_blur_deluxe.php"&gt;stack blur&lt;/a&gt;, adopted among others by &lt;a href="http://en.wikipedia.org/wiki/Anti-Grain_Geometry"&gt;AGG&lt;/a&gt;. KHTML notably uses stack blur for its Canvas shadow blur support. &lt;a href="http://zrusin.blogspot.com/2006/07/more-blurring.html"&gt;Exponential blur&lt;/a&gt; is known to be very fast, although quality-wise it deviates farther from a true Gaussian one. The portable, raster version of &lt;a href="http://doc.qt.nokia.com/4.6/qgraphicsdropshadoweffect.html"&gt;QGraphicsDropShadowEffect&lt;/a&gt; (via QPixmapFilter) is using this algorithm.&lt;/p&gt;

&lt;p&gt;For this particular use-case, namely blurring the shadow (as opposed to generic blur filter), I'm surprised that the Gaussian blur approximation is not necessary slower than KHTML's stack blur approach or even QGraphicsDropShadowEffect's exponential blur. I did a quick benchmark, measuring the time spent creating the shadow for two images (horizontal 149x13 and vertical 13x149) for different radii (small 4px and medium 17px), on a Core i7 machine. The outcome is shown in the following bar chart. The result was from several runs, with the overall confidence level observed to make sure it was statistically sound. Still, take it with a pinch of salt.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/oPoIjGcxin1FA6ReLNCx9g?feat=embedwebsite"&gt;&lt;img src="http://lh5.ggpht.com/_Oijhf1ZPv-4/TIdU_Oxxl_I/AAAAAAAABsw/gvNQDxN0YZk/s800/shadowspeed.png" border="0"/&gt;&lt;/a&gt;

&lt;p&gt;With a very large blur radius, e.g. 50, stack blur performance deteriorates quickly, probably because the pre-loop initial setup. Exponential blur is pretty much radius-agnostic, although I can't find cases where it wins against my shadow blur code (which is BTW only 60 lines). Larger source images would highlight the performance difference even more. Maybe I am doing something wrong, or maybe that's how it is. In any case, I insert a low-priority entry in my (already infinite) TODO list: spend some quality evenings with callgrind and examine those blur implementations.&lt;/p&gt;

&lt;p&gt;On mobile devices however the situation is reversed. The approximated Gaussian blur is consistently slower, around 10%, compared to exponential or stack blur, when tested on 600 MHz Cortex A8-powered &lt;a href="http://en.wikipedia.org/wiki/Nokia_N900"&gt;Nokia N900&lt;/a&gt;. Due to slower memory speed and smaller cache, the repetitive memory access for the successive box blurs cancels its fast processing benefit. Hopefully the 1 GHz generation CPU (like in &lt;a href="http://en.wikipedia.org/wiki/Nokia_N8"&gt;Nokia N8&lt;/a&gt;) and improved memory bus will eliminate this minor slow down.&lt;/p&gt;

&lt;p&gt;Anyway, in all cases, just like &lt;a href="http://labs.trolltech.com/blogs/2010/09/08/state-of-html5-canvas-in-qtwebkit/"&gt;Andreas mentioned&lt;/a&gt;, now you can enjoy &lt;a href="http://www.mrspeaker.net/dev/parcycle/"&gt;the fancy Parcycle demo&lt;/a&gt; in its full glory:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/seUTwzxKSMZ3xUXZSOKIuA?feat=embedwebsite"&gt;&lt;img src="http://lh4.ggpht.com/_Oijhf1ZPv-4/TIh-wfIeLwI/AAAAAAAABtE/0ugYbe4OfPs/s800/qtwebkit-parcycle.png" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-2751001393631801862?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/2751001393631801862/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=2751001393631801862' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2751001393631801862'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2751001393631801862'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/09/art-of-blurring-shadow.html' title='the art of blurring the shadow'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_Oijhf1ZPv-4/TIdRZdhEb1I/AAAAAAAABso/m16m0smbZxg/s72-c/shadowdemo.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-8453072365033085218</id><published>2010-09-08T07:32:00.000+02:00</published><updated>2010-09-08T07:33:28.064+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qtwebkit'/><category scheme='http://www.blogger.com/atom/ns#' term='meego'/><category scheme='http://www.blogger.com/atom/ns#' term='sencha'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><category scheme='http://www.blogger.com/atom/ns#' term='n900'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>Sencha Touch and N900</title><content type='html'>&lt;p&gt;Being &lt;a href="http://ariya.blogspot.com/2010/08/adventure-to-land-of-green-tea.html"&gt;part&lt;/a&gt; of the awesome &lt;a href="http://www.sencha.com/company/team.php"&gt;Sencha Team&lt;/a&gt;, I did shoot a quick attempt to run &lt;a href="http://www.sencha.com/products/touch/"&gt;Sencha Touch&lt;/a&gt;, more precisely its &lt;a href="http://dev.sencha.com/deploy/touch/examples/kitchensink/"&gt;Kitchen Sink demo&lt;/a&gt;, on &lt;a href="http://www.maemo.org"&gt;Maemo&lt;/a&gt;-powered &lt;a href="http://en.wikipedia.org/wiki/Nokia_N900"&gt;Nokia N900&lt;/a&gt;. Since Sencha Touch targets &lt;a href="http://www.webkit.org"&gt;WebKit&lt;/a&gt; but &lt;a href="http://maemo.nokia.com/features/maemo-browser/"&gt;Maemo default browser&lt;/a&gt; is Gecko/Firefox-based, I crafted a mini launcher which wraps Sencha Touch in &lt;a href="http://doc.qt.nokia.com/4.6/qtwebkit.html"&gt;QtWebKit&lt;/a&gt;. The screenshots below serve as the proof:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/Em5XmjhfPIpotor7lfqKQw?feat=embedwebsite"&gt;&lt;img src="http://lh3.ggpht.com/_Oijhf1ZPv-4/TIcXxh7ZuBI/AAAAAAAABsc/YQN4U5epB6M/s800/sencha_touch_n900.png" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most of the stuff works just fine. There are some minor issues and performance problems, but I worry not. With the amazing amount of optimizations Qt+Nokia put in place for Qt 4.7 and QtWebKit 2.x, writing applications for Maemo/MeeGo will be fun (again).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-8453072365033085218?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/8453072365033085218/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=8453072365033085218' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8453072365033085218'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8453072365033085218'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/09/sencha-touch-and-n900.html' title='Sencha Touch and N900'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_Oijhf1ZPv-4/TIcXxh7ZuBI/AAAAAAAABsc/YQN4U5epB6M/s72-c/sencha_touch_n900.png' height='72' width='72'/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-8813722249270894280</id><published>2010-08-18T10:11:00.001+02:00</published><updated>2010-08-18T10:13:47.722+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='chipmunk'/><category scheme='http://www.blogger.com/atom/ns#' term='accelerometer'/><category scheme='http://www.blogger.com/atom/ns#' term='physics'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><category scheme='http://www.blogger.com/atom/ns#' term='n900'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>box of marbles redux</title><content type='html'>&lt;p&gt;If you enjoy &lt;a href="http://ariya.blogspot.com/2010/08/box-of-marbles_10.html"&gt;the box of marbles&lt;/a&gt; demo, now we extend it to include some basic network support. The premise is simple, look at this short video first (or &lt;a href="http://www.youtube.com/watch?v=8yCeIwM0PP4"&gt;watch on YouTube&lt;/a&gt;):&lt;/p&gt;

&lt;p&gt;&lt;object width="500" height="405"&gt;&lt;param name="movie" value="http://www.youtube.com/v/8yCeIwM0PP4?fs=1&amp;amp;hl=en_US&amp;amp;rel=0&amp;amp;color1=0x006699&amp;amp;color2=0x54abd6&amp;amp;border=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/8yCeIwM0PP4?fs=1&amp;amp;hl=en_US&amp;amp;rel=0&amp;amp;color1=0x006699&amp;amp;color2=0x54abd6&amp;amp;border=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="500" height="405"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;

&lt;p&gt;The code to handle the physics of the marbles remains the same, i.e. we just use &lt;a href="http://howlingmoonsoftware.com/chipmunk.php"&gt;Chipmunk physics engine&lt;/a&gt;. However, I added a simple feature to transfer marbles from one place to another. To keep it simple, it is done using &lt;a href="http://tools.ietf.org/html/rfc768"&gt;UDP&lt;/a&gt;. The &lt;a href="http://doc.qt.nokia.com/4.6/qtnetwork.html"&gt;Qt network module&lt;/a&gt; supports UDP quite well, making the datagram code short and readable.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/jRIXPm26rAID7oGRierazQ?feat=embedwebsite"&gt;&lt;img src="http://lh3.ggpht.com/_Vfxwh9hPwVg/TGtZ6XYCB8I/AAAAAAAAACk/6U392QhxGiA/s800/IMG_9723.JPG"  style="border: solid #cccccc 1px; padding: 5px;"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The intended use of this example is easy: run the desktop version and then run the mobile version (tested with &lt;a href="http://en.wikipedia.org/wiki/Nokia_N900"&gt;Nokia N900&lt;/a&gt;). Each instance should find each other and start communicating. Again, we simplify the situation here and handle only 2 (two) peers. To facilitate troubleshooting, the application window title will contain the network address information, if the two peers are fully connected. To avoid complicated setup, discovery is carried out automagically through broadcast. This makes such a demo runs only under the same subnet, which is not a big deal.&lt;/p&gt;

&lt;p&gt;It would have been much more fun doing the transfer between two smartphones (instead of a phone and my laptop). However, I own only one Nokia N900. Hint: I will not refuse your donation of &lt;a href="http://en.wikipedia.org/wiki/Nokia_N8"&gt;Nokia N8&lt;/a&gt; or (preferably) MeeGo-powered &lt;a href="http://www.engadget.com/2010/06/14/nokia-n9-meego-slider-leaks-in-early-video-tease/"&gt; Nokia N9&lt;/a&gt; (i.e. the N900's successor, whatever the real name is).&lt;/p&gt;

&lt;p&gt;If you want to give it a try, head to the usual &lt;a href="http://gitorious.org/ofi-labs/X2"&gt;X2 repository&lt;/a&gt; and look at &lt;a href="http://gitorious.org/ofi-labs/x2/trees/master/demo/marblenet"&gt;demo/marblenet&lt;/a&gt; subdirectory. Again, have the patient to follow the README file before you start compiling it.&lt;/p&gt;

&lt;p&gt;Of course, feel free to extend this example to suit your (more wild) fantasy!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-8813722249270894280?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/8813722249270894280/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=8813722249270894280' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8813722249270894280'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8813722249270894280'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/08/box-of-marbles-redux.html' title='box of marbles redux'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_Vfxwh9hPwVg/TGtZ6XYCB8I/AAAAAAAAACk/6U392QhxGiA/s72-c/IMG_9723.JPG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-1851831317249204453</id><published>2010-08-11T09:16:00.001+02:00</published><updated>2010-08-11T09:18:25.439+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='sencha'/><category scheme='http://www.blogger.com/atom/ns#' term='musing'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>adventure to the land of green tea</title><content type='html'>&lt;p&gt;&lt;img src="http://lh3.ggpht.com/_Oijhf1ZPv-4/TGJKVQA3TXI/AAAAAAAABrM/gkaRF85wbAY/s800/sencha_logo.png" border="0"&gt;&lt;/p&gt;

&lt;p&gt;Now I work for &lt;a href="http://www.sencha.com"&gt;Sencha&lt;/a&gt;, the company behind the leading JavaScript frameworks such as &lt;a href="http://www.sencha.com/products/touch/"&gt;Sencha Touch&lt;/a&gt;, &lt;a href="http://www.sencha.com/products/js/"&gt;Ext JS&lt;/a&gt;, &lt;a href="http://www.sencha.com/products/gwt/"&gt;Ext GWT&lt;/a&gt;, &lt;a href="http://www.sencha.com/products/designer/"&gt;Ext Designer&lt;/a&gt;, &lt;a href="http://jqtouch.com/"&gt;jQTouch&lt;/a&gt;, &lt;a href="http://raphaeljs.com/"&gt;Raphaël&lt;/a&gt;, &lt;a href="http://github.com/extjs/Connect"&gt;Connect&lt;/a&gt;, which empower developers to create, deploy and optimize application using web-standard technologies (HTML5, CSS, JavaScript). Beside, it's &lt;a href="http://techcrunch.com/2010/06/23/sencha-html5-funding-sequoia/"&gt;a hot startup&lt;/a&gt; to work for.&lt;p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-1851831317249204453?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/1851831317249204453/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=1851831317249204453' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1851831317249204453'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1851831317249204453'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/08/adventure-to-land-of-green-tea.html' title='adventure to the land of green tea'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_Oijhf1ZPv-4/TGJKVQA3TXI/AAAAAAAABrM/gkaRF85wbAY/s72-c/sencha_logo.png' height='72' width='72'/><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-4510503989584155411</id><published>2010-08-11T08:13:00.000+02:00</published><updated>2010-08-11T08:14:16.944+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='kde'/><title type='text'>quattro cinque</title><content type='html'>&lt;p&gt;&lt;img src="http://kde.org/announcements/4.5/images/kde45-small.png"&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.kde.org/announcements/4.5/"&gt;It's released!&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-4510503989584155411?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/4510503989584155411/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=4510503989584155411' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/4510503989584155411'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/4510503989584155411'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/08/quattro-cinque.html' title='quattro cinque'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-3433318325386247685</id><published>2010-08-10T08:02:00.001+02:00</published><updated>2010-08-10T08:37:01.339+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='chipmunk'/><category scheme='http://www.blogger.com/atom/ns#' term='accelerometer'/><category scheme='http://www.blogger.com/atom/ns#' term='physics'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><category scheme='http://www.blogger.com/atom/ns#' term='n900'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>box of marbles</title><content type='html'>&lt;p&gt;The next logical step after simple &lt;a href="http://ariya.blogspot.com/2010/08/bouncing-ball-with-accelerometer-on.html"&gt;bouncing ball example&lt;/a&gt; is something which uses a real, full-featured &lt;a href="http://en.wikipedia.org/wiki/Physics_engine"&gt;physics engine&lt;/a&gt;. &lt;a href="http://www.box2d.org/"&gt;Box2D&lt;/a&gt; is usually the popular choice. Combining Box2D with Qt has been done by many people, recently demonstrated before by &lt;a href="http://labs.trolltech.com/blogs/2010/02/26/qt-box2d-is-easy/"&gt;Andreas&lt;/a&gt; and &lt;a href="http://labs.trolltech.com/blogs/2010/06/29/fun-things-you-can-do-with-the-nokia-qt-sdk/"&gt;Thorbjørn&lt;/a&gt;. I decided to pick something else, i.e. &lt;a href="http://howlingmoonsoftware.com/chipmunk.php"&gt;Chipmunk physics engine&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Because this is supposed to an example, I tried to make it as simple as possible (you'd be able to extend it, once you grab the basics). Basically we have a box full of colorful marbles (yes, I loved to &lt;a href="http://en.wikipedia.org/wiki/Marble_(toy)"&gt;play marbles&lt;/a&gt; when I was a kid, there was not any PlayStation back then). A mouse click, or a screen tap, will generated a new marble with a random color. If you run the example on &lt;a href="http://en.wikipedia.org/wiki/Nokia_N900"&gt;Nokia N900&lt;/a&gt;, you can control how the marbles move and hit each other by tilting and shaking the phone.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/zV6hPO6LkqZDm8esZmKJ_Q?feat=embedwebsite"&gt;&lt;img src="http://lh5.ggpht.com/_Oijhf1ZPv-4/TF3EYG6He7I/AAAAAAAABqo/QChSyIHhixo/s800/marblebox.png" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check the code yourself at the usual &lt;a href="http://gitorious.org/ofi-labs/X2"&gt;X2 repository&lt;/a&gt; under the &lt;a href="http://gitorious.org/ofi-labs/x2/trees/master/demo/marblebox"&gt;demo/marblebox&lt;/a&gt; subdirectory. Make sure you open and follow the instructions in the included README file.&lt;/p&gt;

&lt;p&gt;For a sneak peek, just watch this video (or &lt;a href="http://www.youtube.com/watch?v=SOHXo7UrCP8"&gt;enjoy on YouTube&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;
&lt;object width="500" height="405"&gt;&lt;param name="movie" value="http://www.youtube.com/v/SOHXo7UrCP8&amp;amp;hl=en_US&amp;amp;fs=1?rel=0&amp;amp;color1=0x006699&amp;amp;color2=0x54abd6&amp;amp;border=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/SOHXo7UrCP8&amp;amp;hl=en_US&amp;amp;fs=1?rel=0&amp;amp;color1=0x006699&amp;amp;color2=0x54abd6&amp;amp;border=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="500" height="405"&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;/p&gt;

&lt;p&gt;There is still a sequel to this marble box. And still with Chipmunk.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-3433318325386247685?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/3433318325386247685/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=3433318325386247685' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/3433318325386247685'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/3433318325386247685'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/08/box-of-marbles_10.html' title='box of marbles'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_Oijhf1ZPv-4/TF3EYG6He7I/AAAAAAAABqo/QChSyIHhixo/s72-c/marblebox.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-7518228451648506414</id><published>2010-08-10T07:57:00.000+02:00</published><updated>2010-08-10T07:58:55.284+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photo'/><category scheme='http://www.blogger.com/atom/ns#' term='munich'/><category scheme='http://www.blogger.com/atom/ns#' term='funny'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><category scheme='http://www.blogger.com/atom/ns#' term='dessert'/><title type='text'>what is it with this froyo obsession</title><content type='html'>&lt;p&gt;Eclair still rocks :)&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/4753230430/" title="Eclair by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm5.static.flickr.com/4098/4753230430_12b67f3d82.jpg" width="500" height="300" alt="Eclair"  style="border: solid #cccccc 1px; padding: 5px;"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-7518228451648506414?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/7518228451648506414/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=7518228451648506414' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/7518228451648506414'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/7518228451648506414'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/08/what-is-it-with-this-froyo-obsession.html' title='what is it with this froyo obsession'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm5.static.flickr.com/4098/4753230430_12b67f3d82_t.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-6255917551929067629</id><published>2010-08-09T03:14:00.000+02:00</published><updated>2010-08-09T03:15:26.142+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='accelerometer'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><category scheme='http://www.blogger.com/atom/ns#' term='n900'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>bouncing ball with accelerometer on N900</title><content type='html'>&lt;p&gt;First of all, I apologize for my laziness in updating &lt;a href="http://ariya.blogspot.com/2010/03/new-x2-logo.html"&gt;X2&lt;/a&gt; with new code example. I have actually written quite a number of interesting examples, some of which have even been shown back in March, during &lt;a href="http://ariya.blogspot.com/2010/03/manaus-and-bossa-conf.html"&gt;my talk&lt;/a&gt; at Bossa Conference 10, though I did not find the time to clean up and polish them.  Although I'd face new challenges in &lt;a href="http://ariya.blogspot.com/2010/08/even-lost-has-its-season-finale.html"&gt;my upcoming adventure&lt;/a&gt;, I am quite confident I will reach the designated rate of new X2 example fortnightly.&lt;/p&gt;

&lt;p&gt;Now let's focus on the newest example: a minor modification to the previous &lt;a href="http://ariya.blogspot.com/2010/03/n900-and-its-accelerometer.html"&gt;accelerometer code on Nokia N900&lt;/a&gt; [1]. There has been confusion with my statement there: &lt;i&gt;put this function is a separate thread&lt;/i&gt;. This is the alternative to a non-blocking D-Bus code. The main goal of course is not to be able to get faster acceleration values per second, it is only to prevent your code from being blocked by the synchronous D-Bus call.&lt;/p&gt;

&lt;p&gt;Rather than just updating the code with the threaded version, I also added some high-school &lt;a href="http://en.wikipedia.org/wiki/Newton's_laws_of_motion"&gt;Newtonian physics&lt;/a&gt;. Instead of &lt;a href="http://picasaweb.google.com/lh/photo/r1iV9dKiNyNL86bwaYEr0Q?feat=embedwebsite"&gt;boring sliders&lt;/a&gt;, you'll get a ball which moves based on the acceleration [2], i.e. it follows the gravity if you keep your N900 straight.&lt;/p&gt;

&lt;p&gt;Here is the obligatory video. Or &lt;a href="http://www.youtube.com/watch?v=vW_KWfZbLoc"&gt;watch directly&lt;/a&gt; on YouTube.&lt;/p&gt;

&lt;p&gt;&lt;object width="500" height="405"&gt;&lt;param name="movie" value="http://www.youtube.com/v/vW_KWfZbLoc&amp;amp;hl=en_US&amp;amp;fs=1?color1=0x2b405b&amp;amp;color2=0x6b8ab6&amp;amp;border=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/vW_KWfZbLoc&amp;amp;hl=en_US&amp;amp;fs=1?color1=0x2b405b&amp;amp;color2=0x6b8ab6&amp;amp;border=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="500" height="405"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;

&lt;p&gt;The code can be found in the &lt;a href="http://gitorious.org/ofi-labs/X2"&gt;X2 repository&lt;/a&gt; under the &lt;a href="http://gitorious.org/ofi-labs/x2/trees/master/sensor/bouncingball"&gt;sensor/bouncingball&lt;/a&gt; subdirectory.&lt;/p&gt;

&lt;p&gt;In the next installment, we will integrate a third-party real physics engine and make the example more alive!&lt;/p&gt;

&lt;p&gt;[1] Another approach is to use Qt Mobility. However, &lt;a href="http://bugreports.qt.nokia.com/browse/QTMOBILITY-381"&gt;QTMOBILITY-381&lt;/a&gt; (which was spawn from &lt;a href="http://bugreports.qt.nokia.com/browse/QTMOBILITY-326"&gt;QTMOBILITY-326&lt;/a&gt;) has not been solved yet (as of today).
&lt;br&gt;
[2] The overall math is not too scientifically correct, but hey, I always need to leave out something, for your homework :P
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-6255917551929067629?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/6255917551929067629/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=6255917551929067629' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/6255917551929067629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/6255917551929067629'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/08/bouncing-ball-with-accelerometer-on.html' title='bouncing ball with accelerometer on N900'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-2302025792205981293</id><published>2010-08-06T11:06:00.002+02:00</published><updated>2010-08-06T11:11:09.518+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='san diego'/><category scheme='http://www.blogger.com/atom/ns#' term='qualcomm'/><category scheme='http://www.blogger.com/atom/ns#' term='musing'/><title type='text'>even LOST has its season finale</title><content type='html'>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/4864012123/" title="the final countdown by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm5.static.flickr.com/4101/4864012123_de5084fb36.jpg" width="500" height="333" alt="the final countdown" border="0" style="border: solid #cccccc 1px; padding: 5px;"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Today is my last day at Qualcomm.&lt;/p&gt;

&lt;p&gt;It still feels like yesterday when &lt;a href="http://ariya.blogspot.com/2009/12/i-for-innovate.html"&gt;I set foot&lt;/a&gt; in this continent, started some fun &lt;a href="http://ariya.blogspot.com/2010/02/introducing-x2.html"&gt;with X2&lt;/a&gt;, &lt;a href="http://ariya.blogspot.com/2010/03/manaus-and-bossa-conf.html"&gt;enjoyed Brazil&lt;/a&gt;, had this &lt;a href="http://ariya.blogspot.com/2010/04/cupertino.html"&gt;meet-up in Cupertino&lt;/a&gt;, did &lt;a href="http://ariya.blogspot.com/2010/06/spring-to-summer-photo-blog.html"&gt;little exploration&lt;/a&gt; around San Diego, and then &lt;a href="http://ariya.blogspot.com/2010/07/var-adam-new-childariya.html"&gt;got blessed with a cute boy&lt;/a&gt;. &lt;i&gt;Time&lt;/i&gt; really flies. Now it's already &lt;i&gt;time&lt;/i&gt; to move on, again (though this &lt;i&gt;time&lt;/i&gt; without &lt;a href="http://ariya.blogspot.com/2009/10/even-qpainter-has-qpainterend.html"&gt;a geeky resignation&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;I will miss &lt;a href="http://en.wikipedia.org/wiki/Snapdragon_(processor)"&gt;Snapdragon&lt;/a&gt; (the pictured HTC EVO is powered by the said platform). Or any other dragons.&lt;/p&gt;

&lt;p&gt;Those who are annoyed by a certain obsession of mine probably can guess where I'm heading to. In the grand mission of inspiring and pushing developers to write better and more exciting applications, a particular productivity barrier needs to be broken. And I dropped enough (subtle) hints in my previous blog entries already.&lt;/p&gt;

&lt;p&gt;Stay tuned.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-2302025792205981293?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/2302025792205981293/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=2302025792205981293' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2302025792205981293'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2302025792205981293'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/08/even-lost-has-its-season-finale.html' title='even LOST has its season finale'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm5.static.flickr.com/4101/4864012123_de5084fb36_t.jpg' height='72' width='72'/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-1921085330001269845</id><published>2010-08-02T08:04:00.000+02:00</published><updated>2010-08-02T08:05:21.103+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='musing'/><category scheme='http://www.blogger.com/atom/ns#' term='openstreetmap'/><category scheme='http://www.blogger.com/atom/ns#' term='mapquest'/><title type='text'>crowdsourcing for the win</title><content type='html'>&lt;p&gt;&lt;a href="http://blog.mapquest.com/2010/07/09/mapquest-opens-up/"&gt;In some news&lt;/a&gt;, MapQuest embraces &lt;a href="http://www.openstreetmap.org"&gt;OpenStreetMap&lt;/a&gt;, launches the maps site at &lt;a href="http://open.mapquest.co.uk"&gt;open.mapquest.co.uk&lt;/a&gt; using the data from OpenStreetMap, as well as sets aside $1 million funding to improve the maps situation in USA. Let's see if other maps services will follow.&lt;/p&gt;

&lt;a href="http://picasaweb.google.com/lh/photo/G9NYwN5vhzhWVnqi66JADg?feat=embedwebsite"&gt;&lt;img src="http://lh3.ggpht.com/_Oijhf1ZPv-4/TFZcrpvS6II/AAAAAAAABqY/FGnAH9Q2jmQ/s800/osm_mapquest.png" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-1921085330001269845?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/1921085330001269845/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=1921085330001269845' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1921085330001269845'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1921085330001269845'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/08/crowdsourcing-for-win.html' title='crowdsourcing for the win'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_Oijhf1ZPv-4/TFZcrpvS6II/AAAAAAAABqY/FGnAH9Q2jmQ/s72-c/osm_mapquest.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-1347195097499990283</id><published>2010-07-16T06:21:00.001+02:00</published><updated>2010-07-16T19:17:15.566+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='san diego'/><category scheme='http://www.blogger.com/atom/ns#' term='musing'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><title type='text'>var Adam = new Child(Ariya);</title><content type='html'>&lt;p&gt;&amp;gt; Adam.prototype&lt;br/&gt;
Human&lt;br/&gt;
&amp;gt; Adam.timestamp&lt;br/&gt;
1279148700&lt;br/&gt;
&amp;gt; Adam.length&lt;br/&gt;
50.17&lt;br/&gt;
&amp;gt; Adam.weight&lt;br/&gt;
3.4&lt;br/&gt;
&amp;gt; Adam.health&lt;br/&gt;
Checking.... Good&lt;br/&gt;
&amp;gt; Adam.mother.health&lt;br/&gt;
Checking... Good&lt;br/&gt;
&amp;gt; Adam.father.status&lt;br/&gt;
&amp;quot;Happy&amp;quot;
&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-1347195097499990283?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/1347195097499990283/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=1347195097499990283' title='41 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1347195097499990283'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1347195097499990283'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/07/var-adam-new-childariya.html' title='var Adam = new Child(Ariya);'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><thr:total>41</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-7010423563896342624</id><published>2010-07-09T16:47:00.001+02:00</published><updated>2010-07-09T16:49:55.538+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='musing'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='optimization'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>faster quaternion multiplication</title><content type='html'>&lt;p&gt;Sweet memories, it was fun to derive it.&lt;/p&gt;

&lt;p&gt;&lt;i&gt;Faster&lt;/i&gt; here however must be taken with a grain of salt as the new code is not always guaranteed to be better pipelined.&lt;/p&gt;

&lt;p&gt;And of course, it's trivial to beat this generic C code with architecture-specific hand-rolled assembly.&lt;/p&gt;

&lt;pre&gt;
git show cbc22908
commit cbc229081a9df67a577b4bea61ad6aac52d470cb
Author: Ariya Hidayat &lt;ariya.hidayat@nokia.com&gt;
Date:   Tue Jun 30 11:18:03 2009 +0200

    Faster quaternion multiplications.
    
    Use the known factorization trick to speed-up quaternion multiplication.
    Now we need only 9 floating-point multiplications, instead of 16 (but
    at the cost of extra additions and subtractions).
    
    Callgrind shows that the function now takes 299 instructions instead of
    318 instructions, which is not a big win. However I assume the speed-up
    has a better effect for mobile CPU, where multiplications are more
    expensive.
    
    Reviewed-by: Rhys Weatherley

diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h
index 55c871d..9a1b590 100644
--- a/src/gui/math3d/qquaternion.h
+++ b/src/gui/math3d/qquaternion.h
@@ -198,24 +198,17 @@ inline QQuaternion &amp;QQuaternion::operator*=(qreal factor)
 
 inline const QQuaternion operator*(const QQuaternion &amp;q1, const QQuaternion&amp; q2)
 {
-    // Algorithm from:
-    // http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q53
-    float x = q1.wp * q2.xp +
-                    q1.xp * q2.wp +
-                    q1.yp * q2.zp -
-                    q1.zp * q2.yp;
-    float y = q1.wp * q2.yp +
-                    q1.yp * q2.wp +
-                    q1.zp * q2.xp -
-                    q1.xp * q2.zp;
-    float z = q1.wp * q2.zp +
-                    q1.zp * q2.wp +
-                    q1.xp * q2.yp -
-                    q1.yp * q2.xp;
-    float w = q1.wp * q2.wp -
-                    q1.xp * q2.xp -
-                    q1.yp * q2.yp -
-                    q1.zp * q2.zp;
+    float ww = (q1.zp + q1.xp) * (q2.xp + q2.yp);
+    float yy = (q1.wp - q1.yp) * (q2.wp + q2.zp);
+    float zz = (q1.wp + q1.yp) * (q2.wp - q2.zp);
+    float xx = ww + yy + zz;
+    float qq = 0.5 * (xx + (q1.zp - q1.xp) * (q2.xp - q2.yp));
+
+    float w = qq - ww + (q1.zp - q1.yp) * (q2.yp - q2.zp);
+    float x = qq - xx + (q1.xp + q1.wp) * (q2.xp + q2.wp);
+    float y = qq - yy + (q1.wp - q1.xp) * (q2.yp + q2.zp);
+    float z = qq - zz + (q1.zp + q1.yp) * (q2.wp - q2.xp);
+
     return QQuaternion(w, x, y, z, 1);
 }
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-7010423563896342624?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/7010423563896342624/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=7010423563896342624' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/7010423563896342624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/7010423563896342624'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/07/faster-quaternion-multiplication.html' title='faster quaternion multiplication'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-7019040130639817150</id><published>2010-06-21T09:35:00.002+02:00</published><updated>2010-06-21T09:38:12.466+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><title type='text'>proxy server with filtering feature</title><content type='html'>&lt;p&gt;Beside &lt;a href="http://ariya.blogspot.com/2010/06/spring-to-summer-photo-blog.html"&gt;exploring San Diego&lt;/a&gt;, I had done some coding intermittently only. My apology if I do not update &lt;a href="http://ariya.blogspot.com/2010/03/new-x2-logo.html"&gt;X2&lt;/a&gt; with fresh new examples often enough.&lt;/p&gt;

&lt;p&gt;Having said that, here is one network-related example: a minor tweak to the previous example of &lt;a href="http://ariya.blogspot.com/2010/04/simple-http-proxy-server-in-100-lines.html"&gt;Qt-based proxy server&lt;/a&gt;. Basically it adds a minimalistic URL filtering support, in the form of blacklisting certain URLs which start with some predefined strings. The code is available in the usual place, &lt;a href="http://gitorious.org/ofi-labs/X2"&gt;X2 repository&lt;/a&gt;, under the directory &lt;a href="http://gitorious.org/ofi-labs/x2/trees/master/network/filterproxy"&gt;network/filterproxy&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;While major browsers support some variants of content blocking, be it via an extension like AdBlock or as a feature built-in into the browser itself, this new &lt;b&gt;filterproxy&lt;/b&gt; should work with any browser that supports proxy. Alas, I did not bother to implement an AdBlock-compatible rule system because it would complicate the code. Again, consider this is a proof of concept only. A challenging exercise would be to fully support the most known subscription filters.&lt;/p&gt;

&lt;p&gt;It is unheard that content filtering can dramatically improve your browsing experience. Because it cuts the bandwidth usage, it does translate to lower cost for those who are not lucky enough to get unlimited data plan. But most importantly, throwing garbage out of the web pages definitely speeds up the page loading. For this filterproxy example, I did a very unscientific benchmark and test it with Detik.com news site (now you get the answer why the included blacklist.txt contains only some basic advertisement-laden sites). The screenshots below (click to enlarge) show the unfiltered version (left) and the filtered version (right). Notice also the whopping 40% of bandwith saving!&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/5ucXVogSZfk08wVviF33xg?feat=embedwebsite"&gt;&lt;img src="http://lh5.ggpht.com/_Vfxwh9hPwVg/TB6jWBqKdII/AAAAAAAAAB4/1OcL4Ro6Z68/s800/filterproxy.png" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ariya.blogspot.com/2010/04/simple-http-proxy-server-in-100-lines.html"&gt;My promise&lt;/a&gt; was to post two variations from that simple proxy example. This counts as one of them, and when the time allows me to clean-up to the other, you'll know it. Stay tuned and happy proxying!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-7019040130639817150?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/7019040130639817150/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=7019040130639817150' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/7019040130639817150'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/7019040130639817150'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/06/proxy-server-with-filtering-feature.html' title='proxy server with filtering feature'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_Vfxwh9hPwVg/TB6jWBqKdII/AAAAAAAAAB4/1OcL4Ro6Z68/s72-c/filterproxy.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-4444402572612369680</id><published>2010-06-21T07:36:00.000+02:00</published><updated>2010-06-21T07:37:14.270+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='san diego'/><category scheme='http://www.blogger.com/atom/ns#' term='photo'/><category scheme='http://www.blogger.com/atom/ns#' term='sencha'/><category scheme='http://www.blogger.com/atom/ns#' term='musing'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='food'/><title type='text'>spring-to-summer: photo blog</title><content type='html'>&lt;p&gt;Since I've not been blogging for a while, let me do a post on some pictures (plus the stories) instead.&lt;/p&gt;

&lt;p&gt;On a weekend, &lt;a href="http://en.wikipedia.org/wiki/Balboa_Park,_San_Diego,_California"&gt;Balboa Park&lt;/a&gt; is a very nice attraction. Rather than explaining it in details, I suggest to just drop the park a visit. Beside a lot of different types of museum, there is also this &lt;a href="http://www.niwa.org"&gt;Japanese Friendship Garden&lt;/a&gt;. A small cafe there, the Tea Pavillion, is a very nice place to relax and enjoy the surrounding. They serve &lt;b&gt;sencha&lt;/b&gt; and other types of tea. Hungry? Get a rice bowl:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/4719888372/" title="rice bowl by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm5.static.flickr.com/4056/4719888372_fc7ebd8725.jpg" width="500" height="333" alt="rice bowl" style="border: solid #cccccc 1px; padding: 5px;"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are more a beach person instead, then there is a plenty of choices, for example &lt;a href="http://en.wikipedia.org/wiki/Silver_Strand_Beach"&gt;Silver Strand Beach&lt;/a&gt;. It is rather small, but it is always a nice spot to enjoy the sunset.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/4719913322/" title="silhouette @ sunset by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm5.static.flickr.com/4013/4719913322_d42c31e281.jpg" width="500" height="333" alt="silhouette @ sunset" style="border: solid #cccccc 1px; padding: 5px;"/&gt;&lt;/a&gt;

&lt;p&gt;When &lt;a href="http://ariya.blogspot.com/2010/05/google-io-2010.html"&gt;I was at Google IO&lt;/a&gt;, I took some pictures of the large overhang banners because I wanted to test the 8 megapixel camera of &lt;a href="http://en.wikipedia.org/wiki/HTC_Evo_4G"&gt;HTC EVO 4G&lt;/a&gt; that Google gave away (see more in the &lt;a href="http://www.flickr.com/photos/ariyahidayat/sets/72157624321682048/"&gt;complete set&lt;/a&gt;):&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/4719441817/" title="api by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm5.static.flickr.com/4015/4719441817_df292a2c5e.jpg" width="500" height="299" alt="api" style="border: solid #cccccc 1px; padding: 5px;"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Getting a fantastic gift for the Father's day? Thinking of something for the next Mother's Day? What about a beautiful pendant (get one from &lt;a href="http://www.jewelryartdesigns.com/"&gt;LuShae Jewelry&lt;/a&gt;) like what my other better half elegantly captured below?&lt;p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/yolla/4719489249/" title="pendant by Yolla, on Flickr"&gt;&lt;img src="http://farm5.static.flickr.com/4070/4719489249_d465118434.jpg" width="500" height="334" alt="pendant" style="border: solid #cccccc 1px; padding: 5px;"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-4444402572612369680?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/4444402572612369680/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=4444402572612369680' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/4444402572612369680'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/4444402572612369680'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/06/spring-to-summer-photo-blog.html' title='spring-to-summer: photo blog'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm5.static.flickr.com/4056/4719888372_fc7ebd8725_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-3710065911750820799</id><published>2010-05-18T08:54:00.002+02:00</published><updated>2010-05-18T09:03:50.835+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='qualcomm'/><category scheme='http://www.blogger.com/atom/ns#' term='chromium'/><category scheme='http://www.blogger.com/atom/ns#' term='san francisco'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>google io 2010</title><content type='html'>&lt;p&gt;In few hours, I am scheduled to fly to San Francisco, bracing for the impact of &lt;a href="http://code.google.com/events/io/2010/"&gt;Google I/O 2010&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;&lt;img src="http://code.google.com/events/images/io2010logo.png" border="0"&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-3710065911750820799?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/3710065911750820799/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=3710065911750820799' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/3710065911750820799'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/3710065911750820799'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/05/google-io-2010.html' title='google io 2010'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-8943108724762993646</id><published>2010-05-18T08:29:00.002+02:00</published><updated>2010-05-18T08:51:12.522+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='radeon'/><category scheme='http://www.blogger.com/atom/ns#' term='webgl'/><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='fglrx'/><category scheme='http://www.blogger.com/atom/ns#' term='opengl'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Quake and WebGL</title><content type='html'>&lt;p&gt;While I'm there, let me just quickly blog about it. Using the developer version of &lt;a href="http://ariya.blogspot.com/2009/10/chromium-on-opensuse.html"&gt;Chromium on OpenSUSE&lt;/a&gt;, I just run it with the following arguments:&lt;/p&gt;

&lt;pre&gt;/usr/bin/chromium --enable-webgl --in-process-webgl&lt;/pre&gt;

&lt;p&gt;and then I have &lt;a href="http://en.wikipedia.org/wiki/WebGL"&gt;WebGL&lt;/a&gt; at my fingertip. You can test it with some &lt;a href="http://code.google.com/p/o3d/wiki/Samples"&gt;O3D samples&lt;/a&gt; (the pool one is pretty cool).&lt;/p&gt;

&lt;p&gt;In fact, just go ahead and play &lt;a href="http://code.google.com/p/quake2-gwt-port/"&gt;Quake II&lt;/a&gt; at &lt;a href="http://playwebgl.com/games/quake-2-webgl/"&gt;http://playwebgl.com/games/quake-2-webgl/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/cbL4K-KLrO1hemE0NipEPg?feat=embedwebsite"&gt;&lt;img src="http://lh5.ggpht.com/_Oijhf1ZPv-4/S_IxZ8t7zjI/AAAAAAAABnQ/b_2WkXrSZao/s800/webgl-gwtquake.png" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I got bad FPS because I own &lt;a href="http://ariya.blogspot.com/2010/02/new-laptop-free-yourself.html"&gt;a cheap laptop&lt;/a&gt; (8 FPS is more than what I expect from a $330 box). Obviously you can get 25 FPS or more on a much better machine!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-8943108724762993646?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/8943108724762993646/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=8943108724762993646' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8943108724762993646'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8943108724762993646'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/05/quake-and-webgl.html' title='Quake and WebGL'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_Oijhf1ZPv-4/S_IxZ8t7zjI/AAAAAAAABnQ/b_2WkXrSZao/s72-c/webgl-gwtquake.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-5668987091573012144</id><published>2010-05-15T21:10:00.001+02:00</published><updated>2010-05-15T21:12:02.819+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='chromium'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><category scheme='http://www.blogger.com/atom/ns#' term='n900'/><title type='text'>QNetworkAccessManager, tracenet, Speed Tracer</title><content type='html'>&lt;p&gt;Just like &lt;a href="http://www.kdedevelopers.org/node/4210"&gt;Rich's trick&lt;/a&gt; with &lt;a href="http://doc.qt.nokia.com/4.6/qnetworkaccessmanager.html"&gt;QNetworkAccessManager&lt;/a&gt;, I have done something similar which I call &lt;a href="http://gitorious.org/ofi-labs/x2/trees/master/network/tracenet"&gt;tracenet&lt;/a&gt; (around 150 lines of code). Though I have committed this example to X2 some time ago, only now I have the chance to blog about it.&lt;/p&gt;

&lt;p&gt;The idea is to subclass QNetworkAccessManager and reimplement its &lt;a href="http://doc.qt.nokia.com/4.6/qnetworkaccessmanager.html#createRequest"&gt;createRequest&lt;/a&gt; method so that we can keep track all the network responses and replies. This is useful for your network-based application, or even for e.g. QtWebKit. As a matter of fact, the tracenet example captures the network traffic as you load a URL into a web page.&lt;/p&gt;

&lt;p&gt;Now, the next step is how to visualize the result. While it's certainly possible to craft a Qt-based fancy GUI for this (maybe using &lt;a href="http://doc.qt.nokia.com/4.7-snapshot/declarativeui.html"&gt;Qt Quick&lt;/a&gt;?), let's think outside the box. Unless you live in a cave, I am sure you are aware that there is this nice tool called &lt;a href="http://code.google.com/webtoolkit/speedtracer/"&gt;Speed Tracer&lt;/a&gt;, part of GWT, an extension for Google Chrome or Chromium. For this purpose, we won't use the live profiling feature of Speed Tracer, but rather its ability to visualize network requests and replies (with nice timeline and so on). All we have to do is to carefully spit some JSON-formatted data that match the &lt;a href="http://code.google.com/webtoolkit/speedtracer/data-dump-format.html"&gt;Speed Tracer data dump format&lt;/a&gt;. And that is exactly what tracenet does!&lt;/p&gt;

&lt;p&gt;The screenshot below gives an exemplary result from running tracenet on my Nokia N900 when it accesses New York Times front website, a notoriously complicated web page. All I did was to execute &amp;quot;tracenet &amp;gt; nytimes.htm&amp;quot;, transfer back the HTML file to the laptop and then open it with &lt;a href="http://ariya.blogspot.com/2009/10/chromium-on-opensuse.html"&gt;Chromium on OpenSUSE&lt;/a&gt;, click on &amp;quot;Network (resources)&amp;quot; line, and voila! You can click on each entry to get detailed timing info, use zoom in/out, and many other features of Speed Tracer. Refer to some &lt;a href="http://www.google.com/search?q=speed+tracer+tutorial"&gt;tutorials&lt;/a&gt; if you are new to Speed Tracer.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/Z8E_961R6aSHxgTTwfhikQ?feat=embedwebsite"&gt;&lt;img src="http://lh4.ggpht.com/_Oijhf1ZPv-4/S-7enXr0v9I/AAAAAAAABnE/oaJIvZQDlw0/s800/nytimes-speedtracer.png" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want some follow-up and challenging exercise, try to split Speed Tracer code so that the pure GWT-part can run on any browser. Then you can just package it with QtWebKit and use it to show the outcome of all your network sniffing. Have fun!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-5668987091573012144?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/5668987091573012144/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=5668987091573012144' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/5668987091573012144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/5668987091573012144'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/05/qnetworkaccessmanager-tracenet-speed.html' title='QNetworkAccessManager, tracenet, Speed Tracer'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_Oijhf1ZPv-4/S-7enXr0v9I/AAAAAAAABnE/oaJIvZQDlw0/s72-c/nytimes-speedtracer.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-2220089554387430797</id><published>2010-05-09T21:40:00.003+02:00</published><updated>2010-05-09T21:57:04.401+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>vittoria: tiger in color</title><content type='html'>&lt;p&gt;Continuing from &lt;a href="http://ariya.blogspot.com/2010/05/vector-graphics-tiger-in-wireframe.html"&gt;the saga&lt;/a&gt; I started some time ago, at least now I got to the point where it's rendered anti-aliased in full color:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/zdBugG0MugpwSTiHASoYBw?feat=embedwebsite"&gt;&lt;img src="http://lh6.ggpht.com/_Oijhf1ZPv-4/S-cKk1If93I/AAAAAAAABmU/S4mHOAjJ5DE/s800/tiger_vg.png" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Stay tuned, I'd clean-up and release the code soon-ish.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-2220089554387430797?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/2220089554387430797/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=2220089554387430797' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2220089554387430797'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2220089554387430797'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/05/vittoria-tiger-in-color.html' title='vittoria: tiger in color'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_Oijhf1ZPv-4/S-cKk1If93I/AAAAAAAABmU/S4mHOAjJ5DE/s72-c/tiger_vg.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-5208459232700538034</id><published>2010-05-06T17:23:00.004+02:00</published><updated>2010-05-06T17:31:57.635+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>vector graphics, tiger in wireframe</title><content type='html'>&lt;p&gt;At the risk of starting another yet-will-be-unmaintained project, sometime ago I decided to continue learning about graphics stuff in my spare time. I will not announce it of course until its code is better for public consumption. However, I really can't contain my excitement when it reaches an important milestone:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/ldSJwqZ3H0H77dCyDCfZvQ?feat=embedwebsite"&gt;&lt;img src="http://lh5.ggpht.com/_Oijhf1ZPv-4/S-LeyVAB_II/AAAAAAAABmI/MwCDmGMv73A/s800/tiger_wireframe.png" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This sounds like childish, but as a graphics n00b, the above screenshot means a lot to me.&lt;/p&gt;

&lt;p&gt;Stay tuned!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-5208459232700538034?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/5208459232700538034/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=5208459232700538034' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/5208459232700538034'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/5208459232700538034'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/05/vector-graphics-tiger-in-wireframe.html' title='vector graphics, tiger in wireframe'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_Oijhf1ZPv-4/S-LeyVAB_II/AAAAAAAABmI/MwCDmGMv73A/s72-c/tiger_wireframe.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-931974882384822937</id><published>2010-04-10T08:07:00.002+02:00</published><updated>2010-04-10T08:10:16.148+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='cupertino'/><category scheme='http://www.blogger.com/atom/ns#' term='travel'/><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='qualcomm'/><category scheme='http://www.blogger.com/atom/ns#' term='musing'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><title type='text'>cupertino</title><content type='html'>&lt;p&gt;Tomorrow, we (a bunch of &lt;a href="http://ariya.blogspot.com/2009/12/i-for-innovate.html"&gt;Qualcomm folks working on WebKit&lt;/a&gt;) will go up north. We'll be at Apple HQ in Cupertino for the &lt;a href="http://webkit.org/blog/1058/announcing-a-webkit-contributors-meeting/"&gt;WebKit contributors meeting&lt;/a&gt;. I look forward to meeting all the great WebKit hackers (again) face-to-face!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-931974882384822937?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/931974882384822937/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=931974882384822937' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/931974882384822937'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/931974882384822937'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/04/cupertino.html' title='cupertino'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-7889936729158663951</id><published>2010-04-05T00:31:00.002+02:00</published><updated>2010-04-05T01:09:45.690+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><title type='text'>simple http proxy server in 100 lines</title><content type='html'>&lt;p&gt;I guess a simple proxy server should have been an example in &lt;a href="http://doc.qt.nokia.com/qtnetwork.html"&gt;Qt Network module&lt;/a&gt;. What I mean of course a real proxy server based on Qt, not about using a proxy server via &lt;a href="http://doc.qt.nokia.com/qnetworkproxy.html"&gt;QNetworkProxy&lt;/a&gt; class. After all, there are other more complex examples like the &lt;a href="http://doc.qt.nokia.com/network-torrent.html"&gt;torrent client&lt;/a&gt; and &lt;a href="http://doc.qt.nokia.com/network-googlesuggest.html"&gt;Google suggest&lt;/a&gt; (yeah, &lt;a href="http://ariya.blogspot.com/2009/03/i-was-blindfolded-but-now-im-seeing.html"&gt;blame me&lt;/a&gt; for the latter). As a matter of fact, there are e.g. a gazillion &lt;a href="http://proxies.xhaus.com/python/"&gt;proxy servers written in Python&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Look no more. I posted an example in the &lt;a href="http://gitorious.org/ofi-labs/X2"&gt;X2 repository&lt;/a&gt;, under the directory &lt;a href="http://gitorious.org/ofi-labs/x2/trees/master/network/webproxy"&gt;network/webproxy&lt;/a&gt;. The code is written for clarity and not for performance. In fact, fancy error handling is even omitted (minimalism rulez!). There is no support for pipelining, or in-memory cache, or per-connection thread, or even secure connection via https. I leave them as exercises for the curious readers.&lt;/p&gt;

&lt;p&gt;If we focus on things which work, here they are: &lt;a href="http://qt.nokia.com/doc/4.6/network-programming.html#using-tcp-with-qtcpsocket-and-qtcpserver"&gt;asynchronous socket handling&lt;/a&gt;, different &lt;a href="http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods"&gt;request methods&lt;/a&gt; (GET/PUT/POST/HEAD), &lt;a href="http://en.wikipedia.org/wiki/HTTP_persistent_connection"&gt;persistent connection&lt;/a&gt; aka keep alive, and even Flash and HTML 5 video streaming. Yes, you can still watch YouTube or Vimeo if you hook your browser into this little proxy. For a few hours of hacking and 92 lines of code (as reported by &lt;a href="http://www.dwheeler.com/sloccount/"&gt;sloccount&lt;/a&gt;) and certain ways to abuse QObject, I could not be more happier.&lt;/p&gt;

&lt;p&gt;There will be two other offspring examples based on this one. So stay tuned. Meanwhile let's just hope nobody would &lt;a href="http://ariya.blogspot.com/2009/08/mails-i-wish-i-could-skip.html"&gt;ask me&lt;/a&gt; for a colorful UML diagram for this snippet...&lt;/p&gt;

&lt;p&gt;PS: Special thanks to Jan Erik for his feedback and review.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-7889936729158663951?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/7889936729158663951/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=7889936729158663951' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/7889936729158663951'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/7889936729158663951'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/04/simple-http-proxy-server-in-100-lines.html' title='simple http proxy server in 100 lines'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-3907411024270086144</id><published>2010-03-26T01:37:00.001+01:00</published><updated>2010-03-26T01:39:49.005+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='puzzle'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='funny'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>multiples of 3 or 5</title><content type='html'>&lt;p&gt;One day Helder showed me &lt;a href="http://projecteuler.net/"&gt;Project Euler&lt;/a&gt;, a collection of interesting math problems to be solved using computer programs.&lt;/p&gt;

&lt;p&gt;I took a look at the &lt;a href="http://projecteuler.net/index.php?section=problems&amp;amp;id=1"&gt;first problem&lt;/a&gt;: find the sum of all the multiples of 3 or 5 below 1000. Getting the linear time solution was trivial, the constant time solution was also not hard. However, I could not help it, I continued by applying some obfuscation voodoo and came up with this answer (of course, constant time as well):&lt;/p&gt;

&lt;pre&gt;
return "uncopyrightable"[n % 15] - 'a' + 44 - "xzoxy}pge]_LAKD"[n% 15] +
'A' - (!(n % 15)) * 9 + 15 * ((n / 15) * (4 + ("aaabbcdddeffggg"[n % 15] - 'a')) +
(n / 15) * (n / 15 - 1) * 7 / 2);
&lt;/pre&gt;

&lt;p&gt;How did a word ("uncopyrightable") end up in that solution? Believe me, it was (a lot of) fun! :)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-3907411024270086144?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/3907411024270086144/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=3907411024270086144' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/3907411024270086144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/3907411024270086144'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/03/multiples-of-3-or-5.html' title='multiples of 3 or 5'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-8098841193669706147</id><published>2010-03-20T14:45:00.002+01:00</published><updated>2010-03-20T15:16:21.063+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='bossaconf'/><category scheme='http://www.blogger.com/atom/ns#' term='kde'/><category scheme='http://www.blogger.com/atom/ns#' term='effect'/><category scheme='http://www.blogger.com/atom/ns#' term='s60'/><category scheme='http://www.blogger.com/atom/ns#' term='plasma'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><category scheme='http://www.blogger.com/atom/ns#' term='n900'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>morphing clock</title><content type='html'>&lt;p&gt;As I promised before, here is a fresh X2 example. Those who attended Bossa Conference 10 and &lt;a href="http://ariya.blogspot.com/2010/03/manaus-and-bossa-conf.html"&gt;followed my talk&lt;/a&gt; are lucky to have seen it for the first time there. In fact, this example is ridiculously simple that I am not surprised at all if somebody has done this ages ago.&lt;/p&gt;

&lt;p&gt;Let's start with a screen capture, or two:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/yMT2wHqXF-kxQazJ_Wvp6w?feat=embedwebsite"&gt;&lt;img src="http://lh4.ggpht.com/_Oijhf1ZPv-4/S6TKGEr3B-I/AAAAAAAABjI/FluKjrbmFzo/s800/morphingclock_maemo5.png" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Basically the above shows an analog and digital clock running on my Nokia N900, hardly a shock. However, the fun part is when you switch the clock from analog to digital and vice versa. Check out this video, or &lt;a href="http://www.youtube.com/watch?v=mo8PZb_iPAI"&gt;watch directly on YouTube&lt;/a&gt;, courtesy of &lt;a href="http://labs.qt.nokia.com/blogs/author/aportale/"&gt;Signor Portale&lt;/a&gt; from Nokia/Qt, showing the morphing on Nokia 5800:&lt;/p&gt;

&lt;p&gt;&lt;object width="480" height="385"&gt;
&lt;param name="movie" value="http://www.youtube.com/v/mo8PZb_iPAI&amp;hl=en_GB&amp;fs=1&amp;"&gt;&lt;/param&gt;
&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;
&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;
&lt;embed src="http://www.youtube.com/v/mo8PZb_iPAI&amp;hl=en_GB&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"&gt;&lt;/embed&gt;
&lt;/object&gt;&lt;/p&gt;

&lt;p&gt;The trick is simple. Actually it's not even generic enough, meaning that you can't morph from an arbitrary path to another arbitrary path. However, for this clock use-case, the gross approximation is good enough. First, we need to convert the path into a polygon, which is done easily via &lt;a href="http://doc.qt.nokia.com/qpainterpath.html"&gt;QPainterPath::toFillPolygon()&lt;/a&gt; function. Then any line segment in the polygon longer than a certain tolerance is further split into smaller segments. As I claimed above, the result is not perfect, i.e. it does not approximate the original path into line segments with equal length. But hey, it is good enough for this animation purpose (unless your user has ueberhuman eyes).&lt;/p&gt;

&lt;p&gt;The target path needs to be sliced into segments as well. Since we have only two types, circle (for the analog clock frame) and solid block (for the hour and minute hands), it is easier to special-case both. The secret is to have the same number of segments as the source path. The following figure shows the digit '7' and a circle, each splitted to 28 line segments. Small dots indicate the start and end points of those segments. The animation is now a matter of doing tweening, or linear interpolation, between each segment.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/j3bKPy7xdMYNTTtYCODeBw?feat=embedwebsite"&gt;&lt;img src="http://lh4.ggpht.com/_Oijhf1ZPv-4/S6TKGCLf9BI/AAAAAAAABjE/NXwLZ42J7Gk/s800/digitmorph.png" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The flaw of this trick is when the source path contains holes inside it, e.g. for digits like 0, 4, 6, 8, and 9. Again, we are cheating here for the sake of keeping the code simple, so I leave the code as it is. Doing a more advanced, better handling for those cases is left as a motivational exercise for the perfectionist readers. Another bonus puzzle: find out why 503 ms is the morphing time (hint: find the same number in Qt source tree).&lt;/p&gt;

&lt;p&gt;The code is in the &lt;a href="http://gitorious.org/ofi-labs/X2"&gt;X2 repository&lt;/a&gt;, check the sub-directory &lt;a href="http://gitorious.org/ofi-labs/x2/trees/master/widget/morphingclock"&gt;widget/morphingclock&lt;/a&gt;. You need Qt 4.5 or later. It is not long at all (surprise!), &lt;a href="http://www.dwheeler.com/sloccount/"&gt;sloccount&lt;/a&gt; reports 191 lines of code. &lt;a href="http://websvn.kde.org/trunk/playground/base/plasma/applets/morphingclock"&gt;A morphing-clock plasmoid&lt;/a&gt; is also underway, just be patient.&lt;/p&gt;

&lt;p&gt;For the sake of completeness, let me mentioned &lt;a href="http://www.jwz.org/xdaliclock/"&gt;Dali Clock&lt;/a&gt; (even in &lt;a href="http://www.jwz.org/xdaliclock/javascript/"&gt;Canvas and JavaScript version&lt;/a&gt;) from the famous Jamie Zawinski (jwz). It is similar, however Dali Clock just morphs the digits of the digital clock.&lt;/p&gt;

&lt;p&gt;Also, if you just prefer a normal (but old-fashioned!) digital clock with the flipping effect, check the &lt;a href="http://labs.qt.nokia.com/blogs/2009/07/15/digital-clock-in-a-phone/"&gt;digiflip example&lt;/a&gt; I did back then. You already have it if you install &lt;a href="http://www.youtube.com/watch?v=uhr44p2p_3M"&gt;Qt 4.6 for Symbian&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Last but not least, I'd like to mention my &amp;quot;special thanks to Delta Airlines for such a long (but safe) flight to Brazil so I had the chance to write this example while I was bored&amp;quot;, but then I was told by the Trolls that &lt;a href="http://gnome.mirocommunity.org/video/276/ariya-hidayat-special-fx-with-"&gt;this kind of intro line&lt;/a&gt; can't be funny anymore.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-8098841193669706147?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/8098841193669706147/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=8098841193669706147' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8098841193669706147'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8098841193669706147'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/03/morphing-clock.html' title='morphing clock'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_Oijhf1ZPv-4/S6TKGEr3B-I/AAAAAAAABjI/FluKjrbmFzo/s72-c/morphingclock_maemo5.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-2576717324674143582</id><published>2010-03-11T17:36:00.001+01:00</published><updated>2010-03-11T19:51:44.708+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='musing'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>new X2 logo</title><content type='html'>&lt;p&gt;I got few proposed designs after I announced &lt;a href="http://ariya.blogspot.com/2010/02/introducing-x2.html"&gt;X2 project&lt;/a&gt; back then. It is tough to pick the winner cause they are all very good. In the end, the one from Elvis Stansvik becomes the new official logo of X2:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/JaQ4JRaIIe1nC-tSp3s1-w?feat=embedwebsite"&gt;&lt;img src="http://lh6.ggpht.com/_Oijhf1ZPv-4/S5kAq13tZAI/AAAAAAAABiU/YvRNu2rIjFY/s800/x2-logo.png" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thank you to everyone who has sent me the logo design!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-2576717324674143582?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/2576717324674143582/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=2576717324674143582' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2576717324674143582'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2576717324674143582'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/03/new-x2-logo.html' title='new X2 logo'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_Oijhf1ZPv-4/S5kAq13tZAI/AAAAAAAABiU/YvRNu2rIjFY/s72-c/x2-logo.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-2848554419931418165</id><published>2010-03-08T19:45:00.004+01:00</published><updated>2010-03-09T07:14:41.426+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='travel'/><category scheme='http://www.blogger.com/atom/ns#' term='hacks'/><category scheme='http://www.blogger.com/atom/ns#' term='vacation'/><category scheme='http://www.blogger.com/atom/ns#' term='brazil'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='bossaconf'/><category scheme='http://www.blogger.com/atom/ns#' term='manaus'/><category scheme='http://www.blogger.com/atom/ns#' term='effect'/><category scheme='http://www.blogger.com/atom/ns#' term='n900'/><title type='text'>manaus and bossa conf</title><content type='html'>&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Oijhf1ZPv-4/S5VGZcwKegI/AAAAAAAABhc/wul0xPyMpE8/s1600-h/bossaconf.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 361px; height: 292px;" src="http://3.bp.blogspot.com/_Oijhf1ZPv-4/S5VGZcwKegI/AAAAAAAABhc/wul0xPyMpE8/s400/bossaconf.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5446336727403362818" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Right now I am in &lt;a href="http://wikitravel.org/en/Manaus"&gt;Manaus&lt;/a&gt;, in the middle of the Amazon, Brazil. Good weather, beautiful nature. Fresh tropical rain, feels just like home. &lt;/p&gt;

&lt;p&gt;Yes, I am here for the (legendary) &lt;a href="http://bossaconference.indt.org/"&gt;Bossa Conference '10&lt;/a&gt; from the awesome INdT folks. I had delivered my talk, &lt;a href="http://bossaconference.indt.org/programme"&gt;&lt;b&gt;Redefining Mobile Graphics Stack&lt;/b&gt;&lt;/a&gt; this morning. I used the chance to preview (and got feedback) some of upcoming graphics example for X2 from Ofi Labs (what's X2? &lt;a href="http://ariya.blogspot.com/2010/02/introducing-x2.html"&gt;read the explanation&lt;/a&gt;), even straight from my N900, so just watch its &lt;a href="http://gitorious.org/ofi-labs/X2"&gt;git repository&lt;/a&gt; in the next few weeks. BTW, Radeon HD 3200 of &lt;a href="http://ariya.blogspot.com/2010/02/new-laptop-free-yourself.html"&gt;my new toy&lt;/a&gt; and TV output of N900 worked out-the-box with the projector.&lt;/p&gt;

&lt;p&gt;It is also nice to meet few INdT guys I knew, and get to know new folks as well. Since a few Trolls are also here, I also catch up (and share more jokes) with them. Gosh, feels like ages since &lt;a href="http://ariya.blogspot.com/2009/12/i-for-innovate.html"&gt;I left Oslo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is my first visit to Brazil. Looks like it won't be the last time!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-2848554419931418165?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/2848554419931418165/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=2848554419931418165' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2848554419931418165'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2848554419931418165'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/03/manaus-and-bossa-conf.html' title='manaus and bossa conf'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_Oijhf1ZPv-4/S5VGZcwKegI/AAAAAAAABhc/wul0xPyMpE8/s72-c/bossaconf.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-2051076490176033661</id><published>2010-03-05T06:24:00.003+01:00</published><updated>2010-03-05T06:38:19.198+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='accelerometer'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><category scheme='http://www.blogger.com/atom/ns#' term='n900'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>n900 and its accelerometer</title><content type='html'>&lt;p&gt;There is a bunch of code out there (which can be copied and pasted) to grab the &lt;a href="http://wiki.maemo.org/Accelerometers"&gt;acceleration values&lt;/a&gt; from Nokia N900. Here I contribute one more, it's Qt-based and using the &lt;a href="http://qt.nokia.com/doc/qtdbus.html"&gt;QtDBus module&lt;/a&gt;. The values in x, y, z will have the unit of G.&lt;/p&gt;

&lt;pre&gt;
    QDBusConnection connection(QDBusConnection::systemBus());
    QDBusInterface interface("com.nokia.mce", "/com/nokia/icd", QString(), connection);
    QDBusPendingReply&amp;lt;QString, QString, QString, int, int, int&amp;gt; reply;
    reply = interface.asyncCall("get_device_orientation");
    reply.waitForFinished();
    x = static_cast&amp;lt;qreal&amp;gt;(reply.argumentAt&amp;lt;3&amp;gt;()) / 1000;
    y = static_cast&amp;lt;qreal&amp;gt;(reply.argumentAt&amp;lt;4&amp;gt;()) / 1000;
    z = static_cast&amp;lt;qreal&amp;gt;(reply.argumentAt&amp;lt;5&amp;gt;()) / 1000;
&lt;/pre&gt;

&lt;p&gt;As usual, error checking is omitted (left as an exercise for the reader). Like Star Wars, there is also a reason I skip the first 3 QStrings. Debug it yourself to see what you would get. In addition, I found out that at most it would take 25 ms to grab all three values. It means, if you run your application at &gt; 40 fps, then better put this function is a separate thread. Actually, consider that you don't want QDBusPendingReply::waitForFinished() to block your entire GUI, this is likely a good idea anyway.&lt;p&gt;

&lt;p&gt;For a full-version of an accelerometer tool, check out the &lt;a href="http://gitorious.org/ofi-labs/X2"&gt;X2 repository&lt;/a&gt; under the sub-directory &lt;a href="http://gitorious.org/ofi-labs/x2/trees/master/sensor/accelview"&gt;sensor/accelview&lt;/a&gt;. Note that technically acceleration &gt; 1 G is always possible, I clamp the values in this example to keep the UI simple.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/r1iV9dKiNyNL86bwaYEr0Q?feat=embedwebsite"&gt;&lt;img src="http://lh4.ggpht.com/_Oijhf1ZPv-4/S5CPGfaqklI/AAAAAAAABhQ/yAkVn7MLSqk/s800/accelview.jpg" /&gt;&lt;/a&gt;&lt;p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-2051076490176033661?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/2051076490176033661/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=2051076490176033661' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2051076490176033661'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2051076490176033661'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/03/n900-and-its-accelerometer.html' title='n900 and its accelerometer'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_Oijhf1ZPv-4/S5CPGfaqklI/AAAAAAAABhQ/yAkVn7MLSqk/s72-c/accelview.jpg' height='72' width='72'/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-7910630945732654984</id><published>2010-02-28T02:08:00.001+01:00</published><updated>2010-02-28T02:10:02.517+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='colors'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>(q)palette viewer</title><content type='html'>&lt;p&gt;Qt documentation mentions &lt;a href="http://doc.qt.nokia.com/qpalette.html"&gt;QPalette&lt;/a&gt; as the class that contains color groups, Active, Inactive, and Disabled, for each widget state. Knowing the color for many different &lt;a href="http://doc.qt.nokia.com/qpalette.html#ColorRole-enum"&gt;color roles&lt;/a&gt; is important. For example, a style author might want to tweak the colors of each buttons depending on QPalette::Button, QPalette::ButtonText, QPalette::Highlight and likely play with the shades and the saturation. There are probably few different ways to get the RGB values of those colores, here I show one of them: using a small tool that display all the color roles for active, inactive and disabled states:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/hhb3b7qJk2SOH-pJ6iapNw?feat=embedwebsite"&gt;&lt;img src="http://lh3.ggpht.com/_Oijhf1ZPv-4/S4k90l8TVoI/AAAAAAAABgo/wq-IwZCjRGc/s800/palview_x11.png" /&gt;&lt;/a&gt;&lt;p&gt;

&lt;p&gt;And here how it looks like on Nokia N900:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/DliusnfelO7yqXGALUuW3w?feat=embedwebsite"&gt;&lt;img src="http://lh6.ggpht.com/_Oijhf1ZPv-4/S4k91KvEJ1I/AAAAAAAABgs/aTUChc8GNls/s400/palview_maemo5.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code is in the &lt;a href="http://gitorious.org/ofi-labs/X2"&gt;X2 repository&lt;/a&gt;, check the sub-directory &lt;a href="http://gitorious.org/ofi-labs/x2/trees/master/widget/palview"&gt;widget/palview&lt;/a&gt;. A possible exercise for the brave reader: allow the user to choose &lt;a href="http://doc.qt.nokia.com/qcolor.html#Spec-enum"&gt;other color spaces&lt;/a&gt; such as HSL or HSV.&lt;/p&gt;

&lt;p&gt;Have fun with the colors!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-7910630945732654984?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/7910630945732654984/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=7910630945732654984' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/7910630945732654984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/7910630945732654984'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/02/qpalette-viewer.html' title='(q)palette viewer'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_Oijhf1ZPv-4/S4k90l8TVoI/AAAAAAAABgo/wq-IwZCjRGc/s72-c/palview_x11.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-5739375299593578916</id><published>2010-02-23T18:35:00.000+01:00</published><updated>2010-02-23T18:36:16.785+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>web browser and touch device: problem with links</title><content type='html'>&lt;p&gt;Time for X2 premier, like &lt;a href="http://ariya.blogspot.com/2010/02/introducing-x2.html"&gt;I promised before&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Like what every interface designer would tell you, &lt;a href="http://www.useit.com/alertbox/mobile-usability.html"&gt;you can't just reuse&lt;/a&gt; desktop user interface to your mobile version of the application and pray that the application will be useable. Here is an example. In a web browser designed for a mobile device armed with &lt;a href="http://en.wikipedia.org/wiki/Touchscreen"&gt;a touchscreen&lt;/a&gt;, the typical mapping the touch coordinate to the usual mouse event presents a problem because seems every screen has its own &lt;a href="http://en.wikipedia.org/wiki/Accuracy_and_precision"&gt;accuracy and precision problem&lt;/a&gt;. Sometimes it's hard trying to visit a link, merely because it is not possible to hit the link properly with your finger.&lt;/p&gt;

&lt;p&gt;The solution seems to be quite (ridiculously) easy. Instead of trying to find what is exactly under your finger (point of contact with the screen), let's also probe the area in the nearby. If there is a link very close to it, then assume the user wants to go there, she just misses the link accidently by a few pixels. If there are multiple links, then pick the nearest one.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/n4Mw6hr3etkd5KN665Yhnw?feat=embedwebsite"&gt;&lt;img src="http://lh3.ggpht.com/_Oijhf1ZPv-4/S4QCQoZwCNI/AAAAAAAABf8/Zatn1UyNlBQ/s800/probelink.png" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have written a very short example, using Qt 4.6 (or later), based on QtWebKit, to demonstrate this workaround. Check the code in the &lt;a href="http://gitorious.org/ofi-labs/X2"&gt;X2 repository&lt;/a&gt; under the directory &lt;a href="http://gitorious.org/ofi-labs/x2/trees/master/webkit/probelink"&gt;webkit/probelink&lt;/a&gt;. It might not work on web pages with multiple frames, but at least you got the basic idea. The chosen link is even highlighted before the browser loads it, just like in the screenshot above.&lt;/p&gt;

&lt;p&gt;Next week, or the week after, let's see another simple example which implements something like &lt;a href="http://labs.opera.com/news/2009/03/05/"&gt;Opera Fingertouch&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-5739375299593578916?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/5739375299593578916/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=5739375299593578916' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/5739375299593578916'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/5739375299593578916'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/02/web-browser-and-touch-device-problem.html' title='web browser and touch device: problem with links'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_Oijhf1ZPv-4/S4QCQoZwCNI/AAAAAAAABf8/Zatn1UyNlBQ/s72-c/probelink.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-7117011174957996431</id><published>2010-02-21T15:18:00.002+01:00</published><updated>2010-02-21T15:22:44.820+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='x2'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='musing'/><category scheme='http://www.blogger.com/atom/ns#' term='ofilabs'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>introducing X2</title><content type='html'>&lt;p&gt;I know the number of &lt;a href="http://qt.nokia.com/developer/learning/certification"&gt;Qt experts&lt;/a&gt; out there is &lt;a href="http://labs.trolltech.com/blogs/2010/02/10/areas-of-qt-you-want-to-learn-most-what-can-we-do-for-you/"&gt;growing&lt;/a&gt; (like crazy). Still, I believe we should do more to help people master this great framework. I am aware that I might bore you with few Qt code examples I did &lt;a href="http://ariya.blogspot.com/2009/10/graphics-dojo-in-2009-wrap-up.html"&gt;last year&lt;/a&gt; or even &lt;a href="http://ariya.blogspot.com/2008/12/graphics-dojo-in-2008-wrap-up.html"&gt;the year before&lt;/a&gt;, but somehow I feel that I won't do no harm if I keep sharing new stuff I learn every now and then (especially since now &lt;a href="http://ariya.blogspot.com/2010/02/new-laptop-free-yourself.html"&gt;I got a new toy&lt;/a&gt;). And maybe it's not too bad if I change this blog tagline to &amp;quot;don't code today what you can't &lt;i&gt;share&lt;/i&gt; tomorrow&amp;quot; :)&lt;/p&gt;

&lt;p&gt;Since &lt;a href="http://ariya.blogspot.com/2009/12/i-for-innovate.html"&gt;I am not with Nokia/Qt anymore&lt;/a&gt;, I also left &lt;a href="http://ariya.blogspot.com/2008/06/return-of-graphics-dojo-opengl.html"&gt;the Graphics Dojo corner&lt;/a&gt; behind. I decide to publish my new and upcoming Qt examples under a new moniker: X2 from Ofi Labs. The two Xs there stand technically for eXperiments and eXamples, though X2 only sounds cool (even if that X-Men movie would not exist) and I prefer it that way. The name &amp;quot;Ofi Labs&amp;quot; will require a longer explanation, which I rather not elaborate right now.&lt;/p&gt;

&lt;p&gt;The git repository for X2 is at &lt;a href="http://gitorious.org/ofi-labs/X2"&gt;gitorious.org/ofi-labs/X2&lt;/a&gt;. In the next few days, watch this space for the first few examples.&lt;/p&gt;

&lt;p&gt;Meanwhile, enjoy the logo. If you are an artist, feel free to propose a new and better logo!&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/BoaRQEDged_1ffP0ayTMXw?feat=embedwebsite"&gt;&lt;img src="http://lh3.ggpht.com/_Oijhf1ZPv-4/S4AcLEP2dTI/AAAAAAAABfQ/dVpJ1nRnuVc/s800/x2-logo.png" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-7117011174957996431?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/7117011174957996431/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=7117011174957996431' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/7117011174957996431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/7117011174957996431'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/02/introducing-x2.html' title='introducing X2'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_Oijhf1ZPv-4/S4AcLEP2dTI/AAAAAAAABfQ/dVpJ1nRnuVc/s72-c/x2-logo.png' height='72' width='72'/><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-8300088673771392717</id><published>2010-02-20T21:09:00.001+01:00</published><updated>2010-02-20T21:10:25.214+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='opensuse'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='virtualization'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>distcc, VirtualBox, NAT</title><content type='html'>&lt;p&gt;The following scenario is quite typical. Your family member, spouse, or coworker has this fantastic, powerful, brand-new multicore machine which, for some reasons, has to run Windows or Mac OS X. On the other hand, you probably have &lt;a href="http://ariya.blogspot.com/2010/02/new-laptop-free-yourself.html"&gt;some el-cheapo laptop&lt;/a&gt; which is also wonderful but it lacks the processing power to do heavy-duty build and compile. Now, what if you can exploit the other box for a distributed compile? Especially if the powerful box seems to be idle once a while, doing nothing.&lt;/p&gt;

&lt;p&gt;Many of you already figure it out the solution: let's install Linux on a virtual machine and use tools like &lt;a href="http://distcc.googlecode.com/"&gt;distcc&lt;/a&gt; or &lt;a href="http://en.opensuse.org/Icecream"&gt;icecream&lt;/a&gt;. In fact, this is quite easy to do. I managed to find out the details, even if I have only little idea about network stuff.&lt;/p&gt;

&lt;p&gt;&lt;i&gt;Side note&lt;/i&gt;: I don't see why icecream would not work. But since I did try distcc, that's what I wrote below.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/42Sqj_rh1ErX_OOk5mgCYA?feat=embedwebsite"&gt;&lt;img src="http://lh5.ggpht.com/_Oijhf1ZPv-4/S4A1OV4To4I/AAAAAAAABfY/VCZtNUh-mX0/s800/distcc-vbox.png" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the following explanation, refer to the above exemplary network setup. Basically I run virtualized &lt;a href="http://en.opensuse.org"&gt;openSUSE&lt;/a&gt; inside &lt;a href="http://www.virtualbox.org/"&gt;VirtualBox&lt;/a&gt;. You don't even need a full-blown graphical system, you can create a customized openSUSE installation (no X11 but with some development tools like make, gcc, g++, etc) using &lt;a href="http://susestudio.com/"&gt;SUSE Studio&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;First of all, we need to configure VirtualBox to do &lt;a href="http://www.virtualbox.org/manual/ch06.html#natforward"&gt;port forwarding&lt;/a&gt;. If you read the manual, you see that &lt;a href="http://www.virtualbox.org/manual/ch06.html#network_nat"&gt;the default networking is NAT&lt;/a&gt;, which is what we use, along with extra forwarded ports. To do this, run the following on the command prompt (in your installation folder, e.g. C:\Program Files\Sun\VirtualBox for Windows, tweak for Mac OS X), changing &lt;i&gt;openSUSE&lt;/i&gt; with the name of your virtual machine:&lt;/p&gt;

&lt;pre&gt;
VBoxManage.exe setextradata "openSUSE" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/distcc/HostPort" 3632
VBoxManage.exe setextradata "openSUSE" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/distcc/GuestPort" 3632
VBoxManage.exe setextradata "openSUSE" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/distcc/Protocol" TCP
VBoxManage.exe setextradata "openSUSE" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/ssh/HostPort" 2222
VBoxManage.exe setextradata "openSUSE" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/ssh/GuestPort" 22
VBoxManage.exe setextradata "openSUSE" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/ssh/Protocol" TCP
&lt;/pre&gt;

&lt;p&gt;The last 3 lines are not important for distcc itself, however it's quite handy since you will be able to ssh to the machine (on the port 2222, i.e. the forwarded one and not port 22) and start or stop distcc remotely.&lt;/p&gt;

&lt;p&gt;&lt;i&gt;Side note&lt;/i&gt;: I was told that bridged networking mode should work as well (even without the hassle of port forwarding). However, I did not manage to make it working in my setup.&lt;/p&gt;

&lt;p&gt;In addition, tweak the settings of your virtual machine so you get more than one CPU cores. For example, on a quad-core machine, giving the virtualized openSUSE two or three cores might be better, considered if the host system does not run need all that burning power.&lt;/p&gt;

&lt;p&gt;Next step is to install distcc both on the virtualized openSUSE (&lt;i&gt;anjali&lt;/i&gt;) and your laptop (&lt;i&gt;latika&lt;/i&gt;). The easiest way is to use the one click install feature, just go to &lt;a href="http://software.opensuse.org"&gt;software.opensuse.org&lt;/a&gt;, click on Package Search, type in distcc and press Enter and then install both distcc and distcc-server. To do it manually, add http://download.opensuse.org/repositories/home:/dbahi/openSUSE_11.2/ to your repositories and install using:&lt;/p&gt;

&lt;pre&gt;sudo zypper in distcc distcc-server&lt;/pre&gt;

&lt;p&gt;After that, on &lt;i&gt;anjali&lt;/i&gt;, run the following (as normal user, no need to sudo/root):&lt;/p&gt;
&lt;pre&gt;/usr/sbin/distccd --daemon --allow 192.168.1.0/24&lt;/pre&gt;

&lt;p&gt;Now on your own machine, &lt;i&gt;latika&lt;/i&gt; in the above example, set first where you want to distribute the compile:&lt;/p&gt;
&lt;pre&gt;export DISTCC_HOSTS='anjali,lzo'&lt;/pre&gt;

&lt;p&gt;If you want, do this in your .bashrc or shell startup script for your convenient.&lt;/p&gt;

&lt;p&gt;Compiling and building a project is now as easy as replacing the plain make command with:&lt;/p&gt;
&lt;pre&gt;make -j4 CC=distcc CXX=distcc&lt;/pre&gt;

&lt;p&gt;For troubleshooting, run &lt;i&gt;distccmon-text 3&lt;/i&gt; (nice for static logging) or &lt;i&gt;watch distccmon-text&lt;/i&gt; (useful for real-time view).&lt;/p&gt;

&lt;p&gt;Supposed another machine, e.g. &lt;i&gt;naina&lt;/i&gt;, wants to join the party, just do the same steps. Don't forget to adjust DISTCC_HOSTS so that the compile will be distributed also to &lt;i&gt;naina&lt;/i&gt;.&lt;/p&gt;

&lt;p&gt;That's it! For more info (I barely scratch the surface) and better optimization, refer to the manpage of distcc and distccd.&lt;/p&gt;

&lt;p&gt;Now the (trivia) question is, the host that runs &lt;i&gt;anjali&lt;/i&gt;, who do you think he is? :)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-8300088673771392717?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/8300088673771392717/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=8300088673771392717' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8300088673771392717'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8300088673771392717'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/02/distcc-virtualbox-nat.html' title='distcc, VirtualBox, NAT'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_Oijhf1ZPv-4/S4A1OV4To4I/AAAAAAAABfY/VCZtNUh-mX0/s72-c/distcc-vbox.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-8434188622000038483</id><published>2010-02-15T23:36:00.003+01:00</published><updated>2010-02-16T11:12:11.806+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='radeon'/><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='fglrx'/><category scheme='http://www.blogger.com/atom/ns#' term='kde'/><category scheme='http://www.blogger.com/atom/ns#' term='suse'/><title type='text'>new laptop, free yourself!</title><content type='html'>&lt;p&gt;The other day, I couldn't resist buying the el-cheapo Athlon 1.6 GHz-powered &lt;a href="http://www.google.com/search?q=Acer+Aspire+5532"&gt;Acer Aspire 5532&lt;/a&gt; in BestBuy for $330. With its 15.6 inch screen, seems that it is quite a nice bargain. It comes (of course) with Windows 7 Home Premium, but after slapping openSUSE 11.2 DVD I got from &lt;a href="http://ariya.blogspot.com/search/label/camp/"&gt;the last Camp KDE&lt;/a&gt; (must be from Will, thanks dude!) and a bunch of keystrokes, a few hours later the machine happily runs &lt;a href="http://www.kde.org/announcements/4.4/guide.php"&gt;the shiny KDE 4.4&lt;/a&gt;. Sound was not a problem, even WiFi was easy to get it working (hard to believe that after all these years, NetworkManager still does not work for me, maybe my bad karma). The included &lt;a href="http://www.x.org/wiki/radeonhd"&gt;radeonhd driver&lt;/a&gt; is good enough for its Radeon HD 3200 (RS780M chipset), but for the sake of testing, I did &lt;a href="http://en.opensuse.org/ATI_drivers#The_hard_way"&gt;install ATI fglrx &lt;s&gt;7.4&lt;/s&gt; 10.1&lt;/a&gt; and, voila, I got flawless &lt;a href="http://en.opensuse.org/KWin_Effects"&gt;KWin desktop effects&lt;/a&gt;. Even proprietary stuff like Opera, Skype, and Flash plugin faced no serious problem as well.&lt;/p&gt;

&lt;p&gt;Time for some fun hacking! :)&lt;/p&gt;

&lt;p&gt;Obligatory click-to-enlarge desktop snapshot follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/lSNmtU9UFRe3cpO9BI5yfQ?feat=embedwebsite"&gt;&lt;img src="http://lh5.ggpht.com/_Oijhf1ZPv-4/S3l9qOo7YlI/AAAAAAAABeg/HrXSPKTVBgg/s400/desktop-cube.png" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-8434188622000038483?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/8434188622000038483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=8434188622000038483' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8434188622000038483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8434188622000038483'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/02/new-laptop-free-yourself.html' title='new laptop, free yourself!'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_Oijhf1ZPv-4/S3l9qOo7YlI/AAAAAAAABeg/HrXSPKTVBgg/s72-c/desktop-cube.png' height='72' width='72'/><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-1709524884988607596</id><published>2010-01-18T03:11:00.000+01:00</published><updated>2010-01-18T03:12:38.950+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='san diego'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='kde'/><category scheme='http://www.blogger.com/atom/ns#' term='camp kde'/><title type='text'>camp kde: day two (sunday)</title><content type='html'>&lt;p&gt;Again, just track &lt;a href="http://twitter.com/#search?q=campkde"&gt;all the tweets&lt;/a&gt; and &lt;a href="http://planetkde.org"&gt;blogs&lt;/a&gt; to know what happens in &lt;a href="http://camp.kde.org"&gt;Camp KDE&lt;/a&gt; in almost real-time. For more pictures, check out &lt;a href="http://www.flickr.com/groups/1336717@N21/pool/"&gt;KDE Events Pool&lt;/a&gt; at Flickr.&lt;/p&gt;

&lt;p&gt;In one of the talks today, Romain &amp;quot;Frankenstein&amp;quot; Pokrzywka showcased KDE 4 on Windows. Though he &lt;a href="http://c2143.blogspot.com/2009/12/news-from-kdewin-front-part-2.html"&gt;blogged about it&lt;/a&gt; recently, it is definitely interesting to see a live demo, especially things like Plasma running (and crashing, occasionally) on Windows, and that some apps are really usable already. Well, who knows? In the not so distant future, it is definitely easier to convince Window users like Joe Sixpack to start using KDE apps.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/4283602748/" title="Romain by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm5.static.flickr.com/4055/4283602748_cd121dff19.jpg" width="500" height="333" alt="Romain"  style="border: 1px solid rgb(204, 204, 204); padding: 5px;" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-1709524884988607596?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/1709524884988607596/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=1709524884988607596' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1709524884988607596'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1709524884988607596'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/01/camp-kde-day-two-sunday.html' title='camp kde: day two (sunday)'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm5.static.flickr.com/4055/4283602748_cd121dff19_t.jpg' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-5657120839555009996</id><published>2010-01-17T05:53:00.001+01:00</published><updated>2010-01-17T05:59:15.710+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='san diego'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='kde'/><category scheme='http://www.blogger.com/atom/ns#' term='camp kde'/><title type='text'>camp kde: day one (saturday)</title><content type='html'>&lt;p&gt;Showing up at this year's &lt;a href="http://camp.kde.org"&gt;Camp KDE&lt;/a&gt; feels a bit weird. First of all, because I do not need to travel at all since &lt;a href="http://ariya.blogspot.com/2009/12/i-for-innovate.html"&gt;I already moved&lt;/a&gt; to San Diego some time ago. In addition to that, while &lt;a href="http://ariya.blogspot.com/2009/10/even-qpainter-has-qpainterend.html"&gt;I was still&lt;/a&gt; with Nokia (Qt), usually I could only attend conferences only if I have something to present. It is a great relief not to worry about my own talks and just enjoy the event.&lt;/p&gt;

&lt;p&gt;There were &lt;a href="http://camp.kde.org/schedule.html"&gt;few talks&lt;/a&gt; today. As you can guess, you can pretty much follow them if you keep an eye on &lt;a href="http://twitter.com/#search?q=campkde"&gt;#campkde tweets&lt;/a&gt; and/or follow &lt;a href="http://planetkde.org"&gt;Planet KDE these days&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/4280908214/" title="Prof Bourne on Open Access to Data by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm5.static.flickr.com/4043/4280908214_976f019b69.jpg" width="500" height="334" alt="Prof Bourne on Open Access to Data"  style="border: 1px solid rgb(204, 204, 204); padding: 5px;" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The keynote was from &lt;a href="http://www.sdsc.edu/~bourne/"&gt;Professor Bourne&lt;/a&gt;, he had a presentation about open access to data, in particular in the field of science (in his example, pharmaceutical sciences), such as the initiatives with protein databank, Public Library of Science, &lt;a href="http://www.scivee.tv/"&gt;SciVee&lt;/a&gt;. I fully agree with his opinions in this matter, especially since they resemble some of my observations when I was doing my &lt;a href="http://ariya.blogspot.com/2008/11/world-fastest-optical-polarization.html"&gt;graduate research&lt;/a&gt; years ago. In particular, &amp;quot;&lt;a href="http://en.wikipedia.org/wiki/Publish_or_perish"&gt;publish or perish&lt;/a&gt;&amp;quot; could potentially destroy the sharing spirit of researches. I do believe that competition is good, but I also do strongly believe that science is about sharing.&lt;/p&gt;

&lt;p&gt;I hope more people will show up tomorrow. The sunset here is so fantastic, you just have to experience it yourself.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/4239311554/" title="(almost) sunset at Lake Miramar by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2766/4239311554_e0e35d1ab3.jpg" width="500" height="333" alt="(almost) sunset at Lake Miramar"  style="border: 1px solid rgb(204, 204, 204); padding: 5px;" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To be continued (to day 2).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-5657120839555009996?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/5657120839555009996/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=5657120839555009996' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/5657120839555009996'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/5657120839555009996'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2010/01/camp-kde-day-one-saturday.html' title='camp kde: day one (saturday)'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm5.static.flickr.com/4043/4280908214_976f019b69_t.jpg' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-492173662179065441</id><published>2009-12-30T18:18:00.002+01:00</published><updated>2009-12-30T18:22:58.660+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='san diego'/><category scheme='http://www.blogger.com/atom/ns#' term='photo'/><category scheme='http://www.blogger.com/atom/ns#' term='qualcomm'/><category scheme='http://www.blogger.com/atom/ns#' term='musing'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='kde'/><title type='text'>"i" for innovate</title><content type='html'>&lt;p&gt;As I have &lt;a href="http://ariya.blogspot.com/2009/10/even-qpainter-has-qpainterend.html"&gt;hinted before&lt;/a&gt;, somehow I aimed to move to some sunny place in California. Well, lucky as we could be, after days of experiencing the transient stage (with tons of good and bad experiences, what a roller-coaster), we slowly settle in &lt;a href="http://wikitravel.org/en/San_Diego"&gt;San Diego&lt;/a&gt;, (arguably) a beautiful place to live. The proof is the following picture, basically I can enjoy watching sunset from our balcony every day when the weather permits (it does usually).&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/4228855644/" title="sunset from the balcony by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2710/4228855644_38a0120f56.jpg" width="500" height="333" alt="sunset from the balcony" style="border: 1px solid rgb(204, 204, 204); padding: 5px;" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Few weeks ago, I started a new position within &lt;a href="http://www.qualcomm.com/quicinc/"&gt;Qualcomm Innovation Center Inc.&lt;/a&gt;, specifically in the new Web Technologies team. This center is a wholly-owned subsidiary of Qualcomm, one of the &lt;a href="http://en.wikipedia.org/wiki/Worldwide_Top_20_Semiconductor_Sales_Leaders"&gt;top 10 semiconductor sales leaders&lt;/a&gt; last year. The official party line of Qualcomm Innovation Center is best understood by what our president, Rob Chandhok, &lt;a href="http://news.softpedia.com/news/Qualcomm-Offers-Support-for-Open-Source-Developers-125266.shtml"&gt;has expressed once&lt;/a&gt;: &lt;i&gt;focus on such important open source initiatives as Linux and Webkit, and on open source operating systems such as Symbian, Android and Chrome&lt;/i&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/4228855652/" title="Qualcomm by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2624/4228855652_e36bd2c9cb.jpg" width="500" height="334" alt="Qualcomm" style="border: 1px solid rgb(204, 204, 204); padding: 5px;" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, faithful followers of my blog can quickly point out that this whole thing is just a cover-up for the real motive: the strong desire to &lt;a href="http://ariya.blogspot.com/2008/11/i-chose-this-mortal-life.html"&gt;live in a perfect symmetry&lt;/a&gt; :)&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/4228855646/" title="the best juice on earth by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2647/4228855646_22861eba75.jpg" width="500" height="333" alt="the best juice on earth" style="border: 1px solid rgb(204, 204, 204); padding: 5px;" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In addition, to convince you that the alignment of the planet has been planned for this, surely you know (perfectly) where the &lt;a href="http://camp.kde.org/"&gt;upcoming Camp KDE&lt;/a&gt; will be held?&lt;/p&gt;

&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_Oijhf1ZPv-4/SzuMV_B7OUI/AAAAAAAABbo/8Mf_93riApA/s1600-h/Campkde2010_logo.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 66px;" src="http://4.bp.blogspot.com/_Oijhf1ZPv-4/SzuMV_B7OUI/AAAAAAAABbo/8Mf_93riApA/s400/Campkde2010_logo.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5421080885795174722" /&gt;&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;See you in 2 weeks. Happy 0x7da!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-492173662179065441?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/492173662179065441/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=492173662179065441' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/492173662179065441'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/492173662179065441'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2009/12/i-for-innovate.html' title='&quot;i&quot; for innovate'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2710/4228855644_38a0120f56_t.jpg' height='72' width='72'/><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-5314642102985962068</id><published>2009-11-28T12:22:00.000+01:00</published><updated>2009-11-28T12:23:19.729+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photo'/><category scheme='http://www.blogger.com/atom/ns#' term='travel'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='vacation'/><category scheme='http://www.blogger.com/atom/ns#' term='indonesia'/><category scheme='http://www.blogger.com/atom/ns#' term='food'/><title type='text'>putu, kelepon, terang bulan</title><content type='html'>&lt;p&gt;While enjoying &lt;a href="http://ariya.blogspot.com/2009/10/even-qpainter-has-qpainterend.html"&gt;this vacation&lt;/a&gt;, I managed to steal few hours to do some fun coding. Nothing spectacular, but it yielded something I will surely share in the near future. However, since I am still in the mood of &lt;a href="http://ariya.blogspot.com/2009/11/parijs-van-java.html"&gt;bombing the planet again&lt;/a&gt;, here is another post with food pictures.&lt;/p&gt;

&lt;p&gt;Something else we were glad to taste during our extremely &lt;a href="http://ariya.blogspot.com/2009/11/parijs-van-java.html"&gt;short visit to Bandung&lt;/a&gt; were &lt;a href="http://id.wikipedia.org/wiki/Kue_putu"&gt;Putu&lt;/a&gt; and &lt;a href="http://id.wikipedia.org/wiki/Klepon"&gt;Kelepon&lt;/a&gt;, typically sold at the price of 1 EUR for 25 pieces. They are basically rice cake filled with palm sugar and served with grated coconut. Putu is steamed, while kelepon is boiled. The latter is also colored using pandan leaves.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/4140155692/" title="putu and kelepon by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2786/4140155692_8984c2a488.jpg" width="500" height="333" alt="putu and kelepon"   style="border: 1px solid rgb(204, 204, 204); padding: 5px;" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While sampling culinary specialties means that we do not cook quite often, when the opportunity presents itself, it is of course a good feeling to eat something home-made once a while. Here is one: &lt;a href="http://id.wikipedia.org/wiki/Martabak_manis"&gt;Terang Bulan&lt;/a&gt; (literally: bright moon). It is some sort of pancake, very similar to &lt;a href="http://ariya.blogspot.com/2009/06/martabak.html"&gt;Martabak&lt;/a&gt; except Terang Bulan is filled with sugar, sprinkles, condensed milk, cheese, and the likes. Hence, it is also known as Martabak Manis (literally: sweet Martabak), a term that is somehow I dislike (because language-wise it is unnecessary as there exists a good name for that and thus it extends and pollutes the meaning of Martabak with a very weak reason).&lt;/p&gt;

&lt;p&gt;The recipe? Check what &lt;a href="http://dapurnegeridongeng.blogspot.com/2008/11/martabak-manis-indonesian-style-sweet.html"&gt;this lady has posted&lt;/a&gt;. Terang Bulan is sweet and healthy (reduce the amount of sugar if in doubt), it makes for a good snack in the afternoon.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/4139883913/" title="Home-made Terang Bulan by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2710/4139883913_2af45285ce.jpg" width="500" height="333" alt="Home-made Terang Bulan"   style="border: 1px solid rgb(204, 204, 204); padding: 5px;" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Last but not least: &lt;b&gt;Eid Mubarak&lt;/b&gt; to everyone!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-5314642102985962068?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/5314642102985962068/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=5314642102985962068' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/5314642102985962068'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/5314642102985962068'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2009/11/putu-kelepon-terang-bulan.html' title='putu, kelepon, terang bulan'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2786/4140155692_8984c2a488_t.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-123952866131938330</id><published>2009-11-24T02:41:00.002+01:00</published><updated>2009-11-24T02:44:31.742+01:00</updated><title type='text'>parijs van java</title><content type='html'>&lt;p&gt;Somehow the wind finally leads me to &lt;a href="http://en.wikipedia.org/wiki/Bandung"&gt;Bandung&lt;/a&gt;, the place where I spent years
studying at &lt;a href="http://en.wikipedia.org/wiki/Institut_Teknologi_Bandung"&gt;ITB&lt;/a&gt;. While still trying to absorb all the deja-vu sensations (last
time I was here, when I left the place, was 6 years ago!), nothing beats having
breakfast (and potentially also lunch and dinner later on) in one of those
food stalls. Since I promised to write about my culinary excitement, here is
one to pollute the planets (the aggregated blogs, not our blue marble): &lt;i&gt;Kupat
Tahu&lt;/i&gt;. Essentially it is fried tofu, bean sprouts, and &lt;a href="http://en.wikipedia.org/wiki/Lontong"&gt;lontong&lt;/a&gt; (compressed rice)
served with peanut sauce and some crackers. That makes it for a good breakfast.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/4129082463/" title="kupat
tahu bandung by Ariya Hidayat, on Flickr"&gt;&lt;img
src="http://farm3.static.flickr.com/2751/4129082463_3b4ae36860.jpg" width="500"
height="333" alt="kupat tahu bandung"  style="border: solid #cccccc 1px;
padding: 5px;"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I will be in Bandung today and tomorrow, mostly just around the university. If
you are around and want to have a chat, feel free to drop me an email!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-123952866131938330?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/123952866131938330/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=123952866131938330' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/123952866131938330'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/123952866131938330'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2009/11/parijs-van-java.html' title='parijs van java'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2751/4129082463_3b4ae36860_t.jpg' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-592034346360572845</id><published>2009-11-04T23:04:00.002+01:00</published><updated>2009-11-04T23:07:35.921+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='vacation'/><category scheme='http://www.blogger.com/atom/ns#' term='musing'/><category scheme='http://www.blogger.com/atom/ns#' term='funny'/><title type='text'>english vs indonesian</title><content type='html'>&lt;p&gt;One thing which recently made it into my reverse-culture-shock impact list is the
widespread use of incomprehensible (read: broken), mixed-language expressions,
potentially due to many reasons (to name a few: innocent show-off, following the
mainstream, or just trying to look more &amp;quot;educated&amp;quot;). It starts with
an easy one, like denoting the printer cartridge types as &amp;quot;black&amp;quot; and
&amp;quot;color&amp;quot;, i.e. in English, although we have good Indonesian words for
that (&amp;quot;hitam&amp;quot; and &amp;quot;warna&amp;quot;, in case you can't recall). The
worse part is yet to come, it kills me when someone starts to sprinkle English
words in an otherwise perfect sentence, e.g. &amp;quot;tapi &lt;i&gt;you&lt;/i&gt; mesti ngajak
aku &lt;i&gt;to follow your&lt;/i&gt;, ehm [can't find the English words], kegiatan,
&lt;i&gt;which is&lt;/i&gt; sebenarnya &lt;i&gt;quite interesting&lt;/i&gt;&amp;quot;. This
wonderful fragment is ridiculously non-sense for both foreigners who never
learned Indonesian and for my fellow countrymen who do not know English at
all.&lt;/p&gt;

&lt;p&gt;Of course it won't surprise you if I say that you can easily find flyers and
other promotion materials exactly using the same pattern. Just today we found a
state-sponsored, free &lt;i&gt;Shopping &amp;amp; Travelling Guide&lt;/i&gt; booklet featuring
dozens of pages with English headings. Again, the contents are written in
Indonesian. This leads to a number of striking typos and mistakes, one of which
is shown here:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/4075534791/" title="the
typical typo by Ariya Hidayat, on Flickr"&gt;&lt;img
src="http://farm4.static.flickr.com/3502/4075534791_e0394e1b66.jpg" width="500"
height="376" alt="the typical typo" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have nothing against foreign languages (I have my share by learning few of
them), but I also still love my wonderful mother tongue, &lt;a
href="http://en.wikipedia.org/wiki/Bahasa_Indonesia"&gt;Bahasa Indonesia&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-592034346360572845?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/592034346360572845/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=592034346360572845' title='17 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/592034346360572845'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/592034346360572845'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2009/11/english-vs-indonesian.html' title='english vs indonesian'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3502/4075534791_e0394e1b66_t.jpg' height='72' width='72'/><thr:total>17</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-1684525204155885490</id><published>2009-10-22T12:26:00.001+02:00</published><updated>2009-10-22T12:28:01.209+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='musing'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><title type='text'>even QPainter has QPainter::end()</title><content type='html'>&lt;p&gt;&lt;a href="http://ariya.blogspot.com/2008/04/i-think-im-moving-but-i-got-nowhere.html"&gt;I came to Trolltech&lt;/a&gt; (then became Qt Software, then Qt Development Framework) early last year, at the time when the Trolls were busy stabilizing Qt 4.4. I was assigned to work on &lt;a href="http://qt.nokia.com/doc/qtwebkit.html"&gt;QtWebKit&lt;/a&gt;, so right from Day 0, I did carry out my best patching skills and committed my &lt;a href="http://trac.webkit.org/search?q=Ariya+Hidayat&amp;noquickjump=1&amp;changeset=on"&gt;burst fixes&lt;/a&gt; as fast as I could. &lt;a href="http://ariya.blogspot.com/2008/05/quattro-quattro-zero.html"&gt;Qt 4.4.0 was released&lt;/a&gt; shortly after, followed by &lt;a href="http://ariya.blogspot.com/2008/08/quattro-quattro-uno.html"&gt;4.4.1&lt;/a&gt;, and the remaining 4.4.x series.&lt;/p&gt;

&lt;p&gt;Summer was fun. I learned a lot about WebKit, git, development workflow, the art of backporting, and a lot of other stuff. Together with Samuel, we &lt;a href="http://ariya.blogspot.com/2008/06/return-of-graphics-dojo-opengl.html"&gt;did resurrect Graphics Dojo&lt;/a&gt;. Ever since, I am sure you spotted a bunch of biweekly &lt;a href="http://labs.qt.nokia.com/blogs/author/ariya"&gt;graphics and WebKit examples&lt;/a&gt; I posted: 27 examples &lt;a href="http://ariya.blogspot.com/2009/10/graphics-dojo-in-2009-wrap-up.html"&gt;this year&lt;/a&gt; and 12 examples &lt;a href="http://ariya.blogspot.com/2008/12/graphics-dojo-in-2008-wrap-up.html"&gt;last year&lt;/a&gt;. Autumn brought me to my first Qt Developer Days 2008, both in &lt;a href="http://ariya.blogspot.com/2008/10/bye-munich-see-you-in-us.html"&gt;Munich&lt;/a&gt; and &lt;a href="http://ariya.blogspot.com/2008/10/kde-qt.html"&gt;Redwood City&lt;/a&gt;. We also did a bit of tour to &lt;a href="http://ariya.blogspot.com/2008/10/breaking-new-ground.html"&gt;the east coast&lt;/a&gt;, back to &lt;a href="http://ariya.blogspot.com/2008/11/summer-of-code-2008-mentor-summit.html"&gt;around Mountain View&lt;/a&gt;, and most importantly I got to know the &lt;a href="http://ariya.blogspot.com/2008/11/i-chose-this-mortal-life.html"&gt;best juice&lt;/a&gt; in the world.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/3959014488/" title="at work by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2581/3959014488_ef2edfb6a9.jpg" width="500" height="376" alt="at work" style="border: solid #cccccc 1px; padding: 5px;"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I completely forgot to blog about this, probably because it was not worth mentioning, but during this time I rightfully obtained my Ph.D degree (or rather the official &lt;a href="http://en.wikipedia.org/wiki/Doctorate#Germany"&gt;Dr.&amp;nbsp;-Ing&lt;/a&gt;). My 70-page dissertation is &lt;a href="http://ubdok.uni-paderborn.de/servlets/DocumentServlet?id=10598"&gt;available for download&lt;/a&gt;, still I suggest reading the summary in &lt;a href="http://ariya.blogspot.com/2008/11/world-fastest-optical-polarization.html"&gt;the 8-page paper&lt;/a&gt;. FWIW, I passed with &lt;i&gt;magna cum laude&lt;/i&gt;.&lt;/p&gt;

&lt;p&gt;After the winter break (I did &lt;a href="http://ariya.blogspot.com/2008/12/knocked-out.html"&gt;two trips&lt;/a&gt; to my home country), spring brought us the long-waited &lt;a href="http://ariya.blogspot.com/2009/03/quattro-cinque-zero.html"&gt;Qt 4.5&lt;/a&gt; along with &lt;a href="http://ariya.blogspot.com/2009/06/all-blessings-in-may.html"&gt;other blessings&lt;/a&gt; (LGPL, open repository, contribution model, S60 port). Qt for S60 was getting hot, I wrote a bunch of &lt;a href="http://ariya.blogspot.com/2009/07/like-startling-sign-that-fate-had.html"&gt;smaller examples&lt;/a&gt;, &lt;a href="http://ariya.blogspot.com/2009/08/again-map-of-my-world-gets-smaller-as-i.html"&gt;OpenStreetMap&lt;/a&gt;, &lt;a href="http://ariya.blogspot.com/2009/09/frozen-in-headlights-have-i-made-final.html"&gt;ray casting&lt;/a&gt;, and some others, all of them showed up as &lt;a href="http://labs.qt.nokia.com/blogs/2009/10/14/qt-460-beta1-for-symbian-is-out/"&gt;new examples&lt;/a&gt; in Qt 4.6.  After all, I am always thrilled to offer our valued customers some &lt;i&gt;blue sky&lt;/i&gt; approaches and &lt;i&gt;streamlined, breakthrough paradigm shifts&lt;/i&gt; so that they can better &lt;i&gt;monetize&lt;/i&gt; their &lt;i&gt;mission-critical, enterprise&lt;/i&gt; graphical applications in this &lt;i&gt;quality-driven, business-focused Web 2.0&lt;/i&gt; world :-)&lt;/p&gt;

&lt;p&gt;It also meant the traveling time (for doing talks) started again for me. For a lowly code monkey like me, I am proud (on Nokia's behalf) that this year alone, I had delivered 5 (mostly successful) graphics-related presentations in open-source/developer conferences: &lt;a href="http://ariya.blogspot.com/2009/05/daylight-seems-to-want-you-just-as-much.html"&gt;Pycon Italia&lt;/a&gt; in Florence, &lt;a href="http://ariya.blogspot.com/2009/06/and-only-chance-we-have-of-moving-on.html"&gt;LinuxTag&lt;/a&gt; in Berlin, and of course &lt;a href="http://ariya.blogspot.com/2009/07/paella-de-marisco.html"&gt;Akademy&lt;/a&gt; in Gran Canaria, &lt;a href="http://ariya.blogspot.com/2009/10/bye-amsterdam-next-stop-munich.html"&gt;Maemo Summit&lt;/a&gt; in Amsterdam and &lt;a href="http://ariya.blogspot.com/2009/10/bye-munich-and-d2.html"&gt;Qt Developer Days&lt;/a&gt; in Munich.&lt;/p&gt;

&lt;p&gt;At this point, you can probably guess how it would end. Our &lt;a href="http://ariya.blogspot.com/2009/10/paris-lisbon-madrid.html"&gt;last short, memorable vacation&lt;/a&gt; around Europe was enough hint. Yes, today is my last day in the office. Our flight back to Indonesia is due within few days. The parting is amicable and amiable. &lt;a href="http://ariya.blogspot.com/2009/10/webkit-dinner-gado-gado-nasi-uduk.html"&gt;The Last Supper&lt;/a&gt;, for my (soon ex-) team mates has been served, too.&lt;/p&gt;

&lt;p&gt;Spare the tears, follows is the actual resignation e-mail I sent to our internal mailing-list (the &amp;quot;Foul Stench Officer&amp;quot; refers to &lt;a href="http://ariya.blogspot.com/2009/03/for-glorious-nation.html"&gt;the durian incident&lt;/a&gt; back then). Last note: my e-mails ariya.hidayat@trolltech.com and ariya.hidayat@nokia.com will soon RIP.&lt;/p&gt;&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;&lt;i&gt;Subject: Even QPainter has a QPainter::end() function&lt;br&gt;
From: Ariya Hidayat &amp;lt;ariya.hidayat@trolltech.com&amp;gt;&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;After being involved in the affair of &amp;quot;connecting people&amp;quot;  &amp;lt;insert the jingle
here&amp;gt; for some time, I decided that it is the time to move on. If everything
goes smoothly, then starting from November 1st (which is a good day, since
November is the 11th Gregorian month and 11 is the first double-digit prime
number) I would not work for QtSW anymore. Going through a lengthy
discussion, my other (better) half and I finally came to a conclusion that
Oslo, as beautiful as it is, is not really the place where we want to settle
down, at least for the near future.&lt;/p&gt;

&lt;p&gt;I still hesitate to definitely mention where I would be stationed by the end
of this year. This is because many things depend on e.g. the visa process (as
uncertain as the Schrödinger's cat), and being a citizen of a country stamped
in the &amp;quot;terrorism haven&amp;quot; list does not really help. In the worst case, I will
take a short leave in my career and spend time with my family, in some sunny
city (comparable, if not better, than Las Palmas) in our home country. In the
best case (finger crossed!), it will be another sunny city, somewhere in
California (to avoid speculation, I can safely say beforehand: no, right now
I have zero interest to work for a search engine or a fruit company).&lt;/p&gt;

&lt;p&gt;I have been using Qt since my C++ skill was still a joke. Rest assured, I will
be still using Qt in the future, at least for my personal pet projects and/or
my spare-time joyful endeavor with KDE. And although it has nothing to do
with Qt, I can proudly say that my coming professional activities will be
still around open-source projects (surprise!).&lt;/p&gt;

&lt;p&gt;It is an honor to serve with all of you, my fellow Trolls!&lt;/p&gt;

&lt;p&gt;Your Chief Foul Stench Officer&lt;/p&gt;

&lt;p&gt;END OF TRANSMISSION&lt;/p&gt;

&lt;hr&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-1684525204155885490?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/1684525204155885490/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=1684525204155885490' title='23 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1684525204155885490'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1684525204155885490'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2009/10/even-qpainter-has-qpainterend.html' title='even QPainter has QPainter::end()'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2581/3959014488_ef2edfb6a9_t.jpg' height='72' width='72'/><thr:total>23</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-2775458699172697686</id><published>2009-10-22T12:07:00.002+02:00</published><updated>2009-10-22T12:10:16.745+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='musing'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>graphics dojo in 2009: wrap-up</title><content type='html'>&lt;p&gt;That is, 2009 is coming to its end. Some parts in Central Europe already enjoy the snow although Oslo still has a touch of &lt;a href="http://ariya.blogspot.com/2009/10/from-autumn-to-winter.html"&gt;autumn feeling&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is a list of biweekly &lt;a href="http://labs.qt.nokia.com/blogs/author/ariya/"&gt;Graphics Dojo examples&lt;/a&gt; that I managed to pull off this year. Most of them are available for Qt/C++ and PyQt.&lt;/p&gt;

&lt;p&gt;Note that although the examples are categorized (for your convenience), often it does not strictly belong to one category, e.g. &lt;i&gt;night mode&lt;/i&gt; is both a graphics and WebKit example. Also, all S60 examples are designed with S60 mind but they still run well on the desktop, too.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;S60&lt;/b&gt;&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;Wolfenstein-like &lt;a href="http://labs.qt.nokia.com/blogs/2009/08/09/ray-casting-on-qts60/"&gt;ray casting&lt;/a&gt; in your pocket.&lt;/li&gt;

&lt;li&gt;Maps solution &lt;a href="http://labs.qt.nokia.com/blogs/2009/08/04/openstreetmap-and-qt-and-s60/"&gt;using OpenStreetMap&lt;/a&gt;, of course running on the phone, too.&lt;/li&gt;

&lt;li&gt;&lt;a href="http://labs.qt.nokia.com/blogs/2009/07/26/track-your-flight-with-qts60/"&gt;Flight tracking utility&lt;/a&gt;, useful to check the status and time.&lt;/li&gt;

&lt;li&gt;&lt;a href="http://labs.qt.nokia.com/blogs/2009/07/22/weather-info-for-qts60/"&gt;Weather info on your pocket&lt;/a&gt;.&lt;/li&gt;

&lt;li&gt;Still about kinetic scrolling, now with &lt;a href="http://labs.qt.nokia.com/blogs/2009/07/19/kinetic-scrolling-on-any-widgets/"&gt;a Flickable interface&lt;/a&gt; that works smooth also on a phone.&lt;/li&gt;

&lt;li&gt;Suitable for your S60 phone: &lt;a href="http://labs.qt.nokia.com/blogs/2009/07/15/digital-clock-in-a-phone/"&gt;flipping digital clock&lt;/a&gt;.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;b&gt;Graphics&lt;/b&gt;&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;Reborn/recycled &lt;a href="http://labs.qt.nokia.com/blogs/2009/10/22/home-screen-with-parallax-effect/"&gt;parallax effect&lt;/a&gt; for the home screen.&lt;/li&gt;

&lt;li&gt;Simplified &lt;a href="http://labs.qt.nokia.com/blogs/2009/10/07/magnifying-glass/"&gt;magnifying glass&lt;/a&gt; trick.&lt;/li&gt;

&lt;li&gt;A simple trick to get &lt;a href="http://labs.qt.nokia.com/blogs/2009/06/09/night-mode-in-qwebview/"&gt;the night-mode vision&lt;/a&gt;, just like in some navigation system.&lt;/li&gt;

&lt;li&gt;&lt;a href="http://labs.qt.nokia.com/blogs/2009/03/20/moving-top-level-window-by-dragging/"&gt;DragMove charm&lt;/a&gt; to allow widget moving by dragging&lt;/li&gt;

&lt;li&gt;&lt;a href="http://labs.qt.nokia.com/blogs/2009/03/03/qtimeline-made-easy/"&gt;simple timeline demo&lt;/a&gt; along with a custom S-shape curve&lt;/li&gt;

&lt;li&gt;&lt;a href="http://labs.qt.nokia.com/blogs/2009/01/26/creating-thumbnail-preview/"&gt;thumbnail preview&lt;/a&gt; via a fast cheat-scaling trick.&lt;/li&gt;

&lt;li&gt;cheap trick to &lt;a href="http://labs.qt.nokia.com/blogs/2009/01/20/50-scaling-of-argb32-image/"&gt;half-scale ARGB32 image&lt;/a&gt; very fast.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;b&gt;WebKit&lt;/b&gt;&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;Doing a talk? Use &lt;a href="http://labs.qt.nokia.com/blogs/2009/08/25/presentation-with-s5/"&gt;a presentation tool&lt;/a&gt; purely based on web technologies.&lt;/li&gt;

&lt;li&gt;&lt;a href="http://labs.qt.nokia.com/blogs/2009/07/29/maps-with-a-magnifying-glass/"&gt;Magnifying glass trick&lt;/a&gt; with Google Maps.&lt;/li&gt;

&lt;li&gt;&lt;a href="http://labs.qt.nokia.com/blogs/2009/06/30/transparent-qwebview-or-qwebpage/"&gt;Make your QWebView transparent&lt;/a&gt; to achieve some interesting effect.&lt;/li&gt;

&lt;li&gt;&lt;a href="http://labs.qt.nokia.com/blogs/2009/06/06/qwebview-snap-scrolling/"&gt;snap-scrolling in QWebView&lt;/a&gt;, useful for small-screen browser.&lt;/li&gt;

&lt;li&gt;Need to do a visual web scraping? This little &lt;a href="http://labs.qt.nokia.com/blogs/2009/06/02/weather-applet-again/"&gt;weather applet&lt;/a&gt;, which scraps the Google-provided page, might be a good start.&lt;/li&gt;

&lt;li&gt;&lt;a href="http://labs.qt.nokia.com/blogs/2009/04/17/jquery-and-qwebelement/"&gt;Use jQuery, enjoy selector goodies&lt;/a&gt; with QtWebKit&lt;/li&gt;

&lt;li&gt;&lt;a href="http://labs.qt.nokia.com/blogs/2009/03/20/google-suggest-made-easy/"&gt;simple example&lt;/a&gt; to integrate Google Suggest&lt;/li&gt;

&lt;li&gt;&lt;a href="http://labs.qt.nokia.com/blogs/2009/03/12/wysiwyg-html-editor/"&gt;WYSIWYG HTML Editor&lt;/a&gt; using QtWebKit&lt;/li&gt;

&lt;li&gt;&lt;a href="http://labs.qt.nokia.com/blogs/2009/03/08/creating-a-google-chat-client-in-15-minutes/"&gt;Google chat client&lt;/a&gt; made in 15 minutes&lt;/li&gt;

&lt;li&gt;&lt;a href="http://labs.qt.nokia.com/blogs/2009/01/15/capturing-web-pages/"&gt;web capture&lt;/a&gt;, a tool to take a snapshot of web pages.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;b&gt;JavaScript&lt;/b&gt;&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;Run &lt;a href="http://labs.qt.nokia.com/blogs/2009/04/15/monster-evolution-in-qt-episode-3-revenge-of-the-cylinders/"&gt;Monster Evolution demo&lt;/a&gt; with Qt and V8 (the JavaScript engine behind Google Chrome)&lt;/li&gt;

&lt;li&gt;Still about Monster, but &lt;a href="http://labs.qt.nokia.com/blogs/2009/04/07/monster-evolution-in-qt-episode-2-attack-of-the-squirrelfish/"&gt;now with JavaScriptCore of QtWebKit&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;Or, just run this cool Monster Evolution &lt;a href="http://labs.qt.nokia.com/blogs/2009/04/03/monster-evolution-in-qt-part-1-using-qt-script/"&gt;demo with QtScript&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="http://labs.qt.nokia.com/blogs/2009/01/06/simple-qtscript-based-bar-chart/"&gt;simple bar chart&lt;/a&gt; using QtScript.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Need more goodies? See also &lt;a href="http://ariya.blogspot.com/2008/12/graphics-dojo-in-2008-wrap-up.html"&gt;last year (2008) graphics dojo wrap-up&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Until next time.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-2775458699172697686?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/2775458699172697686/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=2775458699172697686' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2775458699172697686'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2775458699172697686'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2009/10/graphics-dojo-in-2009-wrap-up.html' title='graphics dojo in 2009: wrap-up'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-1213154768676535639</id><published>2009-10-21T19:18:00.001+02:00</published><updated>2009-10-21T19:18:44.313+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='travel'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='amsterdam'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='kinetic'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><title type='text'>kinetic scrolling: the state machine</title><content type='html'>&lt;p&gt;Some of the slides from &lt;a href="http://ariya.blogspot.com/2009/10/bye-amsterdam-next-stop-munich.html"&gt;last Maemo Summit in Amsterdam&lt;/a&gt; have been made online. Here is the one from the &lt;a href="http://wiki.maemo.org/Maemo_Summit_2009/Schedule/Day_1#Cross-platform_with_Qt_-_live"&gt;Cross Platform with Qt&lt;/a&gt; talk that I held. It does not give much, though, since mostly what counts is the real live demo. Let us hope that at some point in time, the recorded videos will be online as well. Of course, there are also other interesting slides such as &lt;a href="
http://www.slideshare.net/peterschneider/maemo-5-developer-offering"&gt;Harmattan highlights&lt;/a&gt; and its &lt;a href="http://www.slideshare.net/jtukkine/maemo-6-harmattan-architecture-overview"&gt;architecture&lt;/a&gt;, &lt;a href="http://www.slideshare.net/olevine/handson-development-with-nokia-web-runtime"&gt;Web Runtime&lt;/a&gt;, &lt;a href="http://www.slideshare.net/omcfadde/maemo-summit-quake3"&gt;Quake3&lt;/a&gt;, and many others.&lt;/p&gt;

&lt;div style="width:425px;text-align:left" id="__ss_2290669"&gt;&lt;a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/qtbynokia/cross-platform-qt" title="Cross Platform Qt"&gt;Cross Platform Qt&lt;/a&gt;&lt;object style="margin:0px" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=crossplatformqt-091020061123-phpapp02&amp;stripped_title=cross-platform-qt" /&gt;&lt;param name="allowFullScreen" value="true"/&gt;&lt;param name="allowScriptAccess" value="always"/&gt;&lt;embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=crossplatformqt-091020061123-phpapp02&amp;stripped_title=cross-platform-qt" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"&gt;View more &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/"&gt;documents&lt;/a&gt; from &lt;a style="text-decoration:underline;" href="http://www.slideshare.net/qtbynokia"&gt;Nokia, Qt Development Frameworks&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;While I am there, if you check the slides from my talk above, page 9 shows the secret behind kinetic scrolling code, which I featured before as &lt;a href="http://labs.qt.nokia.com/blogs/2008/11/15/flick-list-or-kinetic-scrolling/"&gt;Flick Charm&lt;/a&gt; or &lt;a href="http://labs.qt.nokia.com/blogs/2009/07/19/kinetic-scrolling-on-any-widgets/"&gt;Flickable interface&lt;/a&gt;. Or, in another version as follows (click to enlarge):&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/6-C8GONsD7zEJDw0_LcZtQ?feat=embedwebsite"&gt;&lt;img src="http://lh6.ggpht.com/_Oijhf1ZPv-4/St3bSQsHyUI/AAAAAAAABZo/hiX14I8CZDQ/s400/kinetic_scrolling.png" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, it is the simplified version and ignore some details, but that should be a good start to really digest the code. Since it was hacked in the old 4.4/4.5 time, I did not have the luxury of using the new &lt;a href="http://qt.nokia.com/doc/4.6-snapshot/qt4-6-intro.html#state-machine-framework"&gt;state machine framework&lt;/a&gt; in Qt 4.6. As an exercise for you, the brave readers, convert the code to use the framework. In addition, it does not support yet bouncing-on-edge feature, something which can serve as another exercise, too.&lt;/p&gt;

&lt;p&gt;Have fun with scrolling :)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-1213154768676535639?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/1213154768676535639/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=1213154768676535639' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1213154768676535639'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1213154768676535639'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2009/10/kinetic-scrolling-state-machine.html' title='kinetic scrolling: the state machine'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_Oijhf1ZPv-4/St3bSQsHyUI/AAAAAAAABZo/hiX14I8CZDQ/s72-c/kinetic_scrolling.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-1123286046163554012</id><published>2009-10-20T09:36:00.001+02:00</published><updated>2009-10-20T09:38:20.936+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='opensuse'/><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='chromium'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><title type='text'>Chromium on OpenSUSE</title><content type='html'>&lt;p&gt;Though Google Chrome &lt;a href="http://www.google.com/chrome/intl/en/linux.html"&gt;for Linux&lt;/a&gt; is not yet officially announced, people have been working to make Chromium, the open-source version thereof, available for different popular distributions. &lt;a href="http://ariya.blogspot.com/2008/09/on-crossover-chromium-way-for-chrome-on.html"&gt;I wrote before&lt;/a&gt; about CrossOver Chromium, but not only this is just a hack, it is also not up-to-date at all. The easiest way for OpenSUSE 11.1 users is to use &lt;a href="http://stick.gk2.sk/blog/2009/10/chromium-package-in-contrib/"&gt;the package from Contrib&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Though for veteran OpenSUSE fans, the steps to install Chromium are obvious, here I write down the idiot-proof version. Go to &lt;a href="http://software.opensuse.org/search"&gt;http://software.opensuse.org/search&lt;/a&gt;, type Chromium and click the Search button, wait for a moment, find the entry from openSUSE:Factory:Contrib/openSUSE_11.1, then well, click on the &lt;i&gt;1-Click Install&lt;/i&gt; button there. Follow the usual installation guides (mostly just agreeing and confirming some stuff), then in few minutes you will get:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/zNp3usH_PgJSzd-KVXg0qw?feat=embedwebsite"&gt;&lt;img src="http://lh6.ggpht.com/_Oijhf1ZPv-4/Stz50q-7FII/AAAAAAAABZc/i6wdY5hyVhQ/s400/chromium_opensuse.png" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Who says installing software in Linux is difficult? :)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-1123286046163554012?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/1123286046163554012/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=1123286046163554012' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1123286046163554012'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1123286046163554012'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2009/10/chromium-on-opensuse.html' title='Chromium on OpenSUSE'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_Oijhf1ZPv-4/Stz50q-7FII/AAAAAAAABZc/i6wdY5hyVhQ/s72-c/chromium_opensuse.png' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-8602557259704822750</id><published>2009-10-18T20:05:00.000+02:00</published><updated>2009-10-18T20:06:16.436+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photo'/><category scheme='http://www.blogger.com/atom/ns#' term='musing'/><category scheme='http://www.blogger.com/atom/ns#' term='oslo'/><title type='text'>from autumn to winter</title><content type='html'>&lt;p&gt;The wave of cold weather is approaching us, the nature's way of saying &lt;i&gt;Wind of Change&lt;/i&gt;. While some parts of Europe enjoy the snow already, Oslo is relative still calm and actually enjoyable, even in the afternoon, for a walk.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/4022408597/" title="from autumn to winter by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3087/4022408597_037425e39f.jpg" width="500" height="376" alt="from autumn to winter" border="0" style="border: solid #cccccc 1px; padding: 5px;" /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;(Picture was taken and shared to Flickr using Nokia N900 :)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-8602557259704822750?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/8602557259704822750/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=8602557259704822750' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8602557259704822750'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8602557259704822750'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2009/10/from-autumn-to-winter.html' title='from autumn to winter'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3087/4022408597_037425e39f_t.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-1927703785520232226</id><published>2009-10-16T17:03:00.000+02:00</published><updated>2009-10-16T17:04:30.640+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photo'/><category scheme='http://www.blogger.com/atom/ns#' term='munich'/><category scheme='http://www.blogger.com/atom/ns#' term='travel'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='devdays'/><category scheme='http://www.blogger.com/atom/ns#' term='food'/><title type='text'>bye munich (and D2)</title><content type='html'>&lt;p&gt;After &lt;a href="http://ariya.blogspot.com/2009/10/qt-developer-days-2009-live.html"&gt;kickstarted on Tuesday&lt;/a&gt;, Qt Developer Days 2009 Munich has ended. Some of us, the Trolls, are already back in Oslo, recovering from the intense adrenalin kicks within the last 72 hours (or more). The extra surprise was to experience the first snow in Munich (and this is still mid October!). Most must recharge pretty fast, considering the &lt;a href="http://qt.nokia.com/qtdevdays2009/hotel-and-travel#qt-developer-days-san"&gt;San Francisco version&lt;/a&gt; of the event is in about two weeks time.&lt;/p&gt;

&lt;p&gt;There already a bunch of articles &lt;a href="http://news.google.com/news/search?q=nokia+qt+developer+days"&gt;covering the event&lt;/a&gt; which show up in some sites, Aron has most of them in &lt;a href="http://blog.qt.nokia.com/2009/10/14/qt-developer-days-munich-and-thats-a-wrap/"&gt;his wrap-up blog entry&lt;/a&gt;. More links are and will be available via &lt;a href="http://twitter.com/qtbynokia"&gt;qtbynokia twitter&lt;/a&gt;. Fancy some pictures instead? Search for &lt;a href="http://www.flickr.com/photos/tags/qtdd09/"&gt;qtdd09 tag on Flickr&lt;/a&gt; and enjoy them!&lt;/p&gt;

&lt;p&gt;As for me, I am glad that this is finally over. It's all about people: it was exciting to meet old friends and make new ones. In addition, my &lt;b&gt;Special FX with Graphics View&lt;/b&gt; talk was well received (the room was jam-packed), I got some very interesting feedback and questions to follow-up. The other talk, &lt;b&gt;Copy Your Favourite Nokia App with Qt&lt;/b&gt;, was a bit quiet (the typical problem of all presentations in the afternoon of the last day) but still, it was as interactive as it could be.&lt;/p&gt;

&lt;p&gt;This mini wrap-up is not complete without food photos. While we were in Munich, we ventured some different possibilities for dinner. Let me just show you two of them: Low-carb Seafood and Biryani:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/4016467020/" title="Low-carb Meal (with Seafood) by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2610/4016467020_a2768d3556.jpg" width="500" height="334" alt="Low-carb Meal (with Seafood)"  border="0" style="border: solid #cccccc 1px; padding: 5px;"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/4016467018/" title="Biryani by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3495/4016467018_1d17e5dec9.jpg" width="500" height="334" alt="Biryani" border="0" style="border: solid #cccccc 1px; padding: 5px;"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-1927703785520232226?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/1927703785520232226/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=1927703785520232226' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1927703785520232226'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/1927703785520232226'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2009/10/bye-munich-and-d2.html' title='bye munich (and D2)'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2610/4016467020_a2768d3556_t.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-5584330780890543480</id><published>2009-10-13T12:26:00.005+02:00</published><updated>2009-10-13T12:41:36.558+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='munich'/><category scheme='http://www.blogger.com/atom/ns#' term='travel'/><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='devdays'/><category scheme='http://www.blogger.com/atom/ns#' term='effect'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><title type='text'>Qt Developer Days 2009 - Live</title><content type='html'>&lt;p&gt;Like &lt;a href="http://ariya.blogspot.com/2009/10/bye-amsterdam-next-stop-munich.html"&gt;I mentioned before&lt;/a&gt;, now I am in Munich for Qt Developer Days 2009. The training sessions started yesterday already, the plenary was initiated this morning as we had &lt;a href="http://qt.nokia.com/qtdevdays2009/agenda#general-sessions-keynotes"&gt;the keynotes&lt;/a&gt; from Sebastian, Lars, Walter, and Matthias. We are now in the middle of lunch break, the technical track will start very soon.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/N1oZZpGcFUA2tX5V8XWf6Q?authkey=Gv1sRgCLqSjOHtuvSBMA&amp;feat=embedwebsite"&gt;&lt;img src="http://lh3.ggpht.com/_Oijhf1ZPv-4/StRV7HhOEEI/AAAAAAAABY0/vB5SdnMpfKY/s400/2009-10-13%2009.22.34.jpg" border="0" alt="Qt Everywhere"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the biggest Qt Developer Days so far, we have over 650 participants (&lt;a href="http://ariya.blogspot.com/2008/10/bye-munich-see-you-in-us.html"&gt;last year&lt;/a&gt; it was only around 400). Can you imagine now what happens during the lunch break? Hint: the queue. As a nice touch, we even show a coffee machine running Qt:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/8ooMswIyq-MagQ-jvSo_3g?authkey=Gv1sRgCLqSjOHtuvSBMA&amp;feat=embedwebsite"&gt;&lt;img src="http://lh3.ggpht.com/_Oijhf1ZPv-4/StRXtdD5AjI/AAAAAAAABY8/W-pxjpODyOY/s400/2009-10-13%2011.34.44.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I will have two talks tomorrow (Day 2) for the &lt;a href="http://qt.nokia.com/qtdevdays2009/qt-technical-sessions#innovate"&gt;Innovate track&lt;/a&gt;: &lt;b&gt;Special FX with Graphics View&lt;/b&gt; and &lt;b&gt;Copy Your Favourite Nokia App with Qt&lt;/b&gt;. See you there!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-5584330780890543480?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/5584330780890543480/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=5584330780890543480' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/5584330780890543480'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/5584330780890543480'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2009/10/qt-developer-days-2009-live.html' title='Qt Developer Days 2009 - Live'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh3.ggpht.com/_Oijhf1ZPv-4/StRV7HhOEEI/AAAAAAAABY0/vB5SdnMpfKY/s72-c/2009-10-13%2009.22.34.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-8965128976765663206</id><published>2009-10-11T10:53:00.001+02:00</published><updated>2009-10-11T10:54:38.504+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photo'/><category scheme='http://www.blogger.com/atom/ns#' term='travel'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='amsterdam'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><category scheme='http://www.blogger.com/atom/ns#' term='food'/><title type='text'>bye amsterdam. next stop: munich</title><content type='html'>&lt;p&gt;Today is the last day of &lt;a href="http://wiki.maemo.org/Maemo_Summit_2009"&gt;Maemo Summit 2009&lt;/a&gt;. I am sure the news spreads quickly; everyone and his uncle know already that Nokia lends around 300 shiny &lt;a href="http://maemo.nokia.com/n900/"&gt;N900&lt;/a&gt; (preproduction devices), worth 500 EUR, to the summit participants, excluding Nokia employees and contractors. It's Christmas in Amsterdam!&lt;/p&gt;

&lt;p&gt;I had done my &lt;a href="http://wiki.maemo.org/Maemo_Summit_2009/Schedule/Day_1#Cross-platform_with_Qt_-_live"&gt;Cross Platform with Qt&lt;/a&gt; talk, I was quite content with it (that hopelessly small room was jam-packed). There were (and still will be) many &lt;a href="http://wiki.maemo.org/Maemo_Summit_2009/Schedule"&gt;other interesting tracks&lt;/a&gt; as well. For the detailed coverage, check out &lt;a href="http://www.allaboutmaemo.com"&gt;All About Maemo&lt;/a&gt; site, they are doing great jobs keeping the rest of the world up-to-date with the latest excitements from WesterGasFabriek.&lt;/p&gt;

&lt;p&gt;While waiting in &lt;a href="http://en.wikipedia.org/wiki/Amsterdam_Airport_Schiphol"&gt;Schiphol&lt;/a&gt; for my next flight to Munich (for &lt;a href="http://ariya.blogspot.com/2009/07/2009-developer-days.html"&gt;Qt Developer Days 2009&lt;/a&gt;), I had a quick glance at some of photos taken in the last few days. Let me just post one:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/4000606252/" title="Nasi Rames by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2642/4000606252_56b58bb6b2.jpg" width="500" height="333" alt="Nasi Rames"  border="0" style="border: solid #cccccc 1px; padding: 5px;"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One evening, we picked Restaurant Sari Citra for our dinner. It serves Indonesian cuisine, the proof is the picture above. You have the choice to &lt;a href="http://en.wikipedia.org/wiki/Nasi_Campur"&gt;mix your own rice dish&lt;/a&gt;, such &lt;a href="http://en.wikipedia.org/wiki/Nasi_kuning"&gt;Nasi Kuning&lt;/a&gt; (rice with coconut milk and turmeric) with &lt;a href="http://en.wikipedia.org/wiki/Tempeh"&gt;Tempe Kering&lt;/a&gt; (slices of fried, crispy tempe mixed with peanuts), &lt;a href="http://id.wikipedia.org/wiki/Perkedel"&gt;Perkedel Kentang&lt;/a&gt; (mashed potato fritters) along with a wide selection of vegetables. Authentic experience with a reasonable price. Everyone enjoyed the dinner; happy Trolls :)&lt;/p&gt;

&lt;p&gt;And see you in Munich!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-8965128976765663206?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/8965128976765663206/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=8965128976765663206' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8965128976765663206'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/8965128976765663206'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2009/10/bye-amsterdam-next-stop-munich.html' title='bye amsterdam. next stop: munich'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2642/4000606252_56b58bb6b2_t.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-4407254402953406753</id><published>2009-10-09T10:44:00.000+02:00</published><updated>2009-10-09T10:45:34.489+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='travel'/><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='amsterdam'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>Maemo Summit 2009 - Live</title><content type='html'>&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/UUBxW5DBZ8ZErYAn213Ayw?authkey=Gv1sRgCLqSjOHtuvSBMA&amp;feat=embedwebsite"&gt;&lt;img src="http://lh5.ggpht.com/_Oijhf1ZPv-4/Ss72-SkR42I/AAAAAAAABYY/oiZpJnM5_bw/s400/2009-10-09%2010.39.40.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Like &lt;a href="http://ariya.blogspot.com/2009/09/maemo-summit-2009-amsterdam-9-11-oct.html"&gt;mentioned before&lt;/a&gt;, with other few Trolls, we are now in Amsterdam for the &lt;a href="http://wiki.maemo.org/Maemo_Summit_2009"&gt;Maemo Summit 2009&lt;/a&gt;. If you are there, don't forget to look for us and/or drop us a visit!&lt;/p&gt;

&lt;p&gt;&lt;img src="http://wiki.maemo.org/images/0/00/Ms09-logo_05b2.png" alt="Maemo Summit 2009"/&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-4407254402953406753?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/4407254402953406753/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=4407254402953406753' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/4407254402953406753'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/4407254402953406753'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2009/10/maemo-summit-2009-live.html' title='Maemo Summit 2009 - Live'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh5.ggpht.com/_Oijhf1ZPv-4/Ss72-SkR42I/AAAAAAAABYY/oiZpJnM5_bw/s72-c/2009-10-09%2010.39.40.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-4286576749235615403</id><published>2009-10-07T08:38:00.001+02:00</published><updated>2009-10-07T08:41:32.825+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='photo'/><category scheme='http://www.blogger.com/atom/ns#' term='food'/><title type='text'>webkit dinner: gado-gado + nasi uduk</title><content type='html'>&lt;a href="http://www.flickr.com/photos/ariyahidayat/3987547555/" title="Nasi Uduk by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2612/3987547555_2db9031d63.jpg" width="500" height="334" alt="Nasi Uduk" border="0" style="border: solid #cccccc 1px; padding: 5px;"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Something I can always be proud of is to be part of the Nokia &lt;a href="http://qt.nokia.com/doc/qtwebkit.html"&gt;QtWebKit&lt;/a&gt; team. The fact that we are all the WebKit reviewers from Nokia (at the moment, surely the situation will improve in the future) is one thing, but most important is that the team is small and agile, and it comprises great hackers. You surely already hear a lot from &lt;a href="http://labs.qt.nokia.com/blogs/author/simon"&gt;Simon&lt;/a&gt;, &lt;a href="http://labs.qt.nokia.com/blogs/author/tavestbo"&gt;Tor Arne&lt;/a&gt;, and &lt;a href="http://labs.qt.nokia.com/blogs/author/kent"&gt;Kent&lt;/a&gt; these days, and you will hear from the new blood pretty soon, too.&lt;/p&gt;

&lt;p&gt;The least we can do for such great coworkers is to offer them a bit of culinary journey to our culture. Hence, the so-called &lt;i&gt;WebKit dinner&lt;/i&gt;. As much as I love Italian food, &lt;a href="http://ariya.blogspot.com/2008/10/lamb-pizza.html"&gt;such as pizza&lt;/a&gt;, it's also time for a change.&lt;/p&gt;

&lt;p&gt;The starter was &lt;a href="http://en.wikipedia.org/wiki/Gado-gado"&gt;Gado-gado&lt;/a&gt;, which is just vegetable salad served with peanut sauce as the dressing. The main dish consisted of fish curry (generously contributed by Kavindra) and &lt;a href="http://en.wikipedia.org/wiki/Uduk_(cuisine)"&gt;Nasi Uduk&lt;/a&gt;. The latter, which is shown in the photo above, is rice cooked with (among others) coconut milk served with sliced omelette, fried tofu, chicken, fish, and vegetables. A lot of other slight variations also exist. Original (from Sidoarjo) prawn crackers, aka &lt;a href="http://en.wikipedia.org/wiki/Krupuk"&gt;Krupuk&lt;/a&gt;, completed the experience.&lt;/p&gt;

&lt;p&gt;Dessert? Not forgotten. It was basically just fresh waffles (like &lt;a href="http://ariya.blogspot.com/2008/09/fresh-waffle.html"&gt;I blogged before&lt;/a&gt;) served with the sauce made from brown sugar and coconut milk. Let's say it's the European interpretation of &lt;a href="http://en.wikipedia.org/wiki/Serabi"&gt;Serabi&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Tasty. What else does a man want?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-4286576749235615403?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/4286576749235615403/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=4286576749235615403' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/4286576749235615403'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/4286576749235615403'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2009/10/webkit-dinner-gado-gado-nasi-uduk.html' title='webkit dinner: gado-gado + nasi uduk'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2612/3987547555_2db9031d63_t.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-5760760162731873738</id><published>2009-10-06T08:30:00.000+02:00</published><updated>2009-10-06T08:31:17.145+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='madrid'/><category scheme='http://www.blogger.com/atom/ns#' term='photo'/><category scheme='http://www.blogger.com/atom/ns#' term='travel'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='vacation'/><category scheme='http://www.blogger.com/atom/ns#' term='lisbon'/><category scheme='http://www.blogger.com/atom/ns#' term='paris'/><category scheme='http://www.blogger.com/atom/ns#' term='food'/><title type='text'>paris lisbon madrid</title><content type='html'>&lt;p&gt;Finally I had a real vacation, albeit short. Like many typical holidaymakers, I decided to do a little tour passing three selected cities in Europe, at the same time also using the chance to practice light, one-bag travelling (with a great success, mind you!).&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/3984359631/" title="Église Saint-Eustache, Paris by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2516/3984359631_48b127bbc0.jpg" width="500" height="333" alt="Église Saint-Eustache, Paris" border="0" style="border: solid #cccccc 1px; padding: 5px;"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://wikitravel.org/en/Paris"&gt;Paris&lt;/a&gt; can always make a good start. The target at this second visit to Paris was to enjoy it at night. After all, it is supposed to be &lt;i&gt;la Ville Lumière&lt;/i&gt; (City of Light). However, a long walking tour during the day was still inevitable, as evidenced from the picture of &lt;a href="http://en.wikipedia.org/wiki/Église_Saint-Eustache,_Paris"&gt;Église Saint-Eustache&lt;/a&gt; above.&lt;/p&gt;

&lt;a href="http://www.flickr.com/photos/ariyahidayat/3984359609/" title="Nasi Goreng by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2496/3984359609_0eeccd089a.jpg" width="500" height="334" alt="Nasi Goreng"  border="0" style="border: solid #cccccc 1px; padding: 5px;"/&gt;&lt;/a&gt;

&lt;p&gt;As for the food, we decided to try non-local cuisine instead. We dined at the nicely-decorated &lt;a href="http://www.restaurant-indonesia.com"&gt;Restaurant Indonesia&lt;/a&gt;, one of two restaurants in Paris (the other one is &lt;a href="http://www.djakarta-bali.com/"&gt;Djakarta-Bali&lt;/a&gt;) serving authentic culinary experience from my home country. If you happen to be nearby, give it a try as the dishes were good and reasonably priced.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/3985375602/" title="on the way to Castle St George, Lisbon by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3490/3985375602_b53be6e361.jpg" width="500" height="333" alt="on the way to Castle St George, Lisbon" border="0" style="border: solid #cccccc 1px; padding: 5px;"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://wikitravel.org/en/Lisbon"&gt;Lisbon&lt;/a&gt; is fabulous and rich with history. We managed to explore the downtown area on foot, enjoying the busy &lt;a href="http://en.wikipedia.org/wiki/Marquis_of_Pombal_Square"&gt;Marquês de Pombal&lt;/a&gt;, even walking up to the &lt;a href="http://en.wikipedia.org/wiki/Castle_of_São_Jorge"&gt;Castelo de São Jorge&lt;/a&gt;. However I feel that exploring the surrounding would have been much better with a car. The view of Lisbon from the castle was majestic, also from the dozens of the short alleys on the way up there (the photo above). Of course, passing &lt;a href="http://en.wikipedia.org/wiki/25_de_Abril_Bridge"&gt;Ponte 25 de Abril&lt;/a&gt; - the sister bridge of San Francisco's Golden Gate - both on the motorway and using the train, was also a wonderful experience. Due to our limited time, we had to skip some other tourist attractions. We already compiled a list of must-visit places for the future, in case we fly to Lisbon again.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/3985463830/" title="the lucky takes them all by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2594/3985463830_1873e19791.jpg" width="500" height="334" alt="the lucky takes them all" border="0" style="border: solid #cccccc 1px; padding: 5px;"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nevertheless we had the obligatory fantastic dinner with &lt;a href="http://en.wikipedia.org/wiki/Cod"&gt;cod&lt;/a&gt;. In another occasion, a simplistic but enjoyable dinner buffet in a &lt;a href="http://en.wikipedia.org/wiki/Churrascaria"&gt;Churrascaria&lt;/a&gt; was also memorable. A short detour to the beach at midnight completed the unforgettable journey.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/3984688769/" title="Plaza de Toros, Madrid by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2555/3984688769_102077b34b.jpg" width="500" height="333" alt="Plaza de Toros, Madrid" border="0" style="border: solid #cccccc 1px; padding: 5px;"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://wikitravel.org/en/Madrid"&gt;Madrid&lt;/a&gt; was very vibrant and dynamic. It is also quite  warm (as expected) with the heat at noon being close to unbearable. I like the fact that it was still possible, even convenient, to sit on a bench even somewhere in downtown as long as it is still in the shadow. Unfortunately Madrid was &lt;a href="http://en.wikipedia.org/wiki/Madrid_bid_for_the_2016_Summer_Olympics"&gt;defeated by Rio&lt;/a&gt; in the race for the &lt;a href="http://en.wikipedia.org/wiki/2016_Summer_Olympics"&gt;2016 Summer Olympics host&lt;/a&gt;. Otherwise it would have been extremely fantastic as we were there after the last round.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/ariyahidayat/3984688749/" title="Chocolate con Churros by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2572/3984688749_b6888b62ec.jpg" width="500" height="333" alt="Chocolate con Churros" border="0" style="border: solid #cccccc 1px; padding: 5px;"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We did the usual sightseeing (on foot) - including the compulsory visit to &lt;a href="http://en.wikipedia.org/wiki/Palacio_Real"&gt;Palacio Real&lt;/a&gt; - and other usual rituals: having &lt;a href="http://en.wikipedia.org/wiki/Churro"&gt;chocolate con churros&lt;/a&gt; for breakfast, drinking &lt;a href="http://en.wikipedia.org/wiki/Horchata"&gt;horchata&lt;/a&gt; to ease from the heat at midday, as well as eating traditional &lt;a href="http://en.wikipedia.org/wiki/Paella"&gt;paella&lt;/a&gt; (and &lt;a href="http://en.wikipedia.org/wiki/Fideuà"&gt;fidueà&lt;/a&gt;) for the (very!) late dinner.&lt;/p&gt;

&lt;p&gt;Madrid at night on the other hand is a bit problematic for me. Since I am not a nightlife type, I don't drink, and I can't stand the cigarette smoke, touring the city after sunset is practically a mild torture.&lt;/p&gt;

&lt;p&gt;Next to visit (due in few days): Amsterdam and Munich.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-5760760162731873738?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/5760760162731873738/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=5760760162731873738' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/5760760162731873738'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/5760760162731873738'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2009/10/paris-lisbon-madrid.html' title='paris lisbon madrid'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2516/3984359631_48b127bbc0_t.jpg' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-531950188006243160</id><published>2009-09-27T16:18:00.001+02:00</published><updated>2009-09-27T16:18:52.394+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='travel'/><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='amsterdam'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='maemo'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>Maemo Summit 2009, Amsterdam, 9-11 Oct</title><content type='html'>&lt;p&gt;&lt;img src="http://wiki.maemo.org/images/0/00/Ms09-logo_05b2.png" alt="Maemo Summit 2009"/&gt;&lt;/p&gt;

&lt;p&gt;Another exciting event coming up soon: &lt;a href="http://wiki.maemo.org/Maemo_Summit_2009"&gt;Maemo Summit 2009&lt;/a&gt;! This time it will be in &lt;a href="http://wikitravel.org/en/Amsterdam"&gt;Amsterdam&lt;/a&gt;. My flight ticket is secured already, I look forward to it. And of course, since this will be also my first visit to Amsterdam.&lt;/p&gt;

&lt;p&gt;My talk will be on Friday afternoon, see the &lt;a href="http://wiki.maemo.org/Maemo_Summit_2009/Schedule"&gt;schedule&lt;/a&gt; for details. Although the title &amp;quot;Cross-platform with Qt&amp;quot; is a bit boring, rest assured you will see showcases of many things (which I can pack in 25 minutes) Qt is capable of doing.&lt;/p&gt;

&lt;p&gt;A few other Trolls will be there as well so go there and find us. In all cases, if you are around and want to have a chat, drop me an email (ariya.hidayat AT gmail DOT com).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-531950188006243160?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/531950188006243160/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=531950188006243160' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/531950188006243160'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/531950188006243160'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2009/09/maemo-summit-2009-amsterdam-9-11-oct.html' title='Maemo Summit 2009, Amsterdam, 9-11 Oct'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-7004929244320930679</id><published>2009-09-27T09:28:00.000+02:00</published><updated>2009-09-27T09:29:40.231+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='photo'/><category scheme='http://www.blogger.com/atom/ns#' term='food'/><title type='text'>a moment, a love, a dream, a laugh, a kiss, a cry</title><content type='html'>&lt;a href="http://www.flickr.com/photos/ariyahidayat/3958219876/" title="pizza (again) by Ariya Hidayat, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2477/3958219876_824a069925.jpg" width="500" height="333" alt="pizza (again)"   style="border: solid #cccccc 1px; padding: 5px;"/&gt;&lt;/a&gt;

&lt;p&gt;Seems autumn always calls for my service, hence the usual pizza-baking obligation, as evidenced from the photo. Recipe? Check what &lt;a href="http://ariya.blogspot.com/2008/10/lamb-pizza.html"&gt;I have posted last year&lt;/a&gt;. A slight variation: slices of pineapples :)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-7004929244320930679?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/7004929244320930679/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=7004929244320930679' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/7004929244320930679'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/7004929244320930679'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2009/09/moment-love-dream-laugh-kiss-cry.html' title='a moment, a love, a dream, a laugh, a kiss, a cry'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2477/3958219876_824a069925_t.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-4370025611297680136</id><published>2009-09-23T10:48:00.000+02:00</published><updated>2009-09-23T10:50:51.843+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hacks'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='s60'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>frozen in the headlights (have I made the final sacrifice?)</title><content type='html'>&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/t-cu5RW6ZiJo_KZWIB3cfw?feat=embedwebsite"&gt;&lt;img src="http://lh4.ggpht.com/_Oijhf1ZPv-4/Srjh6qqR-2I/AAAAAAAABXA/kV4L2ClVxNU/s800/raycasting.png" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This slick stuff is mostly educational (for the lazy, see the &lt;a href="http://www.youtube.com/watch?v=FcIe9EPmqGs"&gt;30-second YouTube video&lt;/a&gt; courtesy of &lt;a href="http://labs.qt.nokia.com/blogs/author/aportale"&gt;Alessandro&lt;/a&gt;). With all the accelerated graphics (with those alphabet soups) these days, who on earth uses &lt;a href="http://en.wikipedia.org/wiki/Raycasting"&gt;ray casting&lt;/a&gt; for real-world apps? Nevertheless, since I still keep the piece of code (read: a function, literally) I wrote ages ago, why not giving it a try again?&lt;/p&gt;

&lt;p&gt;Testing it on &lt;a href="http://en.wikipedia.org/wiki/Nokia_E71"&gt;Nokia E71&lt;/a&gt; (powered by ARM 369 MHz processor), I am content to get a consistent 25 fps at QVGA resolution (and the code is still portable!). I reckon I need to resort to platform-specific, e.g. &lt;a href="http://wiki.forum.nokia.com/index.php/Anti-tearing_with_CDirectScreenBitmap"&gt;Anti Tearing API&lt;/a&gt; for S60, if I want to push the frame rate further.&lt;/p&gt;

&lt;p&gt;For the code and the explanation, head to the &lt;a href="http://labs.qt.nokia.com/blogs/2009/08/09/ray-casting-on-qts60/"&gt;S60 ray casting demo&lt;/a&gt;. You would need the &lt;a href="http://labs.qt.nokia.com/blogs/2009/06/25/the-new-pre-release-of-qt-for-s60-is-there/"&gt;Qt 4.5 Tower release&lt;/a&gt; to build it for your favorite phone. Also, you need a four-way controller as I haven't bothered to let it run on a touch device.&lt;/p&gt;

&lt;p&gt;Final (friendly) reminder: use &lt;a href="http://www.dwheeler.com/sloccount/"&gt;sloccount&lt;/a&gt; and check yourself how long this example is. Why? Because usually people think I try to trick them when I reveal the size of the source code :)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-4370025611297680136?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/4370025611297680136/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=4370025611297680136' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/4370025611297680136'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/4370025611297680136'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2009/09/frozen-in-headlights-have-i-made-final.html' title='frozen in the headlights (have I made the final sacrifice?)'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_Oijhf1ZPv-4/Srjh6qqR-2I/AAAAAAAABXA/kV4L2ClVxNU/s72-c/raycasting.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-2088708970963016295</id><published>2009-09-20T07:43:00.002+02:00</published><updated>2009-09-20T07:43:55.022+02:00</updated><title type='text'>Eid Mubarak</title><content type='html'>&lt;p&gt;Happy &lt;b&gt;Eid Al-Fitr&lt;/b&gt; to all !&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-2088708970963016295?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/2088708970963016295/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=2088708970963016295' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2088708970963016295'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2088708970963016295'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2009/09/eid-mubarak.html' title='Eid Mubarak'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-2317923021954493833</id><published>2009-09-11T12:17:00.002+02:00</published><updated>2009-09-11T21:05:34.150+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='svg'/><category scheme='http://www.blogger.com/atom/ns#' term='tip'/><category scheme='http://www.blogger.com/atom/ns#' term='qt'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='optimization'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><category scheme='http://www.blogger.com/atom/ns#' term='coding'/><title type='text'>SVG: parsing and content optimization</title><content type='html'>&lt;p&gt;A few weeks ago, just for a change (between the usual &lt;a href="http://qt.nokia.com/doc/qtwebkit.html"&gt;QtWebKit&lt;/a&gt; bug-fixing and patches juggling), I did take a look at our &lt;a href="http://qt.nokia.com/doc/qtsvg.html"&gt;QtSvg module&lt;/a&gt;. According to some internal reports, QtSvg is not fast enough when parsing a large and complicated SVG. Of course, slow is relative, slow &lt;i&gt;to what&lt;/i&gt;. And arguably, parsing time is not as important as rendering time. But if you stash your user-interface elements in some sort of SVG theme, loading time becomes a factor (caching the pixmaps whenever possible also helps). Of course, reduced size served in a web server can decrease the bandwidth as well (think of all the SVGs in Wikipedia).&lt;/p&gt;

&lt;p&gt;Still, I decided to have a look, just in case there are low-hanging fruits I can grab. And I was right, &lt;i&gt;far&lt;/i&gt; from being an SVG expert, with just two days of work I managed to squeeze its performance a bit, which you'd enjoy already in the &lt;a href="http://labs.qt.nokia.com/blogs/2009/09/09/qt-460-tech-preview-1/"&gt;recent 4.6 preview&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/cB6SPdhyThvfwYL3fMMrCA?feat=embedwebsite"&gt;&lt;img src="http://lh6.ggpht.com/_Oijhf1ZPv-4/Sqod3XTKV8I/AAAAAAAABVk/S1UTOyBZVMU/s800/benchmark-svg-46-theme.png" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The chart above - &lt;i&gt;shorter is better&lt;/i&gt; - represents the comparison of the time spent in &lt;a href="http://qt.nokia.com/doc/qsvgrenderer.html#load-2"&gt;QSvgRenderer::load()&lt;/a&gt;, measured using &lt;a href="http://qt.nokia.com/doc/qtestlib-manual.html#creating-a-benchmark"&gt;CPU tick counter&lt;/a&gt; (in millions of ticks), comparing Qt 4.5 and 4.6. I also tested some other files as well, see &lt;a href="http://picasaweb.google.com/ariya.hidayat/Screenshots#5379916025148275202"&gt;the bigger bar charts&lt;/a&gt;. In all measurements, the 95% &lt;a href="http://en.wikipedia.org/wiki/Confidence_interval"&gt;confidence intervals&lt;/a&gt; were well below 1%. &lt;i&gt;In-house Theme&lt;/i&gt; refers to an internal SVG that unfortunately I can't share. &lt;i&gt;Tiger&lt;/i&gt; is the SVG version of the famous head in PostScript (taken from GNU GhostScript), something &lt;a href="http://ariya.blogspot.com/2008/08/svg-to-png-using-qtwebkit.html"&gt;I have shown before&lt;/a&gt;. &lt;i&gt;Imperial Coat&lt;/i&gt; of Arms of France is another complex SVG, from &lt;a href="http://commons.wikimedia.org/wiki/File:Imperial_Coat_of_Arms_of_France_(1804-1815).svg"&gt;Wikipedia Commons&lt;/a&gt;. &lt;i&gt;World Map&lt;/i&gt; is the public domain blank grayscale &lt;a href="http://en.wikipedia.org/wiki/File:BlankMap-World6.svg"&gt;world map&lt;/a&gt; from Wikipedia. There are a bunch of other test files I used, they mostly show the same improvements.&lt;/p&gt;

&lt;p&gt;As you can see, Qt 4.6 would enjoy a bit of speed-up (in some cases up to 1.4x) when loading and parsing SVG.&lt;/p&gt;

&lt;p&gt;However, I did not stop there. For the fun of it, I quickly hacked a Qt-based, command line SVG minifier, dubbed &lt;a href="http://svgmin.googlecode.com"&gt;SVGMin&lt;/a&gt;. More about it can be read in the detailed &lt;a href="http://code.google.com/p/svgmin/wiki/QuickStart"&gt;Quick Start&lt;/a&gt;, but basically it tries to eliminate redundant garbages which have no effect whatsoever in the final rendering.&lt;/p&gt;

&lt;p&gt;What follows is the chart showing the same type of measurement but I added the result with the minified SVG (see also &lt;a href="http://picasaweb.google.com/ariya.hidayat/Screenshots#5379916026734960098"&gt;the full comparison chart&lt;/a&gt;). The result should speak for itself:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://picasaweb.google.com/lh/photo/0qrF-kdbY-j3MNJRDkK6yw?feat=embedwebsite"&gt;&lt;img src="http://lh4.ggpht.com/_Oijhf1ZPv-4/Sqoer9QWxXI/AAAAAAAABVs/pBBj7PGNPdg/s800/benchmark-svg-minified-theme.png" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I plan some more improvements to the SVG minifier, for example collapsing a single grouped element (&amp;lt;g&amp;gt;&amp;lt;path ...&amp;gt;&amp;lt;/g&amp;gt; makes no sense), group a bunch of nodes with similar attributes (no need to duplicate the same fill colors over 100 circles), remove useless attributes (why there is fill-* for fill:none?), and many others. Hold your breath.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-2317923021954493833?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/2317923021954493833/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=2317923021954493833' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2317923021954493833'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/2317923021954493833'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2009/09/svg-parsing-and-content-optimization.html' title='SVG: parsing and content optimization'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/_Oijhf1ZPv-4/Sqod3XTKV8I/AAAAAAAABVk/S1UTOyBZVMU/s72-c/benchmark-svg-46-theme.png' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17722541.post-5973729610540828609</id><published>2009-09-08T21:46:00.001+02:00</published><updated>2009-09-08T22:33:17.482+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='musing'/><title type='text'>the game of escalation</title><content type='html'>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/yolla/3064358246/" title="img_0086 by Yolla Indria, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3023/3064358246_7f056caa69.jpg" alt="img_0086" style="border: 1px solid rgb(204, 204, 204); padding: 5px;" height="333" width="500" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Often I ask myself how long I would still want to stay in the software industry. Before I started my professional programming career, I never thought that this wonderful world of software craftsmanship is full of complaints, frustration, anger, and hostility. Perhaps that is just the reflection of people wanting to achieve the best things they can do. When you aim for a perfection, anything &lt;i&gt;good enough&lt;/i&gt; will not be satisfactory.&lt;/p&gt;

&lt;p&gt;I can't say for sure, but somehow I feel that I am still heavily influenced by the positive gratitude mentality, even in the case of calamity. When you have an accident and your right arm is amputated, someone reminds you, &amp;quot;You are lucky, you could have lost your legs!&amp;quot;. Losing an arm is considered lucky? This does not mean that we bury our head in the sand and forget the fact that one arm is gone already, it just means that we should not be blind to the fact that things could have been worse. By doing so hopefully we keep things in perspective and move forwards as positive and as best as we can.&lt;/p&gt;

&lt;p&gt;One of the lessons I learned so far is the amount of extrapolated verdicts you would get from the users, the developers, and/or the customers. Any bugs, any annoyances, no matter how small it is, are sometimes blown out of proportion. I call this the &lt;i&gt;Universal Rule of Blaming&lt;/i&gt;. A customer complains, the company desperately grabs a consultant to help, he finds the bug in the toolkit, the toolkit guy chains it further to the operating systems, and so on. Of course, for each stage, the amount of anger and loudness of the screams increase exponentially. Basically, nobody wants to be the escape goat.&lt;/p&gt;&lt;p&gt;

&lt;p&gt;Sadly, everyone in the business of doing software seems to forget that making a software is just like another engineering project. It has its constraints, the resources are limited, the time is the (common) enemy, priorities must be set, and practically it is impossible to achieve 100% perfectness. It is the classic optimization problems. Thus, the responsible people have to make some decisions and these decisions can't please everyone. There will be people alienated with such decisions. Anyone ever done any kind of sensible business knows exactly what it does mean. Every customer feels that he is important (I mean, who does not?), yet a typical company has a lot of customers and such a company is always ready to disappoints 10% of the customers, rather than 90%.  As you can guess, it is a matter of minimizing the loss. When a business guy asks his customers, &amp;quot;Hey, I need your feedback&amp;quot; and he really means it, he is not trying to be nice, he is trying to save his business.&lt;/p&gt;

&lt;p&gt;However, my concern is not on the technical matters, but rather the non-technical side. When you are angry, you may say some words that you may regret later. Unfortunately, getting mad because of software annoyances can trap you in the same, if not worse, situation. What I often witness is that people start guessing, accusing, throwing blames, up to the a point where it becomes counter-productive and getting personal. You all know what happens when a developer takes it personally: a cycle of violence is about to roll. Once a while I try to stand in the line of fire (a big mistake, I know) in order to bridge both parties. No luck, it is like being trapped in a DMZ and people will just release their steam and waste their bullets to me as if they are happy to find a new bandito to kill. Ever wonder why some developers take the holy vow of silence?&lt;/p&gt;

&lt;p&gt;The most common case is the why-my-bug-is-not-fixed drama. For example if I do not fix the problem X on the platform Y, people might start rambling on anything from &amp;quot;you secretly plan to drop support for Y&amp;quot; to &amp;quot;you rather focus only on feature Z instead of fixing X&amp;quot;. There are various reasons I still do not manage to provide you the fix, but because of the frustration, people tend to invent and believe in some kind of conspiracy theory. Feel free to write a long Pulitzer-quality editorial on why the lack of the fix destroys your million dollar business, but no need to cross the line and start imagining things.&lt;/p&gt;

&lt;p&gt;The drama can continue in a developer conference, where a guy might ask a simple, seemingly innocent question (even in a keynote speech) such as &amp;quot;Why don't you fix (my) bug 123? Why do you work on feature 456 instead?&amp;quot;. Believe me, I saw that happened many many time. Those questions will put both the speaker and the audience in a awkward situation. While I fully agree that every bugs must be fixed, throwing such a question which only has the intention of embarrassing the developer in front of everyone is way too dirty for my taste (not to mention that, like often the case, our poor little developer never took any &lt;i&gt;How to Deal with Angry Customers&lt;/i&gt; course). In fact, every time I encounter this kind of scene, I make a mental note to stay away from that guy. And I am sure I am not the only one who is doing that. Like I often expressed, &lt;i&gt;we are not in the kindergarten anymore, screaming does not make the solution comes faster&lt;/i&gt;. Time to make a ThinkGeek T-shirt for that?&lt;/p&gt;

&lt;p&gt;Thus, I reached a conclusion that there are two types of software guys: those who symphatize with the difficulties and problems of delivering a perfect product (because they are trying to do the same, &amp;quot;Welcome to the club!&amp;quot;) and those who just like to shift the blames to others (because they get customers banging their doors). Nobody likes to deal with angry customers so the choice is (not) hard: either you take the blame (after all, &lt;i&gt;you&lt;/i&gt; are the one who is doing the direct business to your customers) or you pass it along (every one of us is a customer of someone else's product). In the latter case, you just become yet another angry customer.&lt;/p&gt;

&lt;p&gt;Noblesse oblige.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17722541-5973729610540828609?l=ariya.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ariya.blogspot.com/feeds/5973729610540828609/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=17722541&amp;postID=5973729610540828609' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/5973729610540828609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17722541/posts/default/5973729610540828609'/><link rel='alternate' type='text/html' href='http://ariya.blogspot.com/2009/09/game-of-escalation.html' title='the game of escalation'/><author><name>Ariya Hidayat</name><uri>http://www.blogger.com/profile/03121582140059106015</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_Oijhf1ZPv-4/SX4qsCgOeqI/AAAAAAAAAzA/s8SeVcvoLEA/S220/head.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3023/3064358246_7f056caa69_t.jpg' height='72' width='72'/><thr:total>9</thr:total></entry></feed>
