<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;D08BQHcyfSp7ImA9WhBWFUU.&quot;"><id>tag:blogger.com,1999:blog-3365890222783870731</id><updated>2013-04-10T11:24:11.995+02:00</updated><category term="writings" /><category term="technology" /><category term="personal" /><category term="photography" /><category term="software" /><category term="latex" /><category term="programming" /><category term="thoughts" /><title>The Typethinker</title><subtitle type="html">Trying to make sense</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://typethinker.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://typethinker.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Thomas ten Cate</name><uri>http://www.blogger.com/profile/02609144861191873031</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>73</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/typethinker" /><feedburner:info uri="typethinker" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>typethinker</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><entry gd:etag="W/&quot;A0EHRno_fSp7ImA9WhBSEkQ.&quot;"><id>tag:blogger.com,1999:blog-3365890222783870731.post-5799636158944768394</id><published>2013-02-19T19:47:00.002+01:00</published><updated>2013-02-19T19:47:17.445+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-02-19T19:47:17.445+01:00</app:edited><title>Uninstalling old kernels in Ubuntu</title><content type="html">&lt;p&gt;One would think that Ubuntu would be smart enough to remove obsolete kernel packages by itself. One would be wrong.&lt;/p&gt;
&lt;p&gt;I think the Computer Janitor can clean them up but you still have to run that manually. So I prefer the following command:&lt;/p&gt;
&lt;pre&gt;uname -r; sudo apt-get remove $(dpkg --get-selections 'linux-image-*' | grep '\binstall' | head -n-3 | cut -f1)
&lt;/pre&gt;
&lt;p&gt;This removes all kernels except the latest two. It prints the currently running kernel version so you can easily check that it's not removing that one.&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://typethinker.blogspot.com/feeds/5799636158944768394/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3365890222783870731&amp;postID=5799636158944768394" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/5799636158944768394?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/5799636158944768394?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typethinker/~3/YKt6hXL6puo/uninstalling-old-kernels-in-ubuntu.html" title="Uninstalling old kernels in Ubuntu" /><author><name>Thomas ten Cate</name><uri>http://www.blogger.com/profile/02609144861191873031</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://typethinker.blogspot.com/2013/02/uninstalling-old-kernels-in-ubuntu.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEIARHk5cSp7ImA9WhNTGEw.&quot;"><id>tag:blogger.com,1999:blog-3365890222783870731.post-4288251760253772371</id><published>2012-10-21T11:42:00.001+02:00</published><updated>2012-10-21T11:42:25.729+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-10-21T11:42:25.729+02:00</app:edited><title>Turning off the screen saver in Ubuntu</title><content type="html">&lt;p&gt;TL;DR: &lt;code&gt;xset s off&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;That's easy,&amp;rdquo; I could hear you think when you read the title. Well, it took me hours to figure it out. It drove me crazy that I'd have to get up and move the mouse every 10 minutes while watching a movie¹, and I couldn't figure out how to disable this behaviour. And when something takes that much effort, I blog about it so that other people might find the solution more easily.&lt;/p&gt;
&lt;p&gt;Of course you can easily disable the screen saver through the control panel thing. But I'm not using the Gnome panel, so I never know how to get to that GUI in the first place. Also, you may find, like me, that it just &lt;em&gt;does not work&lt;/em&gt; and your screen will still turn black after 10 minutes.&lt;/p&gt;
&lt;p&gt;From the console, you can &lt;a href="http://askubuntu.com/questions/67355/how-do-i-completely-turn-off-screensaver-and-power-management"&gt;disable the screen saver&lt;/a&gt; with:&lt;/p&gt;
&lt;pre&gt;$ gsettings set org.gnome.desktop.screensaver idle-activation-enabled false&lt;/pre&gt;
&lt;p&gt;This probably does the same thing as the check box in the GUI. But for me, it wasn't enough: the screen would &lt;em&gt;still&lt;/em&gt; blank after 10 minutes!&lt;/p&gt;
&lt;p&gt;As it turns out, this is a default built into Xorg itself. Try this:&lt;/p&gt;
&lt;pre&gt;$ xset q
...
Screen Saver:
  prefer blanking:  yes    allow exposures:  yes
  timeout:  600    cycle:  600
...&lt;/pre&gt;
&lt;p&gt;Yep, that's the problem. Once you've found it, the solution is simple:&lt;/p&gt;
&lt;pre&gt;$ xset s off
$ xset q
...
Screen Saver:
  prefer blanking:  yes    allow exposures:  yes
  timeout:  0    cycle:  600
...
&lt;/pre&gt;
&lt;p&gt;This only works until the X server is restarted; put &lt;code&gt;xset s off&lt;/code&gt; in your &lt;code&gt;.xsession&lt;/code&gt; file to make this change permanent.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;¹ At least for some movies. &lt;code&gt;mplayer&lt;/code&gt; disables the screensaver automatically, but Flash doesn't.&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://typethinker.blogspot.com/feeds/4288251760253772371/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3365890222783870731&amp;postID=4288251760253772371" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/4288251760253772371?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/4288251760253772371?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typethinker/~3/GVRTEu83fjk/turning-off-screen-saver-in-ubuntu.html" title="Turning off the screen saver in Ubuntu" /><author><name>Thomas ten Cate</name><uri>http://www.blogger.com/profile/02609144861191873031</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://typethinker.blogspot.com/2012/10/turning-off-screen-saver-in-ubuntu.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMASHcyeSp7ImA9WhJRE0g.&quot;"><id>tag:blogger.com,1999:blog-3365890222783870731.post-1729492854032306983</id><published>2012-07-15T14:55:00.002+02:00</published><updated>2012-07-15T15:20:49.991+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-07-15T15:20:49.991+02:00</app:edited><title>Switching default PulseAudio device when USB microphone is plugged in</title><content type="html">&lt;p&gt;I have a PlayStation Eye for a USB webcam and microphone, which is supposed to be supported by Linux. Unfortunately the microphone won't work until I unplug it and plug it in again after boot.

&lt;p&gt;But the unplugging causes PulseAudio to change its default device back to my on-board sound card, which doesn't have a microphone plugged into it. It won't change the default back to the Eye on its own. Here's a workaround, which took me several hours to develop, and isn't for the faint of heart. But it works now, dammit.

&lt;p&gt;All we need to do is nudge PulseAudio a little via a udev event. First, install the daemon package:

&lt;p&gt;&lt;code&gt;sudo apt-get install daemon&lt;/code&gt;

&lt;p&gt;Then create a new file &lt;code&gt;/etc/udev/rules.d/99-pseye.rules&lt;/code&gt; with the following content (all on one line!):

&lt;p&gt;&lt;code&gt;SUBSYSTEMS=="usb", ATTR{idVendor}=="1415", ATTR{idProduct}=="2000", RUN+="/usr/bin/daemon -- /bin/su thomas -c 'sleep 1 &amp;amp;&amp;amp; /usr/bin/pacmd set-default-source alsa_input.usb-OmniVision_Technologies__Inc._USB_Camera-B4.04.27.1-01-CameraB404271.input-4-channels'"&lt;/code&gt;

&lt;p&gt;OmniVision is apparently the manufacturer of this camera. Reports around the internet have slightly different version numbers; type &lt;code&gt;pacmd list-sources&lt;/code&gt; and use the name of your particular device (which shows up as &lt;code&gt;name: &amp;lt;...&amp;gt;&lt;/code&gt;). You also want to replace &lt;code&gt;thomas&lt;/code&gt; by your own username; this is used to find the running &lt;code&gt;pulseaudio&lt;/code&gt; daemon.

&lt;p&gt;There shouldn't be any need to restart the udev daemon, but if you find otherwise, do &lt;code&gt;sudo restart udev&lt;/code&gt;.

&lt;p&gt;The &lt;code&gt;daemon&lt;/code&gt; command is needed because we need to delay the &lt;code&gt;pacmd&lt;/code&gt; command a bit; if we run it right away, PulseAudio hasn't picked up the new device yet. The trouble is that udev tries very hard to wait for completion of all child processes of the &lt;code&gt;RUN&lt;/code&gt; command before firing its events into userland, so PulseAudio will always get its event only after our script has already finished and failed. Even various combinations of &lt;code&gt;&amp;amp;&lt;/code&gt; and &lt;code&gt;nohup&lt;/code&gt; wouldn't convince udev not to wait, but &lt;code&gt;daemon&lt;/code&gt; does the trick.

&lt;p&gt;If this doesn't work, here are some debugging methods that I used. Try adding &lt;code&gt;-o/tmp/daemon.log&lt;/code&gt; after &lt;code&gt;/usr/bin/daemon&lt;/code&gt; and inspect the output. To watch udev events happen in real time, use &lt;code&gt;udevadm monitor&lt;/code&gt;. Another good source of information is &lt;code&gt;/var/log/syslog&lt;/code&gt;; do &lt;code&gt;tail -f /var/log/syslog | grep pacmd&lt;/code&gt; to filter it. Also check the output of &lt;code&gt;pacmd dump&lt;/code&gt; to see whether the &lt;code&gt;set-default-source&lt;/code&gt; command has taken hold.

&lt;p&gt;Oh, and the upstream PulseAudio people in all their wisdom decided (&lt;a href="https://bugs.freedesktop.org/show_bug.cgi?id=39664" target="_blank"&gt;bug report&lt;/a&gt;) that 4-channel microphones like this one don't deserve to have a default profile, resulting in the message &lt;code&gt;Failed to find a working profile&lt;/code&gt; in &lt;code&gt;/var/log/syslog&lt;/code&gt;. The result is that PulseAudio will retry loading, and retry, and retry &amp;hellip; causing brief and hard to debug system freezes once every minute or so. To make the microphone work at all in Ubuntu 12.04 (&lt;a href="https://bugs.launchpad.net/ubuntu/+source/pulseaudio/+bug/886449" target="_blank"&gt;bug report&lt;/a&gt;), you also have to add the following at the end of &lt;code&gt;/usr/share/pulseaudio/alsa-mixer/profile-sets/default.conf&lt;/code&gt;:

&lt;pre&gt;[Mapping input-4-channels]
device-strings = hw:%f
channel-map = front-left,front-right,rear-left,rear-right
description = 4 Channels Input
direction = input
priority = 5

[Profile input:mic-array]
description = Microphone Array
input-mappings = input-4-channels
priority = 2
skip-probe = yes&lt;/pre&gt;

&lt;p&gt;Then type &lt;code&gt;pulseaudio -k&lt;/code&gt; to reload the daemon (it will be restarted on demand). Yes, this will be overwritten on upgrades. I've found no way to work around that yet.</content><link rel="replies" type="application/atom+xml" href="http://typethinker.blogspot.com/feeds/1729492854032306983/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3365890222783870731&amp;postID=1729492854032306983" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/1729492854032306983?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/1729492854032306983?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typethinker/~3/I6yWHRw3bbo/switching-default-pulseaudio-device.html" title="Switching default PulseAudio device when USB microphone is plugged in" /><author><name>Thomas ten Cate</name><uri>http://www.blogger.com/profile/02609144861191873031</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://typethinker.blogspot.com/2012/07/switching-default-pulseaudio-device.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEMHR38_eip7ImA9WhdQE0g.&quot;"><id>tag:blogger.com,1999:blog-3365890222783870731.post-9147516486240078789</id><published>2011-08-14T22:06:00.001+02:00</published><updated>2011-08-14T22:07:16.142+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-14T22:07:16.142+02:00</app:edited><title>Heathrow runway alternation in Google Calendar</title><content type="html">&lt;p&gt;I moved to London recently, and unfortunately I found out too late that my new flat is &lt;i&gt;right&lt;/i&gt; in the flight path of Heathrow's northern runway, causing quite a bit of overhead noise. However, I noticed that some periods were very quiet (including when I was viewing the flat). Was there some method to this madness?&lt;/p&gt;&lt;p&gt;Turns out, there is. The &lt;a href="http://www.heathrowairport.com/portal/page/Heathrow+noise%5EGeneral%5EWhat+we+do+about+it%5EMeasures+already+in+place%5ERunway+use%5ERunway+alternation/bb67ff6b59b53210VgnVCM10000036821c0a____/448c6a4c7f1b0010VgnVCM200000357e120a____/"&gt;Heathrow runway alternation schedule&lt;/a&gt; is nicely documented on the Heathrow website. Basically: one week has noisy mornings, the next week has noisy afternoons/evenings.&lt;/p&gt;&lt;p&gt;But it's a PDF file, which is only useful for printing and sticking on walls, which is sooooo 2010. So I turned it into a public Google Calendar, for use by myself and anyone else who might be interested. But alas, Google &lt;a href="http://www.google.com/support/forum/p/Calendar/thread?tid=55bc5319154cc24e&amp;amp;hl=en"&gt;removed&lt;/a&gt; the ability to search for public calendars back in 2009, which forces me to post about it here to make it findable.&lt;/p&gt;&lt;p&gt;Here's the ID of this calendar:&lt;br /&gt;
&lt;code&gt;r1846kc94hj3ekk24ueb69151g@group.calendar.google.com&amp;nbsp;&lt;/code&gt;&lt;br /&gt;
Copy this, head over to Google Calendar, and paste it into the box labelled &amp;ldquo;Add a friend&amp;rsquo;s calendar&amp;rdquo;. Simple as that.&lt;/p&gt;&lt;p&gt;That's only for the northern runway, known as 27R (when landing/departing towards the west) or 09L (when landing/departing towards the east). Since landing and departing probably make the same amount of noise, I lumped them all together. If anyone would like a similar thing for the southern runway, let me know and I'll put one together.&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://typethinker.blogspot.com/feeds/9147516486240078789/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3365890222783870731&amp;postID=9147516486240078789" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/9147516486240078789?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/9147516486240078789?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typethinker/~3/7ikEqOdCaj0/heathrow-runway-alternation-in-google.html" title="Heathrow runway alternation in Google Calendar" /><author><name>Thomas ten Cate</name><uri>http://www.blogger.com/profile/02609144861191873031</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://typethinker.blogspot.com/2011/08/heathrow-runway-alternation-in-google.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEAAQHs5fyp7ImA9Wx9bEE8.&quot;"><id>tag:blogger.com,1999:blog-3365890222783870731.post-4291527516229970544</id><published>2011-02-18T11:57:00.001+01:00</published><updated>2011-02-18T11:59:01.527+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-18T11:59:01.527+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="software" /><title>Exporting slices from Inkscape, part 2</title><content type="html">&lt;p&gt;I &lt;a href="http://typethinker.blogspot.com/2010/07/exporting-slices-from-inkscape.html"&gt;previously wrote&lt;/a&gt; about how to export slices from an Inkscape file, using a bash script. Here's a better script, using Python, which doesn't require you to give your slices any special label.&lt;/p&gt;

&lt;p&gt;The new process is as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;First, draw your image as usual.&lt;/li&gt;
&lt;li&gt;Then, add a layer that will hold the slices; name it &lt;code&gt;slices&lt;/code&gt; (this is important). Set the layer's opacity to about 50% to be able to see what you're doing. Enable the grid, and make sure it is set to pixels: you want your slices to align with pixel boundaries.&lt;/li&gt;
&lt;li&gt;Draw your slice rectangles onto the &lt;code&gt;slices&lt;/code&gt; layer, aligned to the grid. Ensure that the rectangles have no border; the fill is irrelevant (I use red).&lt;/li&gt;
&lt;li&gt;Right-click a slice, and choose Object Properties. Change Id field to the name of the eventual PNG file, without the extension. The area defined by a rectangle named &lt;code&gt;foo&lt;/code&gt; will be saved to &lt;code&gt;foo.png&lt;/code&gt;. Repeat this for all slices.&lt;/li&gt;
&lt;li&gt;Hide the slices layer. If you forget this, the script will print a warning.&lt;/li&gt;
&lt;li&gt;Save your image. Let's say you called it &lt;code&gt;layout.svg&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run the script as follows:&lt;br/&gt;
&lt;code&gt;./export.py layout.svg&lt;/code&gt;&lt;br/&gt;
You should see each of your slices being exported to a PNG file in the same directory.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's the code for the script. Save this to a file &lt;code&gt;export.py&lt;/code&gt; and make it executable.&lt;/p&gt;
&lt;pre&gt;
#!/usr/bin/env python

import sys
import os
from xml.dom import minidom

if len(sys.argv) &lt; 2:
    print 'Usage:  %s filename.svg' % sys.argv[0]
    sys.exit(0)
input_file = sys.argv[1]

dom = minidom.parse(input_file)
groups = dom.getElementsByTagName('g')
for group in groups:
    if group.getAttribute('inkscape:groupmode') == 'layer' and group.getAttribute('inkscape:label') == 'slices':
        if 'display:none' not in group.getAttribute('style'):
            print 'Warning: slices layer might still be visible'
        for element in group.getElementsByTagName('rect'):
            export_id = element.getAttribute('id')
            filename = '%s.png' % export_id
            print 'Exporting %s...' % filename
            os.system('inkscape --export-id="%s" --export-png="%s" --file="%s"' % (export_id, filename, input_file))
        break
else:
    print 'No layer named "slices" found; not exporting anything'
    sys.exit(1)
&lt;/pre&gt;</content><link rel="replies" type="application/atom+xml" href="http://typethinker.blogspot.com/feeds/4291527516229970544/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3365890222783870731&amp;postID=4291527516229970544" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/4291527516229970544?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/4291527516229970544?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typethinker/~3/YlYTSVYjFiw/exporting-slices-from-inkscape-part-2.html" title="Exporting slices from Inkscape, part 2" /><author><name>Thomas ten Cate</name><uri>http://www.blogger.com/profile/02609144861191873031</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>3</thr:total><feedburner:origLink>http://typethinker.blogspot.com/2011/02/exporting-slices-from-inkscape-part-2.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak4FQ3s8cSp7ImA9Wx9VFko.&quot;"><id>tag:blogger.com,1999:blog-3365890222783870731.post-4355165935177668380</id><published>2011-02-02T21:35:00.000+01:00</published><updated>2011-02-02T21:35:12.579+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-02T21:35:12.579+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="software" /><title>Editor's Prick?</title><content type="html">&lt;p&gt;Some time ago, I received an e-mail concerning my little open source program &lt;a href="http://taekwindow.sf.net/"&gt;Taekwindow&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Monday, Jan 17, 2011, 10:27&lt;br/&gt;From: F.R.&lt;br/&gt;To: me&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;My name is F., Customer Manager of WareSeeker.com, a professional software directory. I would like to propose a solution to promote your software on our site.&lt;/p&gt;
&lt;p&gt;We would like to take this opportunity to introduce ourselves. Wareseeker is one of top 5 professional software directories in the world and currently serving about 2 million page views per day. Many renowned software publishers rely on us as their primary media of promoting their products, thus increasing the sales or download dramatically.&lt;/p&gt;
&lt;p&gt;We have tested thoroughly and guarantee that Taekwindow 0.3.1
is 100% SAFE TO INSTALL, which means it does not contain any form of malware:  spyware, viruses, trojans and dialers.&lt;/p&gt;
&lt;p&gt;Taekwindow 0.3.1

 has been received Editor’s Pick Award from us.&lt;/p&gt;
&lt;p&gt;We hope that you will gain more benefit through this Award.  Moreover, we would like to request you add our link and Editor's Pick icon on your Awards category at http://taekwindow.sourceforge.net/download.html&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;It's not the first time Taekwindow receives such an award, and they generally don't mean very much. But still, it's a nice gesture, and I've done other download sites the same favour, so I replied in the positive.&lt;/p&gt;

&lt;p&gt;Since the Taekwindow site is largely built by an automated build system that only runs on Windows, and I am spending all my time in Linux lately, I did not make any promises when I would get round to it. It would probably have been later that week.&lt;/p&gt;

&lt;p&gt;Two days later, I received two e-mails in quick succession.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Wed, Jan 19, 2011, 02:40&lt;br/&gt;From: F.R.&lt;br/&gt;To: me&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;How about our request of our link and Editor's Pick icon at http://taekwindow.sourceforge.net/download.html&lt;/p&gt;
&lt;p&gt;You will do that, ok? but when&lt;/p&gt;
&lt;p&gt;Keep contact me&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Wed, Jan 19, 2011, 09:46&lt;br/&gt;From: F.R.&lt;br/&gt;To: me&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;How long you got message of mine? I will remind you in final time for our link and Editor's Pick icon on your site.&lt;/p&gt;
&lt;p&gt;Give me the respond when you reached this email&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Okay, so he expects me to answer to e-mail within 7 hours and 6 minutes, while I'm asleep. And he's getting pushy. But at least I could tell him that I received his mails.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Wed, Jan 19, 2011, 12:04&lt;br/&gt;From: me&lt;br/&gt;To: F.R.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I got your messages alright. I'm a busy person, and I do not
appreciate your impatience about me doing you a favour. Please stop
pushing me. I'll get to it as soon as I have time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I might still have done it later that week, but I didn't get round to it. Today, another e-mail appeared.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Tue, Jan 25, 2011, 02:42&lt;br/&gt;From: F.R.&lt;br/&gt;To: me&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I don't know how are you busy, I'm also a busy man with a huge business volume  each day but I still spend some minutes to write for me to remind you about our request.&lt;/p&gt;
&lt;p&gt;Today If you don't reply my mail, I will remove our award for your product on my site.  Contact me immediately when you reached this mail&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Is that how you treat people when you want them to do you a favour? Not appreciated.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Tue, Jan 25, 2011, 11:45&lt;br/&gt;From: me&lt;br/&gt;To: F.R.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Dear Mr. R.,&lt;/p&gt;
&lt;p&gt;The usual nature of awards is that they are given without requesting
anything in return. In spite of that, I graciously agreed to return
the favour, although due to other obligations I couldn't say when.
After a few days, a gentle reminder might certainly have been
appropriate. However, two reminders within eight hours (during which I
was asleep, I might add), of an increasingly unfriendly nature, did
not increase the likelihood that I would answer to your request. Your
further pushy behaviour did not improve the situation, and now you
request has turned into a demand, with a corresponding punishment
should I not comply.&lt;/p&gt;
&lt;p&gt;I noticed that Taekwindow has received 13 downloads through your site,
and this number has not changed in the last few days. Compared to 149
downloads at Softoxi and 1121 downloads at Softpedia, I doubt there is
much value for Taekwindow to be hosted on your site. Given the
apparent attitude of the site's employees, it might even do more harm
than good.&lt;/p&gt;
&lt;p&gt;If it must be like this, I would prefer not to have anything to do
with you or your site anymore. I have removed the staged modifications
to the Taekwindow website. I will now proceed to write a post about
our exchange on my blog, which receives a moderate amount of traffic.
Good luck with your future endeavours.&lt;/p&gt;
&lt;p&gt;Sincerely,&lt;/p&gt;
&lt;p&gt;Thomas&lt;/p&gt;
&lt;p&gt;P.S. Incidentally, the download page for Taekwindow on WareSeeker
reads: "Software piracy is theft, Using crack, password, serial
numbers, registration codes, key generators, cd key, hacks is illegal
and prevent future development of Taekwindow 0.3.1 Edition." None of
these statements are true. Software piracy may be considered a crime
in most countries, but it is distinct from theft. The use of
password[s], serial numbers, registration codes and/or cd keys is
often a part of software installation required by the software's
manufacturer, without which the software will not function, so this
can hardly be considered illegal. Finally, the use of any of these
will not impact the future development of Taekwindow 0.3.1 in the
slightest.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here's that blog post. See? I do keep my promises &amp;mdash; mostly.&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://typethinker.blogspot.com/feeds/4355165935177668380/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3365890222783870731&amp;postID=4355165935177668380" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/4355165935177668380?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/4355165935177668380?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typethinker/~3/1sNYaDI1iAQ/editors-prick.html" title="Editor's Prick?" /><author><name>Thomas ten Cate</name><uri>http://www.blogger.com/profile/02609144861191873031</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>6</thr:total><feedburner:origLink>http://typethinker.blogspot.com/2011/02/editors-prick.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0QMRXc-fyp7ImA9Wx5UEUs.&quot;"><id>tag:blogger.com,1999:blog-3365890222783870731.post-7906290563939766777</id><published>2010-10-09T20:42:00.003+02:00</published><updated>2010-10-15T19:56:24.957+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-15T19:56:24.957+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="software" /><title>Installing Rails 3 in Ubuntu 10.4</title><content type="html">&lt;p&gt;For the record, and for those of my friends who are going to participate in the &lt;a href="http://railsrumble.com/"&gt;Rails Rumble&lt;/a&gt; next weekend: here's how you install Rails 3 on your Ubuntu Karmic system. (10.10, known as Maverick, is supposed to arrive tomorrow and might make this post obsolete. But I won't be risking an upgrade before the weekend.)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install Ruby; apt contains the required version:
&lt;pre&gt;sudo apt-get install ruby&lt;/pre&gt;
&lt;li&gt;Uninstall RubyGems, because we'll install a more recent version from source:
&lt;pre&gt;sudo apt-get remove rubygems&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Install RubyGems from source:&lt;br/&gt;
&lt;pre&gt;cd /tmp
wget http://production.cf.rubygems.org/rubygems/rubygems-1.3.7.tgz
tar xzf rubygems-1.3.7.tgz
cd rubygems-1.3.7
sudo ruby setup.rb
sudo ln -s gem1.8 /usr/bin/gem&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Install Rails:
&lt;pre&gt;sudo gem install rails&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;</content><link rel="replies" type="application/atom+xml" href="http://typethinker.blogspot.com/feeds/7906290563939766777/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3365890222783870731&amp;postID=7906290563939766777" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/7906290563939766777?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/7906290563939766777?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typethinker/~3/btFUQj3gv3Y/installing-rails-3-in-ubuntu-104.html" title="Installing Rails 3 in Ubuntu 10.4" /><author><name>Thomas ten Cate</name><uri>http://www.blogger.com/profile/02609144861191873031</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://typethinker.blogspot.com/2010/10/installing-rails-3-in-ubuntu-104.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEAESXwzeSp7ImA9Wx9bEE8.&quot;"><id>tag:blogger.com,1999:blog-3365890222783870731.post-1009046099595444835</id><published>2010-07-18T15:39:00.006+02:00</published><updated>2011-02-18T11:58:28.281+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-18T11:58:28.281+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="software" /><title>Exporting slices from Inkscape</title><content type="html">&lt;p&gt;&lt;strong&gt;If you have a Python interpreter available, you can use the slightly better alternative from &lt;a href="http://typethinker.blogspot.com/2011/02/exporting-slices-from-inkscape-part-2.html"&gt;Part 2&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In Photoshop, it's possible to &amp;ldquo;slice&amp;rdquo; an image into pieces, name the individual pieces, and export each to a separate file. This is really useful for web design: you can do the whole design in one image, then export the bits and pieces for later reassembling in HTML/CSS. Can we do the same slicing trick with Inkscape?&lt;/p&gt;

&lt;p&gt;It turns out that we can; it's even on the &lt;a href="http://www.inkscape.org/doc/tips/tutorial-tips.html"&gt;Inkscape Tips and Tricks page&lt;/a&gt;. However, the exporting itself remains manual labour. I wrote a bash script to automate that; the code is given below.&lt;/p&gt;

&lt;p&gt;The process is as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;First, draw your image as usual.&lt;/li&gt;
&lt;li&gt;Then, add a layer that will hold the slices; name it, for example, &lt;code&gt;slices&lt;/code&gt;. Set the layer's opacity to about 50% to be able to see what you're doing. Enable the grid, and make sure it is set to pixels: you want your slices to align with pixel boundaries.&lt;/li&gt;
&lt;li&gt;Draw your slice rectangles onto the &lt;code&gt;slices&lt;/code&gt; layer, aligned to the grid. Ensure that the rectangles have no border; the fill is irrelevant (I use red).&lt;/li&gt;
&lt;li&gt;Right-click a slice, and choose Object Properties. Change Id field to &lt;code&gt;EXP-something&lt;/code&gt; and hit Enter. The tag &lt;code&gt;EXP-&lt;/code&gt; indicates that this rectangle is intended for export; &lt;code&gt;something&lt;/code&gt; will become the filename (&lt;code&gt;something.png&lt;/code&gt;). Repeat this for all slices.&lt;/li&gt;
&lt;li&gt;Hide the slices layer, and save your image. Let's say you called it &lt;code&gt;layout.svg&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run the script as follows:&lt;br/&gt;
&lt;code&gt;./export.sh layout.svg&lt;/code&gt;&lt;br/&gt;
You should see each of your slices being exported to a PNG file in the same directory.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's the code for the script. Save this to a file &lt;code&gt;export.sh&lt;/code&gt; and make it executable.&lt;/p&gt;
&lt;pre&gt;#!/bin/bash

if [[ -z $1 ]] ; then
 echo "Usage: $0 [FILE]"
 exit 0
else
 FILENAME=$1
fi

PREFIX=EXP-

for ID in `grep -o "id=\"$PREFIX.*\"" $FILENAME | cut -d\" -f2` ; do
 OUTPUT=${ID#$PREFIX}.png
 echo "Exporting area $ID to $OUTPUT..."
 inkscape --export-id=$ID --export-png=$OUTPUT --file=$FILENAME
done&lt;/pre&gt;</content><link rel="replies" type="application/atom+xml" href="http://typethinker.blogspot.com/feeds/1009046099595444835/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3365890222783870731&amp;postID=1009046099595444835" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/1009046099595444835?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/1009046099595444835?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typethinker/~3/obKxQlond1U/exporting-slices-from-inkscape.html" title="Exporting slices from Inkscape" /><author><name>Thomas ten Cate</name><uri>http://www.blogger.com/profile/02609144861191873031</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://typethinker.blogspot.com/2010/07/exporting-slices-from-inkscape.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUMRnw9eSp7ImA9WxFXE0g.&quot;"><id>tag:blogger.com,1999:blog-3365890222783870731.post-84119674462272804</id><published>2010-05-20T13:00:00.008+02:00</published><updated>2010-05-20T14:08:07.261+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-20T14:08:07.261+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>Are C++ iostreams really slow?</title><content type="html">&lt;p&gt;In the C++ world, one often hears the statement &amp;ldquo;&lt;code&gt;iostream&lt;/code&gt;s are slow, you should use &lt;code&gt;printf&lt;/code&gt; instead&amp;rdquo;. Is this true?&lt;/p&gt;

&lt;p&gt;It is possible that this story results from abuse of &lt;code&gt;endl&lt;/code&gt;. Beginner's C++ books often recommend &lt;code&gt;endl&lt;/code&gt; over &lt;code&gt;'\n'&lt;/code&gt; for writing a newline. The observable result is often the same, but &lt;code&gt;endl&lt;/code&gt; results in extra overhead: it flushes the stream. This results in a system call, slowing things down while often unnecessary.&lt;/p&gt;

&lt;p&gt;Using my newly written &lt;a href="http://typethinker.blogspot.com/2010/05/timing-section-of-code-in-c.html"&gt;&lt;code&gt;TimedSection&lt;/code&gt; class&lt;/a&gt;, I tested whether the story is actually true, or just a myth. I tried three methods of printing:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;code&gt;cout&lt;/code&gt; with &lt;code&gt;endl&lt;/code&gt; for line endings
&lt;li&gt;&lt;code&gt;cout&lt;/code&gt; with &lt;code&gt;'\n'&lt;/code&gt; for line endings
&lt;li&gt;&lt;code&gt;printf&lt;/code&gt; (also with &lt;code&gt;'\n'&lt;/code&gt; for line endings, so no forced flushing)&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;Each of these was tested in the following scenarios:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;printing an empty line&lt;/li&gt;
&lt;li&gt;printing a line containing a string literal&lt;/li&gt;
&lt;li&gt;printing a line containing a string variable, a string literal, and an integer variable&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;All strings used were 20 characters long; I figured this would be a typical average length for printing messages. Newline characters were absorbed into string constants wherever possible.&lt;/p&gt;

&lt;p&gt;Each of these was run 10 million times, redirecting the output to &lt;code&gt;/dev/null&lt;/code&gt;. The testing machine is an Intel i7 920, running Ubuntu 10.4, Linux 2.6.32 and gcc 4.4.3.&lt;/p&gt;

&lt;p&gt;Here are the results:&lt;/p&gt;
&lt;pre&gt;cout with only endl                     1461.310252 ms
cout with only '\n'                      343.080217 ms
printf with only '\n'                     90.295948 ms
cout with string constant and endl      1892.975381 ms
cout with string constant and '\n'       416.123446 ms
printf with string constant and '\n'     472.073070 ms
cout with some stuff and endl           3496.489748 ms
cout with some stuff and '\n'           2638.272046 ms
printf with some stuff and '\n'         2520.318314 ms&lt;/pre&gt;

&lt;p&gt;Surprise! Yes, for printing newlines, &lt;code&gt;printf&lt;/code&gt; greatly outperforms &lt;code&gt;cout&lt;/code&gt;. We can also see the huge slowdown of using &lt;code&gt;endl&lt;/code&gt; inappropriately, something which is clearly to be avoided.&lt;/p&gt;

&lt;p&gt;However, even for printing a moderately-sized string constant, &lt;code&gt;cout&lt;/code&gt; outperforms &lt;code&gt;printf&lt;/code&gt;. This effect becomes more pronounced as the string gets longer, probably because &lt;code&gt;printf&lt;/code&gt; has to do more processing per character.&lt;/p&gt;

&lt;p&gt;Finally, for some slightly more complicated formatting, the difference is quite small. For longer string constants, it becomes even smaller.&lt;/p&gt;

&lt;p&gt;We can conclude that &lt;code&gt;iostream&lt;/code&gt;s are definitely not always slower than C-style &lt;code&gt;printf&lt;/code&gt;. It depends on the particular use, and as the formatting becomes more complicated, the difference drops to zero. Part of the myth may be ascribed to inappropriate use of &lt;code&gt;endl&lt;/code&gt;; maybe another part is due to unoptimized implementations of the standard library. Either way: myth busted.&lt;/p&gt;

&lt;p&gt;Update: For the curious, here is the full source code. You may need to link with &lt;code&gt;-lrt&lt;/code&gt; to get &lt;code&gt;clock_gettime&lt;/code&gt;.&lt;/p&gt;

&lt;pre style="height:20em;overflow:scroll"&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;iostream&amp;gt;
#include &amp;lt;ctime&amp;gt;

class TimedSection {
    char const *d_name;
    timespec d_start;
    public:
        TimedSection(char const *name) :
            d_name(name)
        {
            clock_gettime(CLOCK_REALTIME, &amp;d_start);
        }
        ~TimedSection() {
            timespec end;
            clock_gettime(CLOCK_REALTIME, &amp;end);
            double duration = 1e3 * (end.tv_sec - d_start.tv_sec) +
                              1e-6 * (end.tv_nsec - d_start.tv_nsec);
            std::cerr &amp;lt;&amp;lt; d_name &amp;lt;&amp;lt; '\t' &amp;lt;&amp;lt; std::fixed &amp;lt;&amp;lt; duration &amp;lt;&amp;lt; " ms\n"; 
        }
};

int main() {
    const int iters = 10000000;
    char const *text = "01234567890123456789";
    {
        TimedSection s("cout with only endl");
        for (int i = 0; i &amp;lt; iters; ++i)
            std::cout &amp;lt;&amp;lt; std::endl;
    }
    {
        TimedSection s("cout with only '\\n'");
        for (int i = 0; i &amp;lt; iters; ++i)
            std::cout &amp;lt;&amp;lt; '\n';
    }
    {
        TimedSection s("printf with only '\\n'");
        for (int i = 0; i &amp;lt; iters; ++i)
            printf("\n");
    }
    {
        TimedSection s("cout with string constant and endl");
        for (int i = 0; i &amp;lt; iters; ++i)
            std::cout &amp;lt;&amp;lt; "01234567890123456789" &amp;lt;&amp;lt; std::endl;
    }
    {
        TimedSection s("cout with string constant and '\\n'");
        for (int i = 0; i &amp;lt; iters; ++i)
            std::cout &amp;lt;&amp;lt; "01234567890123456789\n";
    }
    {
        TimedSection s("printf with string constant and '\\n'");
        for (int i = 0; i &amp;lt; iters; ++i)
            printf("01234567890123456789\n");
    }
    {
        TimedSection s("cout with some stuff and endl");
        for (int i = 0; i &amp;lt; iters; ++i)
            std::cout &amp;lt;&amp;lt; text &amp;lt;&amp;lt; "01234567890123456789" &amp;lt;&amp;lt; i &amp;lt;&amp;lt; std::endl;
    }
    {
        TimedSection s("cout with some stuff and '\\n'");
        for (int i = 0; i &amp;lt; iters; ++i)
            std::cout &amp;lt;&amp;lt; text &amp;lt;&amp;lt; "01234567890123456789" &amp;lt;&amp;lt; i &amp;lt;&amp;lt; '\n';
    }
    {
        TimedSection s("printf with some stuff and '\\n'");
        for (int i = 0; i &amp;lt; iters; ++i)
            printf("%s01234567890123456789%i\n", text, i);
    }
}&lt;/pre&gt;</content><link rel="replies" type="application/atom+xml" href="http://typethinker.blogspot.com/feeds/84119674462272804/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3365890222783870731&amp;postID=84119674462272804" title="10 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/84119674462272804?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/84119674462272804?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typethinker/~3/aFtgLVTQrIg/are-c-iostreams-really-slow.html" title="Are C++ iostreams really slow?" /><author><name>Thomas ten Cate</name><uri>http://www.blogger.com/profile/02609144861191873031</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>10</thr:total><feedburner:origLink>http://typethinker.blogspot.com/2010/05/are-c-iostreams-really-slow.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUUFRXg4eip7ImA9WxFXE0g.&quot;"><id>tag:blogger.com,1999:blog-3365890222783870731.post-4659942787352547796</id><published>2010-05-20T12:49:00.004+02:00</published><updated>2010-05-20T13:00:14.632+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-20T13:00:14.632+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>Timing a section of code in C++</title><content type="html">&lt;p&gt;Sometimes it's useful to measure how long a certain part of your C++ code takes to execute. Here's a little utility class that makes this extremely easy. It can be used like this:&lt;/p&gt;

&lt;pre&gt;void foo() {
    TimedSection s("foo()");
    // do some long operation...
}&lt;/pre&gt;

&lt;p&gt;Calling &lt;code&gt;foo()&lt;/code&gt; will print something like this to stderr:&lt;/p&gt;

&lt;pre&gt;foo()   336.856127 ms&lt;/pre&gt;

&lt;p&gt;As you may have guessed, a &lt;code&gt;TimedSection&lt;/code&gt; records the time between its construction and its destruction. Since C++ has no garbage collection, destructors are called at a deterministic moment: when the local object (called &lt;code&gt;s&lt;/code&gt; above) goes out of scope. If you want to time a section that is not a scope by itself, you can introduce a pair of braces to scope the object. If the section is even more complex (e.g. spanning multiple functions), you can use &lt;code&gt;new&lt;/code&gt; and &lt;code&gt;delete&lt;/code&gt;, but that destroys the elegant simplicity of &lt;code&gt;TimedSection&lt;/code&gt;'s usage.&lt;/p&gt;

&lt;p&gt;The implementation is rather simple as well:&lt;/p&gt;

&lt;pre&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;ctime&amp;gt;

class TimedSection {
    char const *d_name;
    timespec d_start;
    public:
        TimedSection(char const *name) :
            d_name(name)
        {
            clock_gettime(CLOCK_REALTIME, &amp;d_start);
        }
        ~TimedSection() {
            timespec end;
            clock_gettime(CLOCK_REALTIME, &amp;end);
            double duration = 1e3 * (end.tv_sec - d_start.tv_sec) +
                              1e-6 * (end.tv_nsec - d_start.tv_nsec);
            std::cerr &amp;lt;&amp;lt; d_name &amp;lt;&amp;lt; '\t' &amp;lt;&amp;lt; std::fixed &amp;lt;&amp;lt; duration &amp;lt;&amp;lt; " ms\n"; 
        }
};&lt;/pre&gt;

I hereby release this little code snippet into the public domain. Enjoy!</content><link rel="replies" type="application/atom+xml" href="http://typethinker.blogspot.com/feeds/4659942787352547796/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3365890222783870731&amp;postID=4659942787352547796" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/4659942787352547796?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/4659942787352547796?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typethinker/~3/C__VkeT8cGQ/timing-section-of-code-in-c.html" title="Timing a section of code in C++" /><author><name>Thomas ten Cate</name><uri>http://www.blogger.com/profile/02609144861191873031</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://typethinker.blogspot.com/2010/05/timing-section-of-code-in-c.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk4CQXk8eCp7ImA9WxFTFEs.&quot;"><id>tag:blogger.com,1999:blog-3365890222783870731.post-426393586028577147</id><published>2010-04-05T12:10:00.005+02:00</published><updated>2010-04-05T12:56:00.770+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-05T12:56:00.770+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="software" /><title>So long, and thanks for all the glass</title><content type="html">&lt;p&gt;When I first installed Windows 7 after nearly a decade of using XP, I decided I'd not customize it. I'd just leave the settings at their default values and see what the wise men at Microsoft had decided for me. After all, there are thousands of hours of usability testing behind those decisions, so it seemed a good idea to give them a chance.&lt;/p&gt;

&lt;p&gt;Now, half a year later, I've gotten used to most of Windows 7. Although I've tweaked the occasional thing here and there (show me the damn file extensions already!), I think most of it is pretty reasonable. But there's one thing I just can't get used to: the Aero theme.&lt;/p&gt;

&lt;p&gt;It's not that it's semi-transparent. It's not that it fades and zooms and zips and zaps. It's just the minor little thing that &lt;em&gt;I can't see the difference anymore between active and inactive windows&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;When you activate a window, the title bar and borders become a little bit darker, the shadow becomes a little bit blacker, and the close button changes its colour from glassy to red. You can see the changes happen while you're switching focus, but telling the difference at a glance from a static image is hard. And because the title bar is transparent, the colour depends on the things behind it, making it even harder. There's just no single, consistent look for active and inactive title bars. I kept having to look at the close button to tell which window was active.&lt;/p&gt;

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_JMO36jorXIA/S7m_QiyKhJI/AAAAAAAAAho/wRjBwdk2TkY/s1600/aero-focus.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 129px;" src="http://4.bp.blogspot.com/_JMO36jorXIA/S7m_QiyKhJI/AAAAAAAAAho/wRjBwdk2TkY/s400/aero-focus.png" border="0" alt="The subtle difference between an inactive and active title bar in Windows Aero" id="BLOGGER_PHOTO_ID_5456602714472088722" /&gt;&lt;/a&gt;

&lt;p&gt;So what am I to do? Am I to magically know which window is active? When I've just clicked it, or when I'm typing into it, sure, I'll know. But being the Alt+Tab guy that I am, I shift focus without clicking all the time, and not always to the correct window right away. And what if some unexpected window suddenly pops up that might have stolen my focus, like an auto-updater? How can I tell if I can continue typing, or that I'd better yank my hands away from the keyboard in case I inadvertedly activate the Launch Nukes button?&lt;/p&gt;

&lt;p&gt;Unfortunately, there is no way to change the look. The wise men at Microsoft have decided that a &amp;ldquo;theme&amp;rdquo; will be nothing more than a single colour for the glass, along with a set of wallpapers. There's no way to select different colours for active and inactive windows, like there is for the &amp;ldquo;classic&amp;rdquo; themes. There's also no way to install a clearer Aero theme without resorting to commercial third-party software like &lt;a href="http://www.stardock.com/products/windowblinds/"&gt;WindowBlinds&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So in the end, after my millionth focus fuckup, I switched back to the classic Windows 2000 lookalike theme. Blue versus gray seems like a distinction my eyes can handle.&lt;/p&gt;

&lt;p&gt;Why do I have to sacrifice good looks to gain usability? Why can't Microsoft just make them get along?&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://typethinker.blogspot.com/feeds/426393586028577147/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3365890222783870731&amp;postID=426393586028577147" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/426393586028577147?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/426393586028577147?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typethinker/~3/dz58OeGZn10/so-long-and-thanks-for-all-glass.html" title="So long, and thanks for all the glass" /><author><name>Thomas ten Cate</name><uri>http://www.blogger.com/profile/02609144861191873031</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_JMO36jorXIA/S7m_QiyKhJI/AAAAAAAAAho/wRjBwdk2TkY/s72-c/aero-focus.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://typethinker.blogspot.com/2010/04/so-long-and-thanks-for-all-glass.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUQAQn48eSp7ImA9WxBaEU8.&quot;"><id>tag:blogger.com,1999:blog-3365890222783870731.post-7000944946022003622</id><published>2010-03-20T23:02:00.004+01:00</published><updated>2010-03-20T23:15:43.071+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-20T23:15:43.071+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="software" /><title>A harmonograph in JavaScript</title><content type="html">&lt;p&gt;What's a harmonograph, you ask? Well, it's something like a Spirograph for grown-ups. A harmonograph uses a construction with pendulums to draw pretty patterns.&lt;/p&gt;

&lt;p&gt;One particular incarnation uses two pendulums of nearly equal length, each about two metres. To the right pendulum, a slowly revolving disk is attached, which is driven by a small electrical motor. The drawing paper is taped onto the disk. To the left pendulum, an arm is attached with the pen at the end. When the pressure and thus the friction of the pen is sufficiently low, the pendulums can keep swinging for tens of minutes.&lt;/p&gt;

&lt;p&gt;For learning and fun, I replicated this harmonograph in JavaScript with the HTML5 canvas element. The pendulum motion is approximated by a sine function, and friction by an exponential, but apart from that it should be pretty physically accurate.&lt;/p&gt;

&lt;p&gt;Without further ado, I present to you: &lt;a href="http://thomas.home.fmf.nl/harmonograph/"&gt;Harmonograph in JavaScript&lt;/a&gt;. Usage should be self-evident. Although some input validation is done, you will be able to break it with strange values. Obviously, it will not (yet) work in Internet Explorer, but it works correctly in Firefox, and probably Chrome, Safari and Opera as well.&lt;/p&gt;

&lt;p&gt;With the link at the top, you can save and bookmark your creations or send them to your friends. Enjoy!&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://typethinker.blogspot.com/feeds/7000944946022003622/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3365890222783870731&amp;postID=7000944946022003622" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/7000944946022003622?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/7000944946022003622?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typethinker/~3/hqcnR8HxCrM/harmonograph-in-javascript.html" title="A harmonograph in JavaScript" /><author><name>Thomas ten Cate</name><uri>http://www.blogger.com/profile/02609144861191873031</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://typethinker.blogspot.com/2010/03/harmonograph-in-javascript.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0cBQ3wzfip7ImA9WxBbFUo.&quot;"><id>tag:blogger.com,1999:blog-3365890222783870731.post-1202853787217671506</id><published>2010-03-14T14:29:00.007+01:00</published><updated>2010-03-14T14:57:32.286+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-14T14:57:32.286+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="software" /><title>Capitalizing MP3s from the command line</title><content type="html">&lt;p&gt;For my own future reference and your enjoyment, here's a neat little oneliner to transform &lt;tt&gt;01 - some song.mp3&lt;/tt&gt; into &lt;tt&gt;01 - Some Song.mp3&lt;/tt&gt;:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;rename "s/([^._'])\b(\w)(\w*)/\$1\U\$2\L\$3/g" *.mp3&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;It needs the &lt;code&gt;prename&lt;/code&gt; utility from Perl, which on Ubuntu is available by default under the name &lt;code&gt;rename&lt;/code&gt;.&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://typethinker.blogspot.com/feeds/1202853787217671506/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3365890222783870731&amp;postID=1202853787217671506" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/1202853787217671506?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/1202853787217671506?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typethinker/~3/uh_kxFtcK0Y/capitalizing-mp3s-from-command-line.html" title="Capitalizing MP3s from the command line" /><author><name>Thomas ten Cate</name><uri>http://www.blogger.com/profile/02609144861191873031</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>3</thr:total><feedburner:origLink>http://typethinker.blogspot.com/2010/03/capitalizing-mp3s-from-command-line.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUUBRXw9cCp7ImA9Wx5TGUk.&quot;"><id>tag:blogger.com,1999:blog-3365890222783870731.post-6928797725488264305</id><published>2010-02-05T18:30:00.008+01:00</published><updated>2010-08-04T19:34:14.268+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-08-04T19:34:14.268+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="software" /><title>Ubuntu fails to load nvidia kernel module</title><content type="html">&lt;p&gt;As much a note to myself, as a warning to others&amp;hellip;&lt;/p&gt;

&lt;p&gt;After a kernel upgrade, my Ubuntu Karmic started the X server in low-resolution mode. My Xorg.0.log said:&lt;/p&gt;
&lt;pre&gt;(II) LoadModule: "nvidia"
(II) Loading /usr/lib/xorg/modules/drivers//nvidia_drv.so
(II) Module nvidia: vendor="NVIDIA Corporation"
        compiled for 4.0.2, module version = 1.0.0
        Module class: X.Org Video Driver
(EE) NVIDIA: Failed to load the NVIDIA kernel module. Please check your
(EE) NVIDIA:     system's kernel log for additional error messages.
(II) UnloadModule: "nvidia"
(II) Unloading /usr/lib/xorg/modules/drivers//nvidia_drv.so
(EE) Failed to load module "nvidia" (module-specific error, 0)
(EE) No drivers available.&lt;/pre&gt;

&lt;p&gt;I tried &lt;code&gt;modprobe nvidia&lt;/code&gt; and such, but it seemed that the module actually did not exist. This module should be installed by the package &lt;code&gt;nvidia-185-kernel-source&lt;/code&gt;, which was present on my system. However, it turns out that the kernel module is compiled on-the-fly by a program called &lt;code&gt;jockey&lt;/code&gt; which controls DKMS, the Dynamic Kernel Module Support.&lt;/p&gt;

&lt;p&gt;It is possible to force a recompile using &lt;code&gt;dpkg-reconfigure&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;$ sudo dpkg-reconfigure nvidia-185-kernel-source
Removing all DKMS Modules
Done.
Loading new nvidia-185.18.36 DKMS files...
Building for architecture x86_64
Module build for the currently running kernel was skipped since the
kernel source for this kernel does not seem to be installed.&lt;/pre&gt;

&lt;p&gt;I need the kernel source, eh? Why the hell is that not a dependency, if the driver package is useless without it? Anyway, let's install the kernel source then:&lt;/p&gt;
&lt;pre&gt;$ uname -r
2.6.31-19-generic
$ sudo apt-get install linux-source-2.6.31&lt;/pre&gt;

&lt;p&gt;Installs fine, but makes no difference. Turns out that &lt;code&gt;dpkg-reconfigure&lt;/code&gt; was lying: I just need the headers. Here we go:&lt;/p&gt;
&lt;pre&gt;$ sudo apt-get install linux-headers-2.6.31-19-generic
...
$ sudo dpkg-reconfigure nvidia-185-kernel-source
Removing all DKMS Modules
Done.
Loading new nvidia-185.18.36 DKMS files...
Building for architecture x86_64
Building initial module for 2.6.31-19-generic
Done.

nvidia.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/2.6.31-19-generic/updates/dkms/

depmod......

DKMS: install Completed.
$ modprobe nvidia
$
&lt;/pre&gt;
&lt;p&gt;That's better.&lt;/p&gt;

&lt;p&gt;Several bug reports indicate similar problems, but the current way this is handled is terribly inadequate. The driver package should pull in the kernel headers if it needs them. There was no warning about this when the kernel was upgraded. There was no warning when the module failed to compile on boot. A fix for a problem with the same symptoms was released back in December; another one is in the upcoming Lucid release.&lt;/p&gt;

&lt;p&gt;Oh yeah, I ended up rebooting my system. Whatever happened to Ctrl+Alt+Backspace? (&lt;a href="https://wiki.ubuntu.com/XorgCtrlAltBackspace"&gt;Answer&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update, 2010-08-04&lt;/strong&gt;: After another kernel upgrade, my display driver was hosed again. After hours of tinkering, I typed &lt;code&gt;sudo dpkg-reconfigure nvidia-current&lt;/code&gt; and was greeted with the message &lt;code&gt;gzip: stdout: No space left on device&lt;/code&gt;. Apparently, my &lt;code&gt;/boot&lt;/code&gt; partition was full (of abandoned kernels). Something to check, for whoever runs into similar problems! Also, the kernel module appears to have been renamed from &lt;code&gt;nvidia&lt;/code&gt; to &lt;code&gt;nvidia-current&lt;/code&gt;.&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://typethinker.blogspot.com/feeds/6928797725488264305/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3365890222783870731&amp;postID=6928797725488264305" title="23 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/6928797725488264305?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/6928797725488264305?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typethinker/~3/03yp4zAtKhk/ubuntu-fails-to-load-nvidia-kernel.html" title="Ubuntu fails to load nvidia kernel module" /><author><name>Thomas ten Cate</name><uri>http://www.blogger.com/profile/02609144861191873031</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>23</thr:total><feedburner:origLink>http://typethinker.blogspot.com/2010/02/ubuntu-fails-to-load-nvidia-kernel.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMGQ385fSp7ImA9WxBXE0g.&quot;"><id>tag:blogger.com,1999:blog-3365890222783870731.post-8405487276045097070</id><published>2010-01-24T14:58:00.017+01:00</published><updated>2010-01-24T17:27:02.125+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-24T17:27:02.125+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="software" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>Review of free C++ IDEs for Linux</title><content type="html">&lt;p&gt;For my new project, I started looking into IDEs for Linux for the C++ language. And since I'm testing them anyway, I might as well write some quick reviews. &amp;lsquo;Quick&amp;rsquo;, because I'll mostly be going on first impressions, and some things I say might be quite wrong. Feel free to correct me in the comments!&lt;/p&gt;

&lt;p&gt;My previous IDE experience includes Visual Studio for C++ and for C#, Eclipse for Java. I will sometimes compare to these.&lt;/p&gt;

&lt;h2&gt;Code::Blocks&lt;/h2&gt;

&lt;p&gt;I am greeted with very nice wizards, and it's easy to get up to speed. There is even a template for GLFW projects, which I select. But when trying to compile (using shortcuts nothing like any other IDE I know) I get a linker error; some XF86 library is missing, and even &lt;code&gt;apt-file&lt;/code&gt; cannot tell me where to get it.&lt;/p&gt;

&lt;p&gt;Hunting through the build settings, I notice many other problems. The settings are nested three levels deep: a bar with huge icons on the left, &lt;em&gt;scrolling&lt;/em&gt; tabs (the horror) on the right, and &lt;em&gt;nested&lt;/em&gt; tabs below those. Many options are unclear. When I press Esc to cancel my changes and dismiss the dialog, nothing happens.&lt;/p&gt;

&lt;p&gt;Some parts of the Code::Blocks UI are really good, other parts are&amp;hellip; not so good. I wouldn't want to work in this for a long time.&lt;/p&gt;

&lt;h2&gt;KDevelop&lt;/h2&gt;

&lt;p&gt;It starts up with a blank screen, so I have to ask it to create a new project myself. Not a big deal. The New Project wizard is reminiscent of Visual Studio, so I feel quickly at home. It allows me to create a CMake project; I like CMake. The wizard gives me a Hello World program, but I cannot run it: I have to create a Launch Configuration first. Then I run my program, I think, but where does the output go? The Debug Area (&amp;lsquo;Perspective&amp;rsquo;) is empty. Turns out that building failed, because I moved the project in the mean time, and the project file contains absolute paths. Bad!&lt;/p&gt;

&lt;p&gt;Support for external tools seems good. I already mentioned CMake; the Valgrind profiler and Git versioning system can also be used right from the IDE.&lt;/p&gt;

&lt;p&gt;The IDE itself actually seems like a blend of Eclipse (borrowing much of its concepts and terminology), Visual Studio (some wizards and the layout of dialogs) and Kate (the general KDE stuff). Not bad at all. Still, I had some trouble getting everything set up, but once you've taken the time to do that, KDevelop might be a decent IDE.&lt;/p&gt;

&lt;h2&gt;Eclipse&lt;/h2&gt;

&lt;p&gt;Big, bloated, but feature-rich and quite user-friendly once you've warmed up to it. That's been my impression of Eclipse for Java, which I'm quite familiar with. For Java, it's easily the best IDE around; the refactoring options alone make it worthwhile. Let's see how Eclipse with the CDT plugin performs for C++.&lt;/p&gt;

&lt;p&gt;I install Eclipse, grab the CDT plugin through its update site and restart Eclipse. A few clicks later, I have an empty C++ project. I add a main Hello World file, and after some strange trouble with the Debug Configuration, it runs. I add a library to link with, finding the option without any difficulty. Not being unhappy about this, I continue to write some more code, to try the completion and refactoring features.&lt;/p&gt;

&lt;p&gt;Completion pleasantly surprises me. This stuff is better than Visual Studio's. It's fast, it's accurate, it gets the contents of a newly included header file right after I saved&amp;hellip; nice! Smart insert mode adds closing paretheses, braces and quotes, but if I type them myself as well, they are overwritten.&lt;/p&gt;

&lt;p&gt;Error highlighting is equally fancy. Unlike Visual Studio, syntax errors are highlighted in real time, without even having to save the file.&lt;/p&gt;

&lt;p&gt;I ask it to create a new class, and get a header and source file with a nice skeleton. It's not exactly the way I would write it, but I'm sure it's customizable.&lt;/p&gt;

&lt;p&gt;Refactoring, unfortunately, is not as fancy as it is for Java. It is limited to renaming identifiers, and doesn't rename the source and header file accordingly. It can also extract selected expressions/statements into a separate function, but it does not create this as a member function. There are no &amp;ldquo;quick fix&amp;rdquo; options for adding include directives, like with Java. Yet, it's better than what Visual Studio offers on this front.&lt;/p&gt;

&lt;p&gt;Eclipse with the CDT plugin is not perfect, but it's good. I could live with it.&lt;/p&gt;

&lt;h2&gt;Anjuta&lt;/h2&gt;

&lt;p&gt;I am greeted with a welcome screen, which I ask to create a new project. I am asked for all kinds of needless details, like the license type and my e-mail address. No wonder: it creates an entire autotools project for me. I tried to add a library to the linker command, but couldn't find the option anywhere. Do I really have to edit the Makefile.am?&lt;/p&gt;

&lt;p&gt;I've only had a brief look, and Anjuta seems like a nice IDE if you want what it wants, but at first sight doesn't seem flexible enough to cope with everything.&lt;/p&gt;

&lt;h2&gt;Qt Creator&lt;/h2&gt;

&lt;p&gt;Would this work for non-Qt applications as well? It wouldn't seem so at a first glance, but I imported an empty directory as a Makefile project, which seemed to work. I had to write a Makefile, of course, which failed because the IDE quietly changed my tab to four spaces. After fixing that, and some directory issues, I could build the program. Running it required similar trickery.&lt;/p&gt;

&lt;p&gt;Code completion works very well, and identifiers from a newly included header are available quickly. The entire IDE looks and feels smooth and polished, and is reminiscent of Visual Studio in many details.&lt;/p&gt;

&lt;p&gt;The build system remains weird, though. It created an autotools project for me, with about a dozen files, and not offering me any choice in the matter. There is a reference to CMake in the Preferences, but no clue how to create a CMake project.&lt;/p&gt;

&lt;p&gt;Qt Creator is a slick, clean, usable IDE. I like it. Still, it is very Qt-centric, and its build system seems inflexible. Too bad.&lt;/p&gt;

&lt;h2&gt;NetBeans&lt;/h2&gt;

&lt;p&gt;Yes, another Java IDE that can be used for C++. I have actually never used NetBeans for Java before, so I have no preconceptions about how it should work.&lt;/p&gt;

&lt;p&gt;I apt-get the IDE and install the C/C++ plugin; this is very straightforward. I create a new C++ project, and a Makefile gets created automatically. I run the empty main function, and the program pops up in an external terminal.&lt;/p&gt;

&lt;p&gt;Then I start editing the code, and I'm pleasantly surprised by the editor. Not just syntax errors, but unknown identifiers get highlighted in real time. Function signatures pop up in a large, but helpful tooltip. Even the filenames of include files are autocompleted! The contents of the include file become available without even having to save the file.&lt;/p&gt;

&lt;p&gt;Yet, not all compile errors are highlighted, even though you can click to them from the compiler output window. I could not manage to get the function signature to reappear while I was typing arguments. Refactoring options are all grayed out; I assume those work for Java only.&lt;/p&gt;

&lt;p&gt;The project settings are very much like Visual Studio, but allow for little customization. It's just enough to add a &lt;code&gt;-l&lt;/code&gt; flag to the linker command line to link in an external library. There is also Git integration (if you install the plugin) but I didn't try it.&lt;/p&gt;

&lt;p&gt;I checked out NetBeans as an afterthought, but that seems to have been a mistake. Of all the IDEs I tried, this is actually one of the nicest. It doesn't have many bells and whistles, and its build system might be inflexible, but the code editor makes up for it.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Are IDEs for C++ worth the trouble? I'm not sure. The value of an IDE lies in fast code editing, refactoring options, easy building, and error highlighting, and integrated debugging. None of the IDEs I tried score highly on all these fronts. I can understand: a flexible, usable IDE for C++ is almost impossible to create. Maybe I'll just go back to my trusted old Kate and gnome-terminal&amp;hellip;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://typethinker.blogspot.com/feeds/8405487276045097070/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3365890222783870731&amp;postID=8405487276045097070" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/8405487276045097070?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/8405487276045097070?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typethinker/~3/swleF1Cobrk/review-of-free-c-ides-for-linux.html" title="Review of free C++ IDEs for Linux" /><author><name>Thomas ten Cate</name><uri>http://www.blogger.com/profile/02609144861191873031</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://typethinker.blogspot.com/2010/01/review-of-free-c-ides-for-linux.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUEDR34ycSp7ImA9WxBQEkU.&quot;"><id>tag:blogger.com,1999:blog-3365890222783870731.post-8144052584198290178</id><published>2010-01-12T08:55:00.004+01:00</published><updated>2010-01-12T09:07:56.099+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-12T09:07:56.099+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="photography" /><category scheme="http://www.blogger.com/atom/ns#" term="software" /><title>Programmers are not artists</title><content type="html">&lt;p&gt;As you may know, it takes a &lt;em&gt;long&lt;/em&gt; time to install Visual Studio. Even on a modern system like mine, it took around twenty minutes. No program I know has ever gotten close to that, except Microsoft Office.&lt;/p&gt;
&lt;p&gt;This means that the guy below is on your screen for a &lt;em&gt;long&lt;/em&gt; time. Seriously, the longer you look at it, the more disturbing his face becomes.&lt;/p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_JMO36jorXIA/S0wr7D0dGZI/AAAAAAAAAgk/FAd0WcI0R98/s1600-h/The+Face.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 304px;" src="http://4.bp.blogspot.com/_JMO36jorXIA/S0wr7D0dGZI/AAAAAAAAAgk/FAd0WcI0R98/s400/The+Face.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5425759944712198546" /&gt;&lt;/a&gt;
&lt;p&gt;In the style of &lt;a href="http://photoshopdisasters.blogspot.com/"&gt;Photoshop Disasters&lt;/a&gt;, I'm supposed to write a witty comment below the photo. How about this:&lt;/p&gt;
&lt;p&gt;Management: &amp;ldquo;Hey, this guy is not smiling! Do something about it!&amp;rdquo;&lt;br/&gt;
Intern: &amp;ldquo;Whatever, I'll just photograph my girlfriend's mouth from this entirely different angle and slap it on. It's not as if this photo will be visible for a long time, anyway.&amp;rdquo;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://typethinker.blogspot.com/feeds/8144052584198290178/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3365890222783870731&amp;postID=8144052584198290178" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/8144052584198290178?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/8144052584198290178?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typethinker/~3/h9IJ3Lhkolw/programmers-are-not-artists.html" title="Programmers are not artists" /><author><name>Thomas ten Cate</name><uri>http://www.blogger.com/profile/02609144861191873031</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_JMO36jorXIA/S0wr7D0dGZI/AAAAAAAAAgk/FAd0WcI0R98/s72-c/The+Face.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://typethinker.blogspot.com/2010/01/programmers-are-not-artists.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEYHQHk5eSp7ImA9WxBTGUg.&quot;"><id>tag:blogger.com,1999:blog-3365890222783870731.post-2381210151399875074</id><published>2009-12-16T10:31:00.001+01:00</published><updated>2009-12-16T10:35:31.721+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-16T10:35:31.721+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="software" /><title>Unfortunate cutoff</title><content type="html">&lt;p&gt;If you are writing a piece of text that may be cut off, pay some extra attention to your first sentence&amp;hellip;&lt;/p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_JMO36jorXIA/SyipltVkNLI/AAAAAAAAAgA/ddNoYq1ifTI/s1600-h/virus.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 60px;" src="http://1.bp.blogspot.com/_JMO36jorXIA/SyipltVkNLI/AAAAAAAAAgA/ddNoYq1ifTI/s400/virus.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5415765017203324082" /&gt;&lt;/a&gt;</content><link rel="replies" type="application/atom+xml" href="http://typethinker.blogspot.com/feeds/2381210151399875074/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3365890222783870731&amp;postID=2381210151399875074" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/2381210151399875074?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/2381210151399875074?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typethinker/~3/8z28ZXO8o-I/unfortunate-cutoff.html" title="Unfortunate cutoff" /><author><name>Thomas ten Cate</name><uri>http://www.blogger.com/profile/02609144861191873031</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_JMO36jorXIA/SyipltVkNLI/AAAAAAAAAgA/ddNoYq1ifTI/s72-c/virus.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://typethinker.blogspot.com/2009/12/unfortunate-cutoff.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0EMRHw9fip7ImA9WxBTEEQ.&quot;"><id>tag:blogger.com,1999:blog-3365890222783870731.post-8448503860628615323</id><published>2009-12-06T11:13:00.005+01:00</published><updated>2009-12-06T11:34:45.266+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-06T11:34:45.266+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="software" /><title>Reinstalling GRUB with LVM from the Ubuntu cd</title><content type="html">&lt;p&gt;This post is mostly a reminder to myself. Every time I reinstall Windows, it overwrites my boot sector, and I need to reinstall it from the Ubuntu live CD to get my dual-boot system back. However, since my Ubuntu install is inside an LVM partition, this is not very straightforward. Here are the instructions. I kept them general so that they may be of use to someone else as well.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start from the Ubuntu CD and open a terminal.&lt;/li&gt;
&lt;li&gt;Install LVM:&lt;br/&gt;
&lt;code&gt;sudo apt-get install lvm2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Find the name of the volume group:&lt;br/&gt;
&lt;code&gt;sudo vgdisplay&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Make the volume group available:&lt;br/&gt;
&lt;code&gt;sudo vgchange -ay &lt;em&gt;name-of-vg&lt;/em&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Mount the root and boot file systems, and bind the dev file system:&lt;br/&gt;
&lt;code&gt;sudo mkdir foo&lt;br/&gt;
sudo mount /dev/&lt;em&gt;name-of-vg&lt;/em&gt;/&lt;em&gt;name-of-root-lv&lt;/em&gt; foo&lt;br/&gt;
sudo mount /dev/&lt;em&gt;name-of-boot-partition&lt;/em&gt; foo/boot&lt;br/&gt;
sudo mount -obind /dev foo/dev&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Change to the root of your system:&lt;br/&gt;
&lt;code&gt;sudo chroot foo&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Drop into the GRUB prompt:&lt;br/&gt;
&lt;code&gt;sudo grub&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Install the GRUB MBR (assuming that &lt;code&gt;(hd0)&lt;/code&gt; is your boot drive and &lt;code&gt;(hd0,0)&lt;/code&gt; your boot partition):&lt;br/&gt;
&lt;code&gt;root (hd0,0)&lt;br/&gt;
setup (hd0)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Reboot and have your boot menu back!&lt;/li&gt;
&lt;/ul&gt;</content><link rel="replies" type="application/atom+xml" href="http://typethinker.blogspot.com/feeds/8448503860628615323/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3365890222783870731&amp;postID=8448503860628615323" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/8448503860628615323?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/8448503860628615323?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typethinker/~3/ATOLvx1Hjt0/reinstalling-grub-with-lvm-from-ubuntu.html" title="Reinstalling GRUB with LVM from the Ubuntu cd" /><author><name>Thomas ten Cate</name><uri>http://www.blogger.com/profile/02609144861191873031</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://typethinker.blogspot.com/2009/12/reinstalling-grub-with-lvm-from-ubuntu.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYEQnw9fip7ImA9WxNWGEw.&quot;"><id>tag:blogger.com,1999:blog-3365890222783870731.post-3589197490931149507</id><published>2009-10-17T22:00:00.002+02:00</published><updated>2009-10-17T22:08:23.266+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-17T22:08:23.266+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="software" /><title>Disabled for your protection</title><content type="html">&lt;p&gt;My Firefox, on Windows, just reported that it had disabled the Microsoft .NET Framework Assistant 1.1 extension and the Windows Presentation Foundation plugin. Supposedly, these were security issues. If I'd be so kind as to restart the browser for the changes to take effect.&lt;/p&gt;
&lt;p&gt;Well, whatever, go ahead. After the restart, the Extensions window pops up, showing .NET Framework Assistant as &amp;ldquo;Disabled for your protection.&amp;rdquo; Phew, thank you.&lt;/p&gt;
&lt;p&gt;But now I'm curious. What's so evil about these Microsoft plugins that Mozilla feels the need to block them automatically? Luckily, there is a &amp;ldquo;More Information&amp;rdquo; link right there in the dialogue! So I click it:&lt;/p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_JMO36jorXIA/StojiTuFvMI/AAAAAAAAAfI/dnzGjl7WIjE/s1600-h/firefox-security.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 359px;" src="http://3.bp.blogspot.com/_JMO36jorXIA/StojiTuFvMI/AAAAAAAAAfI/dnzGjl7WIjE/s400/firefox-security.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5393662576045702338" /&gt;&lt;/a&gt;
&lt;p&gt;It's great to see that Mozilla really cares about my security.&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://typethinker.blogspot.com/feeds/3589197490931149507/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3365890222783870731&amp;postID=3589197490931149507" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/3589197490931149507?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/3589197490931149507?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typethinker/~3/VEZy26Kk8Eg/disabled-for-your-protection.html" title="Disabled for your protection" /><author><name>Thomas ten Cate</name><uri>http://www.blogger.com/profile/02609144861191873031</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_JMO36jorXIA/StojiTuFvMI/AAAAAAAAAfI/dnzGjl7WIjE/s72-c/firefox-security.png" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://typethinker.blogspot.com/2009/10/disabled-for-your-protection.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C04AQXc-cSp7ImA9WxNQGEs.&quot;"><id>tag:blogger.com,1999:blog-3365890222783870731.post-7627462124781317776</id><published>2009-09-25T08:41:00.007+02:00</published><updated>2009-09-25T08:59:00.959+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-25T08:59:00.959+02:00</app:edited><title>Digital signatures made easy</title><content type="html">&lt;p&gt;Some time ago, a friend of mine discovered that somebody was plagiarizing the content of this blog. I'm not going to provide this guy with link juice, but you can find it through &lt;a href="http://www.google.com/search?q=&amp;quot;incorrect+application+configuration&amp;quot;"&gt;Google&lt;/a&gt; easily. The post is an exact duplicate of my &lt;a href="http://typethinker.blogspot.com/2007/12/visual-c-application-configuration.html"&gt;Visual C++/Studio: Application configuration incorrect?&lt;/a&gt;, except for the title. Even my remark at the end, which clearly suggests that the author of the post is also a developer on &lt;a href="http://taekwindow.sf.net/"&gt;Taekwindow&lt;/a&gt;, has been copied with the link intact.&lt;/p&gt;

&lt;p&gt;Now imitation is the sincerest form of flattery and all that, but stealing my content without even mentioning my name goes too far. I posted as much on this guy's blog, but have received no response. So in the end I overcame my aversion and filed a &lt;a href="http://www.google.com/support/blogger/bin/request.py?contact_type=blogger_dmca_infringment"&gt;DMCA infringement notification&lt;/a&gt; to Blogger.&lt;/p&gt;

&lt;p&gt;Have a look at that form. Scroll all the way down. What will you see?
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_JMO36jorXIA/Srxn_IXhzpI/AAAAAAAAAfA/y4CVzGj_Fag/s1600-h/signature.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:left;cursor:pointer; cursor:hand;width: 396px; height: 62px;" src="http://4.bp.blogspot.com/_JMO36jorXIA/Srxn_IXhzpI/AAAAAAAAAfA/y4CVzGj_Fag/s400/signature.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5385293588703858322" /&gt;&lt;/a&gt;
Look at that! Isn't it beautiful? I'm supposed to &lt;em&gt;sign a digital form&lt;/em&gt;&amp;hellip; by typing my &amp;ldquo;signature&amp;rdquo; in a text box! Also, this is &lt;em&gt;legally binding&lt;/em&gt;!&lt;/p&gt;

&lt;p&gt;That cracked me up. It cracked me up so completely that I typed a beautiful capital X in that box and hit Submit.&lt;/p&gt;

&lt;p&gt;Today, I received an e-mail from Blogger. It said:&lt;/p&gt;

&lt;blockquote&gt;We have received your DMCA complaint regarding &lt;em&gt;no-link-juice-for-you&lt;/em&gt;.blogspot.com dated 09/20/09. Our policy requires that DMCA complaints be signed by the copyright owner or an agent of such. As your DMCA complaint was unsigned, we cordially request that you re-send us a signed copy of your notice by fax to (650) 618-2680. Once we receive your complaint, we will investigate the issue and process your request accordingly.&lt;/blockquote&gt;

&lt;p&gt;I still wonder what would have happened if I'd just typed my name into that box.&lt;/p&gt;

&lt;p&gt;Hilarious.&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://typethinker.blogspot.com/feeds/7627462124781317776/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3365890222783870731&amp;postID=7627462124781317776" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/7627462124781317776?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/7627462124781317776?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typethinker/~3/rHuDfh0FXFI/some-time-ago-friend-of-mine-discovered.html" title="Digital signatures made easy" /><author><name>Thomas ten Cate</name><uri>http://www.blogger.com/profile/02609144861191873031</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_JMO36jorXIA/Srxn_IXhzpI/AAAAAAAAAfA/y4CVzGj_Fag/s72-c/signature.png" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://typethinker.blogspot.com/2009/09/some-time-ago-friend-of-mine-discovered.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0IARng7fip7ImA9WxNRGUw.&quot;"><id>tag:blogger.com,1999:blog-3365890222783870731.post-1844485330617918879</id><published>2009-09-14T11:04:00.003+02:00</published><updated>2009-09-14T11:12:27.606+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-14T11:12:27.606+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="latex" /><title>Centering a figure on the page in LaTeX</title><content type="html">&lt;p&gt;With those wide margins of LaTeX, it sometimes happens that you have a figure or table that is too wide, and just sticks out to the right. Chances are that you want it centered, sticking out equally to the right and to the left, but tough luck: the standard &lt;code&gt;center&lt;/code&gt; environment still aligns it with the left margin, and so does the &lt;code&gt;\centering&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;I was about to write a package to provide an environment that centers its content on the &lt;em&gt;page&lt;/em&gt; instead of inside the text. This is not too difficult, but preventing the &lt;code&gt;overfull \hbox&lt;/code&gt; errors is tricky (they are so bad that even &lt;code&gt;\hbadness=10000&lt;/code&gt; has no effect). But then I stumbled into a standard LaTeX command that does exactly what I want.&lt;/p&gt;

&lt;p&gt;So here's how to center your figure whilst ignoring the text margins:&lt;br/&gt;
&lt;code&gt;\centerline{\includegraphics{...}}&lt;/code&gt;&lt;br/&gt;
It also works inside float environments such as &lt;code&gt;figure&lt;/code&gt;. That was easy!&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://typethinker.blogspot.com/feeds/1844485330617918879/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3365890222783870731&amp;postID=1844485330617918879" title="11 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/1844485330617918879?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/1844485330617918879?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typethinker/~3/WNTcIy9lbQI/centering-figure-on-page-in-latex.html" title="Centering a figure on the page in LaTeX" /><author><name>Thomas ten Cate</name><uri>http://www.blogger.com/profile/02609144861191873031</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>11</thr:total><feedburner:origLink>http://typethinker.blogspot.com/2009/09/centering-figure-on-page-in-latex.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEANQnoyfSp7ImA9WxJVFkw.&quot;"><id>tag:blogger.com,1999:blog-3365890222783870731.post-3509106127650196632</id><published>2009-07-03T12:20:00.002+02:00</published><updated>2009-07-03T12:26:33.495+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-03T12:26:33.495+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="software" /><title>Speeding up Kile</title><content type="html">&lt;p&gt;Even though I'm mostly a Gnome user, my LaTeX editor of choice is &lt;a href="http://kile.sourceforge.net/"&gt;Kile&lt;/a&gt;. Unfortunately, it can become a &lt;a href="http://bugs.kde.org/show_bug.cgi?id=171099"&gt;bit sluggish&lt;/a&gt;, especially when dealing with long lines. (I hate artificial line breaks, so I just type one line per paragraph and turn on dynamic word wrapping.)&lt;/p&gt;

&lt;p&gt;This seems to have something to do with rendering. To make Kile considerably faster, start it like this:&lt;br/&gt;
&lt;code&gt;kile --graphicssystem raster&lt;/code&gt;&lt;br/&gt;
Instead of &lt;code&gt;raster&lt;/code&gt;, you can also try &lt;code&gt;opengl&lt;/code&gt;, which is &lt;a href="http://labs.trolltech.com/blogs/2008/10/22/so-long-and-thanks-for-the-blit/"&gt;supposed to be even faster&lt;/a&gt;, but not considered stable yet. YMMV.&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://typethinker.blogspot.com/feeds/3509106127650196632/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3365890222783870731&amp;postID=3509106127650196632" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/3509106127650196632?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/3509106127650196632?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typethinker/~3/4H4TlOMnR_s/speeding-up-kile.html" title="Speeding up Kile" /><author><name>Thomas ten Cate</name><uri>http://www.blogger.com/profile/02609144861191873031</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://typethinker.blogspot.com/2009/07/speeding-up-kile.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkINR385cCp7ImA9WxJWFE0.&quot;"><id>tag:blogger.com,1999:blog-3365890222783870731.post-9115574886839560014</id><published>2009-06-15T15:56:00.002+02:00</published><updated>2009-06-19T11:43:16.128+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-19T11:43:16.128+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="software" /><title>Creating a multi-page PDF from images</title><content type="html">&lt;p&gt;It is often convenient to pour a series of JPEG (or PNG, or GIF) files into a PDF, for example for printing or for e-mailing. Given the power of the Linux command line, this is surprisingly difficult, but I found a fairly straightforward way to do it. Skip to the bottom if you just want the oneliner.&lt;/p&gt;

&lt;p&gt;Many websites will tell you the following:&lt;br/&gt;
&lt;code&gt;convert *.jpg output.pdf&lt;/code&gt;&lt;br/&gt;
Easy, no? &lt;strong&gt;Don't do this.&lt;/strong&gt; Why? Look at this:&lt;/p&gt;
&lt;pre&gt;-rw-r--r--  1 thomas thomas &lt;strong&gt;129826204&lt;/strong&gt; 2009-06-15 15:29 output.pdf
-rw-r--r--  1 thomas thomas    947022 2009-06-15 15:04 page1.jpg
-rw-r--r--  1 thomas thomas    962956 2009-06-15 15:05 page2.jpg
-rw-r--r--  1 thomas thomas    925291 2009-06-15 12:54 page3.jpg
-rw-r--r--  1 thomas thomas    952717 2009-06-15 12:54 page4.jpg
-rw-r--r--  1 thomas thomas    642471 2009-06-15 15:08 page5.jpg
&lt;/pre&gt;
&lt;p&gt;The original JPG files are less than 5 MB altogether, but the resulting PDF is a whopping 124 MB! Clearly, &lt;code&gt;convert&lt;/code&gt; (from the otherwise excellent &lt;a href="http://www.imagemagick.org/"&gt;ImageMagick&lt;/a&gt; bundle) re-encodes the images somehow, instead of embedding them straight into the PDF file.&lt;/p&gt;

&lt;p&gt;Enter the little-known utility &lt;a href="http://www.inf.bme.hu/~pts/sam2p/"&gt;&lt;code&gt;sam2p&lt;/code&gt;&lt;/a&gt;. It comes in an Ubuntu package of the same name. In its simplest form, it converts a single image file into a PDF by embedding the image file into the PDF file. For example:&lt;br/&gt;
&lt;code&gt;sam2p page1.jpg page1.pdf&lt;br/&gt;&lt;/code&gt;
One of the shortcomings of &lt;code&gt;sam2p&lt;/code&gt; is that it does not allow you to set the page size directly, so you'll end up with PDFs that exactly fit the original images.&lt;/p&gt;

&lt;p&gt;Now we can generate all the pages as separate PDFs, but &lt;code&gt;sam2p&lt;/code&gt; cannot create a PDF with multiple pages. Enter &lt;code&gt;pdfjoin&lt;/code&gt; from the &lt;a href="http://go.warwick.ac.uk/pdfjam"&gt;&lt;code&gt;pdfjam&lt;/code&gt;&lt;/a&gt; package (available in Ubuntu under that name). It is simple to use:&lt;br/&gt;
&lt;code&gt;pdfjoin page*.pdf --outfile output.pdf&lt;br/&gt;&lt;/code&gt;
This will use a consistent page size, so it is no problem that &lt;code&gt;sam2p&lt;/code&gt; spit out pages of arbitrary size. It defaults to A4 paper; specify &lt;code&gt;--paper letterpaper&lt;/code&gt; to use the Letter format.&lt;/p&gt;

&lt;p&gt;Because I'm lazy, I wrote a little &lt;code&gt;bash&lt;/code&gt; oneliner to do the trick, then let my readers improve upon it (thanks Mark, thanks Eamon!). It is now a twoliner, but who cares:&lt;br/&gt;
&lt;code&gt;find . -maxdepth 1 -iname 'page*.jpg' -exec sam2p '{}' '{}'.pdf \;&lt;br/&gt;
pdfjoin page*.pdf --outfile output.pdf&lt;br/&gt;&lt;/code&gt;
This assumes that your input images are named &lt;code&gt;page1.jpg&lt;/code&gt;, &lt;code&gt;page2.jpg&lt;/code&gt; etcetera, and that there are no files named like &lt;code&gt;page*.pdf&lt;/code&gt; in the current directory. If you have more than 9 pages, remember to prefix a zero to keep them in order. If you want to do this for PNG or other images, remember to change the extension in both places.&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://typethinker.blogspot.com/feeds/9115574886839560014/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3365890222783870731&amp;postID=9115574886839560014" title="10 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/9115574886839560014?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/9115574886839560014?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typethinker/~3/Y1BavMXYwdU/creating-multi-page-pdf-from-images.html" title="Creating a multi-page PDF from images" /><author><name>Thomas ten Cate</name><uri>http://www.blogger.com/profile/02609144861191873031</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>10</thr:total><feedburner:origLink>http://typethinker.blogspot.com/2009/06/creating-multi-page-pdf-from-images.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMCR3cyeip7ImA9WxJRF04.&quot;"><id>tag:blogger.com,1999:blog-3365890222783870731.post-5288679235767066976</id><published>2009-05-19T14:32:00.001+02:00</published><updated>2009-05-19T14:34:26.992+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-19T14:34:26.992+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="software" /><title>Windows Genuine "Advantage"</title><content type="html">&lt;p&gt;My Windows is genuine. I fail to see the advantage.&lt;/p&gt;
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_JMO36jorXIA/ShKnNWFt07I/AAAAAAAAAco/nQ1xD9-GaOU/s1600-h/genuine-advantage.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 121px;" src="http://3.bp.blogspot.com/_JMO36jorXIA/ShKnNWFt07I/AAAAAAAAAco/nQ1xD9-GaOU/s400/genuine-advantage.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5337512356097151922" /&gt;&lt;/a&gt;</content><link rel="replies" type="application/atom+xml" href="http://typethinker.blogspot.com/feeds/5288679235767066976/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3365890222783870731&amp;postID=5288679235767066976" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/5288679235767066976?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/5288679235767066976?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typethinker/~3/3vyEmzE_OxI/windows-genuine-advantage.html" title="Windows Genuine &quot;Advantage&quot;" /><author><name>Thomas ten Cate</name><uri>http://www.blogger.com/profile/02609144861191873031</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_JMO36jorXIA/ShKnNWFt07I/AAAAAAAAAco/nQ1xD9-GaOU/s72-c/genuine-advantage.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://typethinker.blogspot.com/2009/05/windows-genuine-advantage.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMHR3k9eSp7ImA9WxJREkk.&quot;"><id>tag:blogger.com,1999:blog-3365890222783870731.post-5661450908708023389</id><published>2009-05-13T22:55:00.002+02:00</published><updated>2009-05-13T23:00:36.761+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-13T23:00:36.761+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="personal" /><category scheme="http://www.blogger.com/atom/ns#" term="software" /><title>Accepted for Google Summer of Code!</title><content type="html">&lt;p&gt;I have been accepted for Google Summer of Code 2009! The title of my project is &amp;ldquo;Extend EclipseFP functionality for Haskell.&amp;rdquo; I have just set up a blog where I can keep all posts together that are related to this project. (This blog will also allow me to test-drive Wordpress, because as we all know &lt;a href="http://typethinker.blogspot.com/2007/04/blogger-is-bad-mmkay.html"&gt;Blogger&lt;/a&gt; &lt;a href="http://typethinker.blogspot.com/2008/09/news-flash-blogger-still-sucks.html"&gt;sucks&lt;/a&gt;.) You can find more information at my new blog: &lt;a href="http://eclipsefp.wordpress.com/"&gt;EclipseFP GSoC '09&lt;/a&gt;.&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://typethinker.blogspot.com/feeds/5661450908708023389/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=3365890222783870731&amp;postID=5661450908708023389" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/5661450908708023389?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/3365890222783870731/posts/default/5661450908708023389?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/typethinker/~3/d0bWfxgBK9I/accepted-for-google-summer-of-code.html" title="Accepted for Google Summer of Code!" /><author><name>Thomas ten Cate</name><uri>http://www.blogger.com/profile/02609144861191873031</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://typethinker.blogspot.com/2009/05/accepted-for-google-summer-of-code.html</feedburner:origLink></entry></feed>
