<?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: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;C0ECQ3Y4cSp7ImA9WhVUE0U.&quot;"><id>tag:blogger.com,1999:blog-6112936277054198647</id><updated>2012-05-19T08:54:22.839+10:00</updated><category term="workflow" /><category term="synaptics" /><category term="xds" /><category term="mpx" /><category term="tutorial" /><category term="freedesktop.org" /><category term="fedora" /><category term="xkb" /><category term="wacom" /><category term="hal" /><category term="evtest" /><category term="xi2" /><category term="gnome" /><category term="x" /><category term="xorg" /><category term="xts" /><category term="tig" /><category term="configuration" /><category term="git" /><category term="outdoors" /><category term="xorg.conf" /><category term="input device properties" /><category term="compiz" /><category term="gnome-device-setup" /><category term="evdev" /><category term="multitouch" /><category term="xlib" /><title>Who-T</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://who-t.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://who-t.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Peter Hutterer</name><uri>http://www.blogger.com/profile/17204066043271384535</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>109</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/Who-t" /><feedburner:info uri="who-t" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;DEQAQ3kyeyp7ImA9WhVUE08.&quot;"><id>tag:blogger.com,1999:blog-6112936277054198647.post-2840097443696556710</id><published>2012-05-18T17:32:00.000+10:00</published><updated>2012-05-18T17:32:22.793+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-05-18T17:32:22.793+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="outdoors" /><title>Home-made 4WD rooftop awning</title><content type="html">This article describes how to build your own rooftop awning. I recommend that if you do want an awning, purchase one from a store. They have come down in price considerably since I built mine.

If you do go ahead, make sure to check with your local transportation authority and check whether such a device is legal in your country/state.&lt;br /&gt;
&lt;br /&gt;
Anyway, let's start. A while ago I wanted a rooftop awning but I didn't want to pay that much money. In Australia, these awnings go for several hundred dollars, and the small ones are indeed quite small. So I built my own, instructions are below. This is how it looks like:&lt;br /&gt;&lt;br/&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-dITbSuSNpWE/T7OFbmPbjKI/AAAAAAAAA6w/08OPoXfvk0k/s1600/beach.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="192" width="320" src="http://3.bp.blogspot.com/-dITbSuSNpWE/T7OFbmPbjKI/AAAAAAAAA6w/08OPoXfvk0k/s320/beach.jpg" /&gt;&lt;/a&gt;&lt;br/&gt;
Sometimes it's a tough life...
&lt;/div&gt;


&lt;br /&gt;
The ingredients are:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;tarp with metal eyelets. IIRC mine is 2.4 x 3.0m &lt;a href="http://www.bunnings.com.au/products_product_tarpaulin-medium-duty-160gm2_7789.aspx?search=tarpaulin&amp;amp;searchType=any&amp;amp;searchSubType=products"&gt;(similar one)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;3m 25x25mm aluminium square tube (or width of tarp otherwise)&lt;/li&gt;
&lt;li&gt;Two plastic caps for the square tube&lt;/li&gt;
&lt;li&gt;Four 1.5 inch 3/8 bolts + nuts + washers&lt;/li&gt;
&lt;li&gt;Four 2 inch 3/8 bolts + nuts + washers&lt;/li&gt;
&lt;li&gt;Four poles, one crossbar, ropes, pegs&lt;/li&gt;
&lt;li&gt;Wide (~5cm) velcro, 1 m is sufficient (makes 3 strips)&lt;/li&gt;
&lt;/ul&gt;
&lt;br/&gt;
Most of the stuff I got from Bunnings, the poles from the camping store and the velcro from a textile store next to the BCF at Cannon Hill.&lt;br/&gt;
&lt;br /&gt;
The basic design is simple. The tarp is held onto the square tube by a bunch of vertical bolts - one per tarp eyelet. The crossbar, which is too long for my tray, is held in place by two horizontal bolts, on the inside (towards the car). The tarp is folded in half, then rolled up and held in place by three strips of velcro.
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-FxGwHb9tZ0s/T7XyPsWYCiI/AAAAAAAAA7Y/D2Y5KrgFC6U/s1600/tarp-rolled-up.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="214" width="320" src="http://2.bp.blogspot.com/-FxGwHb9tZ0s/T7XyPsWYCiI/AAAAAAAAA7Y/D2Y5KrgFC6U/s320/tarp-rolled-up.jpg" /&gt;&lt;/a&gt;&lt;br/&gt;Tarp when rolled up for transport.&lt;/div&gt;
&lt;br /&gt;
I have Rhino Rack Aero bars and the bolts I got had a head exactly the size of the groove. So I don't need mountings, I simply push the screw into the groove, then sit the awning on it and tighten the nut up the top. And, second time lucky, the eyelets are the distance of my roof racks, so I don't have to do anything there either.
&lt;br /&gt;

&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-5XsWnRsrkdk/T7OHqxaEUbI/AAAAAAAAA7I/EgXkUV-Wtvg/s1600/rack-fitting.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="320" width="213" src="http://1.bp.blogspot.com/-5XsWnRsrkdk/T7OHqxaEUbI/AAAAAAAAA7I/EgXkUV-Wtvg/s320/rack-fitting.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;
The bolt fits exactly into the groove - lucky me :) &lt;br/&gt;Obscured by the rolled-up tarp is the top end of the bolt - simply a washer and a nut.
&lt;/div&gt;

&lt;br/&gt;

&lt;h2&gt;Assembly instructions&lt;/h2&gt;
&lt;br /&gt;
Drill a hole a few cm in from one ond of the square tube. Now take a bolt and nut, screw the tarp's corner to the tube. Stretch it to the other end, drill another hole, bolt, nut, done. The tarp should be tightly stretched. Now mark each eyelets in the middle for more holes. Take the tarp off, drill the remaining holes, then saw the excess square tube off.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-1RIS2VE9xQ0/T7XzubMBQHI/AAAAAAAAA7k/uTNa91DlRuU/s1600/bolt.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="320" width="213" src="http://2.bp.blogspot.com/-1RIS2VE9xQ0/T7XzubMBQHI/AAAAAAAAA7k/uTNa91DlRuU/s320/bolt.jpg" /&gt;&lt;/a&gt;&lt;br/&gt;Bolt shown from the side&lt;/div&gt;

&lt;br /&gt;
As said above, my roof racks are exactly the distance of the eyelets, so I don't need extra mountings. The professional awnings have an L-shaped attachment that goes into the roof racks and the awning then hangs off the side. &lt;a href="http://blkmav.com/prado/awning2.jpg"&gt;This photo&lt;/a&gt; shows the attachment, the same should be possible on this home-made model.&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;
The final bit are two horizontal drillings through the tube. They are for mounting the crossbar next to the tube. I transport the four poles, the ropes and the pegs in the tray.&lt;br /&gt;

&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-HFFaoOLODs4/T7X1Tk1YyxI/AAAAAAAAA7w/DQslh9qOEsw/s1600/crossbar-mount.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="320" width="213" src="http://2.bp.blogspot.com/-HFFaoOLODs4/T7X1Tk1YyxI/AAAAAAAAA7w/DQslh9qOEsw/s320/crossbar-mount.jpg" /&gt;&lt;/a&gt;&lt;br/&gt;
Crossbar mount. The bolt is horizontal when mounted.
&lt;/div&gt;



&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-4pytYiBa97s/T7OHJDI9ayI/AAAAAAAAA68/XtZskqRbpJ0/s1600/side.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="213" width="320" src="http://3.bp.blogspot.com/-4pytYiBa97s/T7OHJDI9ayI/AAAAAAAAA68/XtZskqRbpJ0/s320/side.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;
The front bit of the rolled-up awning, taken from the other side of the car, showing the crossbar mount.
&lt;/div&gt;

&lt;br /&gt;
Setting it up is simple enough, though it does require 2 people. It takes a few minutes to set up, a few minutes to pack up again. If the tarp gives up, I can (hopefully) buy another one and replace it.&lt;br /&gt;
&lt;br /&gt;
Costs for me was just over AUD 100, including the crossbar and the poles. If you already have those, you're obviously able to build it for much less.

&lt;br/&gt; &lt;br /&gt;
&lt;h2&gt;Side notes&lt;/h2&gt;
As I have the handyman's knowledge of a five-year-old, I did a few things wrong. First,
Bunnings sells bolts in imperial and metric. Had I known that, I'd have bought metric screws. I ended up just getting the first set that matched the size I needed. The metric section was a few metres further down the aisle. &lt;br /&gt; &lt;br /&gt;
The first set of (round capped) nuts wasn't galvanised and started rusting (you can see it in the photos). Haven't been able to find galvanised ones for the imperial bolts, so I've since replaced them with galvanised normal nuts.&lt;br /&gt;&lt;br /&gt;
&lt;h2&gt;Pros and Cons&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;It's freaking awesome! Having a shady spot next to the car wherever you roll up is great!&lt;/li&gt;
&lt;li&gt;The awning is big. Not much of an issue once it's mounted but it's pretty unwieldy in the garage.&lt;/li&gt;
&lt;li&gt;The surface area covered is perfect for two people and a table, so no issues there.&lt;/li&gt;
&lt;li&gt;The awning is not free-standing. I believe the commercial models are, but this one needs to be pegged down. Which means that moving the car once it's set up is a no-go, you have to tear it down.&lt;/li&gt;
&lt;li&gt;The way I roll it results in rain collecting in the rolled-up tarp. I could roll it the other way, but that's a bit awkward. No big issue though, except after a good rain when you break at the first set of lights, a few litres of water will run down your windscreen :) &lt;/li&gt;
&lt;li&gt;I can't yet claim how it will hold up in a typical Queensland wind or thunderstorm. I think it will be alright, but so far I've only had it up during light winds and light rain.&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6112936277054198647-2840097443696556710?l=who-t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Who-t/~4/aF9qESGPjJ4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://who-t.blogspot.com/feeds/2840097443696556710/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6112936277054198647&amp;postID=2840097443696556710" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/2840097443696556710?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/2840097443696556710?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Who-t/~3/aF9qESGPjJ4/home-made-4wd-rooftop-awning.html" title="Home-made 4WD rooftop awning" /><author><name>Peter Hutterer</name><uri>http://www.blogger.com/profile/17204066043271384535</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/-dITbSuSNpWE/T7OFbmPbjKI/AAAAAAAAA6w/08OPoXfvk0k/s72-c/beach.jpg" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://who-t.blogspot.com/2012/05/home-made-4wd-rooftop-awning.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUMRX0-eip7ImA9WhVVFkQ.&quot;"><id>tag:blogger.com,1999:blog-6112936277054198647.post-7440622670581948654</id><published>2012-05-10T09:15:00.000+10:00</published><updated>2012-05-11T08:51:24.352+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-05-11T08:51:24.352+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="xorg" /><category scheme="http://www.blogger.com/atom/ns#" term="workflow" /><title>Testing X servers from git</title><content type="html">Every so-often I get asked the question of how to test the X server (or drivers) from git. The setup I have is quite simple: I have a full tree in /opt/xorg, next to the system-installed binaries in /usr. A symlink and some environment variables allow me to switch between git versions of the server and clients and the system-installed ones.
&lt;br/&gt;&lt;br/&gt;
&lt;h2&gt;Installing the tree&lt;/h2&gt;
Getting that setup is quite easy these days:

&lt;small&gt;
&lt;/small&gt;&lt;br /&gt;
&lt;pre&gt;&lt;small&gt;mkdir -p xorg/util
git clone git://anongit.freedesktop.org/git/xorg/util/modular xorg/util/modular
cd xorg
./util/modular/build.sh --clone --autoresume built.modules /opt/xorg
&lt;/small&gt;&lt;/pre&gt;
&lt;small&gt;
&lt;/small&gt;

That takes a while but if any component fails to build (usually due to missing dependencies) just re-run the last command. The built.modules file contains all successfully built modules and the script will simply continue from the last component. Despite the name, build.sh will also &lt;i&gt;install&lt;/i&gt; each component into the specified prefix.&lt;br /&gt;
&lt;br /&gt;
You get &lt;i&gt;everything&lt;/i&gt; here, including a shiny new copy of xeyes. Yes, what you always wanted, I know &lt;br /&gt;
&lt;br /&gt;
Note that build.sh is just a &lt;a href="http://cgit.freedesktop.org/xorg/util/modular/tree/build.sh"&gt;shell script&lt;/a&gt;, so you can make changes to it. Disable the parts you don't want (fonts, for example) by commenting them out. Or alternatively, generate a list of all modules, remove the ones you don't want or need and build with that set only:
&lt;pre&gt;
&lt;small&gt;
./util/modular/build.sh -L &gt; module_list
vim module_list # you can skip fonts, apps (except xkbcomp) and exotic drivers
./util/modular/build.sh --clone --autoresume built.modules --modfile module_list /opt/xorg
&lt;/small&gt;
&lt;/pre&gt;

Either way, you end up with /opt/xorg/bin/Xorg, the X server binary. I just move my system-installed and then symlink the new one.&lt;br/&gt;
&lt;br /&gt;

&lt;pre&gt;&lt;small&gt;sudo mv /usr/bin/Xorg /usr/bin/Xorg_old
sudo ln -s /opt/xorg/bin/Xorg /usr/bin/Xorg
&lt;/small&gt;&lt;/pre&gt;

Next time when gdm starts the server, it'll start the one from git. You can now update modules from git one-by-one as you need to and just run make install in all of them. Alternatively, running the build.sh script again without the --clone parameter will simply git pull in each module.
&lt;br/&gt;&lt;br/&gt;
&lt;h2&gt;Setting up the environment&lt;/h2&gt;
What I then define is a few environment variables. In my .zshrc I have
&lt;pre&gt;&lt;small&gt;alias mpx=". $HOME/.exportrc.xorg"
&lt;/small&gt;&lt;/pre&gt;
and that file contains
&lt;pre&gt;&lt;small&gt;export PKG_CONFIG_PATH=/opt/xorg/lib/pkgconfig:/opt/xorg/share/pkgconfig
export LD_LIBRARY_PATH=/opt/xorg/lib/
export PATH=/opt/xorg/bin:$PATH
export ACLOCAL="aclocal -I /opt/xorg/share/aclocal"
export MANPATH=/opt/xorg/share/man/
&lt;/small&gt;&lt;/pre&gt;
So running "mpx" will start git versions of the clients, link clients against git versions of the libraries, or build against git versions of the protocol.
&lt;br/&gt;&lt;br/&gt;
&lt;h2&gt;Why this setup?&lt;/h2&gt;

The biggest advantage of this setup is simple: the system install doesn't get touched at all and if the git X server breaks changing the symlink back to /usr/bin/Xorg_old gives me a working X again. And it's equally quick to test Fedora rpms, just flick the symlink back and restart the server. I have similar trees for gnome, wayland, and a few other large projects.&lt;br /&gt;
&lt;br /&gt;
It also makes it simple to test if a specific bug is a distribution bug or an upstream bug. Install the matching X server branch instead of master and with a bit of symlink flicking you can check if the bug reproduces in both. For example, only a few weeks ago I noticed that xinput got BadAtom errors when run from /usr/bin but not when run from /opt/xorg/bin. Turns out it was a thing fixed in the upstream libXi but not backported to Fedora yet.&lt;br /&gt;&lt;br /&gt;

The drawback of this setup is that whenever the xorg-x11-server-Xorg module is updated, I need to move and symlink again. That could be automated with a script but so far I've just been too lazy to do it.&lt;br/&gt;&lt;br/&gt;

&lt;small&gt;
[Update 11.05.12: typo and minor fixes, explain build.sh -L]
&lt;/small&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6112936277054198647-7440622670581948654?l=who-t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Who-t/~4/qfsoV_yMXvk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://who-t.blogspot.com/feeds/7440622670581948654/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6112936277054198647&amp;postID=7440622670581948654" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/7440622670581948654?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/7440622670581948654?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Who-t/~3/qfsoV_yMXvk/testing-x-servers-from-git.html" title="Testing X servers from git" /><author><name>Peter Hutterer</name><uri>http://www.blogger.com/profile/17204066043271384535</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>4</thr:total><feedburner:origLink>http://who-t.blogspot.com/2012/05/testing-x-servers-from-git.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEINSXcycSp7ImA9WhVVFUw.&quot;"><id>tag:blogger.com,1999:blog-6112936277054198647.post-632444455653174450</id><published>2012-05-09T08:36:00.000+10:00</published><updated>2012-05-09T08:36:38.999+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-05-09T08:36:38.999+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="workflow" /><title>vimdir for project-specific vim settings</title><content type="html">Sometimes it feels that each project I work on has different indentation settings. Not quite true but still annoying. I don't know of a way to tell vim to auto-detect the indentation settings based on the current file (which, for X.Org projects wouldn't work anyway) but what has been incredibly useful is the &lt;a href="http://www.vim.org/scripts/script.php?script_id=1860"&gt;vimdir&lt;/a&gt; script.

It simply scans the directory tree upwards to find a .vimdir file and loads the settings from there. So I keep files like this around:
&lt;pre&gt;
setlocal noexpandtab shiftwidth=8 tabstop=8
&lt;/pre&gt;

The alternative is to add a snippet to the file itself but not every maintainer is happy with that.

&lt;pre&gt;
/* vim: set noexpandtab tabstop=8 shiftwidth=8: */
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6112936277054198647-632444455653174450?l=who-t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Who-t/~4/00q9sYvlvKY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://who-t.blogspot.com/feeds/632444455653174450/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6112936277054198647&amp;postID=632444455653174450" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/632444455653174450?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/632444455653174450?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Who-t/~3/00q9sYvlvKY/vimdir-for-project-specific-vim.html" title="vimdir for project-specific vim settings" /><author><name>Peter Hutterer</name><uri>http://www.blogger.com/profile/17204066043271384535</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://who-t.blogspot.com/2012/05/vimdir-for-project-specific-vim.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0QEQ3w5cCp7ImA9WhVVEU0.&quot;"><id>tag:blogger.com,1999:blog-6112936277054198647.post-3733470202065921083</id><published>2012-05-04T14:21:00.003+10:00</published><updated>2012-05-04T14:21:42.228+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-05-04T14:21:42.228+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="workflow" /><title>Copy/paste of code is not ok</title><content type="html">Much too often, I see patches that add code copied from other sections of the same repository. The usual excuse is that, well, we know that block of code works, it's easy to copy and we immediately get the result we need.&lt;br /&gt;
&lt;br /&gt;
This is rather short-sighted. Whenever code is copied, the two instances will go and live separate lives. Code is never static, over time that copy becomes a partial reimplementation of the original.&lt;br /&gt;
&lt;br /&gt;
There are a few conditions when copy-paste is acceptable:&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;You can guarantee that the original code does not have any bugs and thus the copy does not have any bugs, now or in the future. Otehr&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;You can guarantee that &lt;i&gt;anyone&lt;/i&gt; making changes to this code in the future is aware of the copy and the original and their respective contexts.&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;You can guarantee that the context of the original and the copy never changes in a different manner.&lt;/li&gt;
&lt;br /&gt;
&lt;li&gt;You are happy to reimburse testers and developers for the time wasted tracking down bugs caused by ignoring any of the three above.&lt;/li&gt;
&lt;/ul&gt;
If the above are true, copying code is ok. And you probably get some price for having found an impossible piece of code. In all other cases, write a helper function and share the code. If the helper function is to unwieldy, maybe it's time to think about the design and refactor some things.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6112936277054198647-3733470202065921083?l=who-t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Who-t/~4/mzCNYP9Rkro" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://who-t.blogspot.com/feeds/3733470202065921083/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6112936277054198647&amp;postID=3733470202065921083" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/3733470202065921083?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/3733470202065921083?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Who-t/~3/mzCNYP9Rkro/copypaste-of-code-is-not-ok.html" title="Copy/paste of code is not ok" /><author><name>Peter Hutterer</name><uri>http://www.blogger.com/profile/17204066043271384535</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://who-t.blogspot.com/2012/05/copypaste-of-code-is-not-ok.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0cNQ3s7fSp7ImA9WhVVEU0.&quot;"><id>tag:blogger.com,1999:blog-6112936277054198647.post-7701694931843662424</id><published>2012-05-03T10:36:00.000+10:00</published><updated>2012-05-04T14:18:12.505+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-05-04T14:18:12.505+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="xorg" /><category scheme="http://www.blogger.com/atom/ns#" term="synaptics" /><title>What's new in Synaptics 1.6.0</title><content type="html">&lt;a href="http://lists.freedesktop.org/archives/xorg-announce/2012-May/001944.html"&gt;xf86-input-synaptics 1.6.0&lt;/a&gt; was released today and it packs a bunch of changes. This post outlines some of these changes and future directions for the drive.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;

Clickpad support&lt;/h2&gt;
Clickpads are touchpads without physical buttons. Instead, the user has to press the whole pad down to trigger a click. These pads are becoming increasingly common in laptops but need a bunch of software workarounds to make them useful with traditional interaction methods. I've got a post dedicated to &lt;a href="http://who-t.blogspot.com.au/2012/04/clickpad-support-in-synaptics-driver.html"&gt;Clickpad support in the synaptics driver&lt;/a&gt;, so best to read that for more details.&lt;br /&gt;
&lt;br /&gt;
The important bit about clickpad support is that it's only available on multi-touch capable X servers. If you're running an older server, you won't see clickpad-y goodness. Sorry. &lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;

Smooth scrolling&lt;/h2&gt;
&lt;a href="http://who-t.blogspot.com.au/2011/09/whats-new-in-xi-21-smooth-scrolling.html"&gt;Smooth scrolling&lt;/a&gt; is now supported by the driver as well. On XI 2.1-compatible servers (read: server 1.12 &lt;span style="font-size: x-small;"&gt;[1]&lt;/span&gt;), the driver will submit scrolling valuators instead of scroll events. This makes for a smoother scrolling experience on clients that support it.&lt;br /&gt;
&lt;br /&gt;
We're in a transition period where clients start to enable smooth scrolling but many other clients don't support it yet. For now, we left coasting enabled by default in the driver to provide a consistent experience. This will likely be disabled once smooth scrolling support and client-side coasting becomes more prevalent.&lt;br /&gt;
&lt;br /&gt;
Meanwhile, clients can disable it by setting the "&lt;i&gt;Synaptics Coasting Speed&lt;/i&gt;" property to 0, 0.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;

Bugs, bugs, bugs&lt;/h2&gt;
Luckily I was able to spend quite some time on synaptics over the last weeks to fix various bugs and I think this is the most solid release of synaptics in quite a while. A few bugs that you may have seen that have now been fixed are:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;touchpad unresponsive after suspend&amp;nbsp; &lt;a href="https://bugs.freedesktop.org/show_bug.cgi?id=49161" target="_blank"&gt;#49161&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;weird cursor jumps while dragging&amp;nbsp;&lt;a href="http://bugs.freedesktop.org/show_bug.cgi?id=48777" target="_blank"&gt;#48777&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;broken double-tap &lt;a href="http://bugs.freedesktop.org/show_bug.cgi?id=31854" target="_blank"&gt;#31854&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;slow or too fast scrolling on pre-1.12 servers &lt;a href="http://bugs.freedesktop.org/show_bug.cgi?id=46617" target="_blank"&gt;#46617&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
and a few more.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;

Future of synaptics&lt;/h2&gt;
What becomes more and more obvious is that the driver is on the edge of being unmaintainable. Pushing new features into the driver always always means that some other feature is broken and sometimes we don't notice for months. Having around 75 options in the driver doesn't help here, testing all combinations is impossible.&lt;br /&gt;
&lt;br /&gt;
I can't claim that I have big plans because I tend to get pre-empted by misc things all the time but the rough plan is to keep a 1.6.x series while re-doing some of the internals of the driver for the 1.7 release. Expect the git master branch to see a few big changes though.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;[1] Ubuntu 12.04 ships a 1.11 with the 1.12 input stack, so the above applies to that server too.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6112936277054198647-7701694931843662424?l=who-t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Who-t/~4/H3-lhPfNtzM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://who-t.blogspot.com/feeds/7701694931843662424/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6112936277054198647&amp;postID=7701694931843662424" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/7701694931843662424?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/7701694931843662424?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Who-t/~3/H3-lhPfNtzM/whats-new-in-synaptics-160.html" title="What's new in Synaptics 1.6.0" /><author><name>Peter Hutterer</name><uri>http://www.blogger.com/profile/17204066043271384535</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://who-t.blogspot.com/2012/05/whats-new-in-synaptics-160.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUUARXY6eyp7ImA9WhVWGEk.&quot;"><id>tag:blogger.com,1999:blog-6112936277054198647.post-9140413144305202056</id><published>2012-05-01T13:34:00.000+10:00</published><updated>2012-05-01T13:34:04.813+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-05-01T13:34:04.813+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="workflow" /><title>Drive-by learning through patch reviews</title><content type="html">This came up on the &lt;a href="http://sourceforge.net/mailarchive/message.php?msg_id=29202048"&gt;linuxwacom-devel&lt;/a&gt; list today and I think it warrants further spread through this post.&lt;br /&gt;
&lt;br /&gt;
Different projects have different patch review requirements but the biggest difference is pre-review and post-review. That is, do patches get reviewed &lt;i&gt;before&lt;/i&gt; or &lt;i&gt;after&lt;/i&gt; they hit the repositories. Not too long ago, the X server employed a post-review process. Everyone with access pushed and bugs would get discovered by those reading commit logs. Patches that ended up on the list were mainly from those that didn't have commit access. Beginning with server 1.8 we introduced a hard review requirement and every patch to make it into the repos ended up on the list, so we switched from post-review to pre-review.&lt;br /&gt;
&lt;br /&gt;
Aside from enforcing that someone gives the formal ACK for a patch, a side-effects is to allow for a passive "drive-by" learning of the code base. Rather than having to explicitly look up commit logs, patches are delivered into one's inbox, outlining where the development currently happens, what it is about and - perhaps most importantly - issues that may have been caused bugs in rejected patches. Ideally that is then archived, so you can link to that discussion later.&lt;br /&gt;
&lt;br /&gt;
The example I linked to from above is automake's INCLUDES versus AM_CPPFLAGS. I wouldn't have know about them if it wasn't for skimming through Gaetan's patches to various X.Org-related projects. That again allowed me to contribute a (in this case admittedly minor) patch to another project. And since that patch ended up on another list, the knowledge can spread on.&lt;br /&gt;
&lt;br /&gt;
Next time when you think of committing directly to a repo, consider sending the patches out. Not just for review, but also to make learning easier for others.&lt;br /&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6112936277054198647-9140413144305202056?l=who-t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Who-t/~4/m2hxH0rdgo8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://who-t.blogspot.com/feeds/9140413144305202056/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6112936277054198647&amp;postID=9140413144305202056" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/9140413144305202056?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/9140413144305202056?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Who-t/~3/m2hxH0rdgo8/drive-by-learning-through-patch-reviews.html" title="Drive-by learning through patch reviews" /><author><name>Peter Hutterer</name><uri>http://www.blogger.com/profile/17204066043271384535</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://who-t.blogspot.com/2012/05/drive-by-learning-through-patch-reviews.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck4NQHs4eip7ImA9WhVWGEk.&quot;"><id>tag:blogger.com,1999:blog-6112936277054198647.post-8591371771794440511</id><published>2012-05-01T12:56:00.000+10:00</published><updated>2012-05-01T12:56:31.532+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-05-01T12:56:31.532+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="synaptics" /><title>Clickpad kernel bugs in 3.3.x and 3.4</title><content type="html">In my last post I talked about &lt;a href="http://who-t.blogspot.com.au/2012/04/clickpad-support-in-synaptics-driver.html"&gt;Clickpad support in the synaptics driver&lt;/a&gt;. Unfortunately, right around the same time a kernel bug surfaced that messed with the events from some clickpads (the Synaptics-branded ones, Apple and others were unaffected).

Affected was the 3.3.x series and obviously 3.4. 

Thanks to &lt;a href="https://plus.google.com/111418381720467414710"&gt;+Benjamin Herrenschmidt&lt;/a&gt;, that bug was fixed and it is now available in a variety of kernels. The &lt;a href="http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commit;h=899c612d74d4a242158a4db20367388d6299c028"&gt;upstream commit&lt;/a&gt; is in Linus tree now, still making it into stable (not in 3.3.4 yet).

Fedora users can grab &lt;a href="https://admin.fedoraproject.org/updates/FEDORA-2012-6898/kernel-3.3.4-1.fc17"&gt;Fedora 17&lt;/a&gt; or &lt;a href="https://admin.fedoraproject.org/updates/kernel-3.3.4-1.fc16"&gt;Fedora 16&lt;/a&gt; kernels that carry this patch.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6112936277054198647-8591371771794440511?l=who-t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Who-t/~4/KWIo7_uGp_g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://who-t.blogspot.com/feeds/8591371771794440511/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6112936277054198647&amp;postID=8591371771794440511" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/8591371771794440511?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/8591371771794440511?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Who-t/~3/KWIo7_uGp_g/clickpad-kernel-bugs-in-33x-and-34.html" title="Clickpad kernel bugs in 3.3.x and 3.4" /><author><name>Peter Hutterer</name><uri>http://www.blogger.com/profile/17204066043271384535</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://who-t.blogspot.com/2012/05/clickpad-kernel-bugs-in-33x-and-34.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UMQXozcCp7ImA9WhVXGEo.&quot;"><id>tag:blogger.com,1999:blog-6112936277054198647.post-4524003263948760384</id><published>2012-04-19T17:19:00.000+10:00</published><updated>2012-04-20T09:48:00.488+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-04-20T09:48:00.488+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="xorg" /><category scheme="http://www.blogger.com/atom/ns#" term="synaptics" /><title>ClickPad support in the synaptics driver</title><content type="html">&lt;small&gt;[update 20 Apr: clarify middle finger emulation]&lt;/small&gt;&lt;br/&gt;

One of the features added to the upcoming &lt;a href="http://cgit.freedesktop.org/xorg/driver/xf86-input-synaptics/"&gt;xf86-input-synaptics&lt;/a&gt; version 1.6 is support for clickpad-style devices. This post outlines what clickpads are, how they are supported and how you go about enabling the new features.

&lt;br /&gt;&lt;br /&gt;
&lt;h2&gt;What are clickpads&lt;/h2&gt;
The name ClickPad comes from the &lt;a href="http://www.synaptics.com/solutions/products/clickpad"&gt;Synaptics product&lt;/a&gt; of the same name. It describes a touchpad that does not have physical buttons. Instead, the whole touchpad works as a button. Devices like this have been around for a while, most notably the touchpads found in Apple laptops and the Dell Mini 10 series.
The challenges for us were to handle the data streams correctly. Most of this work was done by &lt;a href="http://voices.canonical.com/chase.douglas/"&gt;Chase Douglas&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Clickpads give us the position for each finger, and a button 1 event when the pad is pressed. The design of the hardware however means that whenever you click the pad, you always add one more finger to the mix. Decoupling that finger from the ones that actually matter is the challenge. And integrating it with all the other whacky features that the synaptics driver currently has.

&lt;br /&gt;&lt;br /&gt;
&lt;h2&gt;Clickpad Support&lt;/h2&gt;

&lt;b&gt;Clickpad support requires server 1.12&lt;/b&gt; [0]. It heavily relies on multitouch support.&lt;br/&gt;

Central to the new feature is the "ClickPad" option and property. It is enabled if the kernel sets the INPUT_PROP_BUTTONPAD property on the device, otherwise you can enable it in an xorg.conf.d snippet or at runtime with either xinput or synclient:
&lt;br /&gt;
&lt;pre&gt;xinput set-prop "device name" "Synaptics ClickPad" 1
synclient ClickPad=1
&lt;/pre&gt;
This toggles a few driver behaviours to make the clickpad much more usable. Most notably, you can use one finger to press the button and another finger to move the cursor around.&lt;br /&gt;
&lt;br /&gt;
Word of warning here: if you enable clickpad support manually at runtime, you will also have to manually disable traditional middle mouse button emulation (synclient EmulateMidButtonTime=0). For autoconfigured devices or xorg.conf.d configured devices this is done automatically.&lt;br /&gt;
&lt;br /&gt;
The second big feature for clickpads is support for software buttons. Since the device only gives us left button clicks, we expose an option to allow for right and middle button clicks. By default, we ship this xorg.conf.d snippet:
&lt;br /&gt;
&lt;pre&gt;Section "InputClass"
        Identifier "Default clickpad buttons"
        MatchDriver "synaptics"
        Option "SoftButtonAreas" "50% 0 82% 0 0 0 0 0"
EndSection
&lt;/pre&gt;
The order of soft button edges is left, right, top, bottom for the right button, then left, right, top, bottom for the middle button. So the above snippet sets the right half of the bottom 18% to be a right button, with no middle button present. A coordinate of 0 means "stretch to edge of touchpad". &lt;a href="http://www.blogger.com/blogger.g?blogID=6112936277054198647#footnote"&gt;[1]&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Traditional middle mouse button emulation is disabled by default and we don't handle it for clickpads. Traditional middle mouse button emulation refers to the method of generating a button 2 press when both button 1 and button 3 are pressed simultaneously. Mostly because, well, I'm not sure how you would even trigger middle mouse button emulation for clickpads given that all buttons except the first are already emulated anyway. You can still emulate middle mouse button emulations through clickfingers (see below), tapping, or the soft button areas as described above.
&lt;br /&gt;
&lt;br /&gt;
Tapping works as on any other touchpad.&lt;br /&gt;
&lt;br /&gt;
ClickFinger functionality works, albeit slightly different. In the default ClickFinger setting, if you have 2 fingers on the touchpad and you press the left button, you will see a ClickFinger2 action performed (right button by default). On clickpads we guess the number of fingers by proximity (since you need one finger to actually press the button). Fingers closer together than 30% of the touchpad's size [2] will count towards ClickFinger actions, others will be skipped. So in the default use-case, where you have two fingers down on the touchpad in the middle and you use a third to click the button, you will still get a ClickFinger2 action. Likewise, if you press with two fingers down, you will also get a ClickFinger2 action.&lt;br /&gt;
&lt;br /&gt;
All other functions are not affected by clickpad support and behave as before.

&lt;br /&gt;
&lt;a href="" name="footnote"&gt;&lt;/a&gt;
&lt;small&gt;
&lt;/small&gt;&lt;br /&gt;
&lt;ul&gt;&lt;small&gt;
&lt;li&gt;[0] Ubuntu 12.04 will ship a 1.11/1.12 mix, that will work as well&lt;/li&gt;
&lt;li&gt;[1] "edge of touchpads" &lt;i&gt;should&lt;/i&gt; be 100% but it isn't due to a years-old mishandling of the coordinate ranges. So 0 is better to use here.&lt;/li&gt;
&lt;li&gt;[2] All touchpads lie about their size, so we just hardcode 30% since anything we infer is going to be wrong anyways&lt;/li&gt;
&lt;/small&gt;&lt;/ul&gt;
&lt;small&gt;
&lt;/small&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6112936277054198647-4524003263948760384?l=who-t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Who-t/~4/GRWwQMPmqcY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://who-t.blogspot.com/feeds/4524003263948760384/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6112936277054198647&amp;postID=4524003263948760384" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/4524003263948760384?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/4524003263948760384?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Who-t/~3/GRWwQMPmqcY/clickpad-support-in-synaptics-driver.html" title="ClickPad support in the synaptics driver" /><author><name>Peter Hutterer</name><uri>http://www.blogger.com/profile/17204066043271384535</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://who-t.blogspot.com/2012/04/clickpad-support-in-synaptics-driver.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0cNQnk_cSp7ImA9WhVXEEw.&quot;"><id>tag:blogger.com,1999:blog-6112936277054198647.post-4781279763284507060</id><published>2012-04-10T10:51:00.001+10:00</published><updated>2012-04-10T10:51:33.749+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-04-10T10:51:33.749+10:00</app:edited><title>New layout template</title><content type="html">Short summary: layout of the blog changed.
Long summary: One of the issues I ran into repeatedly was that any code postings would overrun the rather narrow column width. Now I've done the lazy thing and applied a new standard template that appears to be wider. So in the future, code snippets are hopefully easier to read.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6112936277054198647-4781279763284507060?l=who-t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Who-t/~4/gLqYU3zho2U" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://who-t.blogspot.com/feeds/4781279763284507060/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6112936277054198647&amp;postID=4781279763284507060" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/4781279763284507060?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/4781279763284507060?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Who-t/~3/gLqYU3zho2U/new-layout-template.html" title="New layout template" /><author><name>Peter Hutterer</name><uri>http://www.blogger.com/profile/17204066043271384535</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://who-t.blogspot.com/2012/04/new-layout-template.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkQMSH49eip7ImA9WhVQGEU.&quot;"><id>tag:blogger.com,1999:blog-6112936277054198647.post-5200299418541852530</id><published>2012-04-08T21:26:00.000+10:00</published><updated>2012-04-08T21:26:29.062+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-04-08T21:26:29.062+10:00</app:edited><title>Chrome's multitask mode - an April fool's 2 years too late?</title><content type="html">&lt;p&gt;Ok, I was away on holidays for the last week so I missed everything. Thanks to Simon Thum, I found the Chrome team's April fools joke: &lt;a href="http://chrome.blogspot.com.au/2012/03/new-way-to-multitask.html"&gt;Chrome's Multitask Mode&lt;/a&gt;. Allegedly a mode for Chrome that allows to use multiple pointers simultaneously.
&lt;/p&gt;

&lt;p&gt;
Great, except that it's just an April fool's joke, they didn't actually implement it. Even though, well, it's been a &lt;b&gt;standard feature in the X.Org X server since September 2009&lt;/b&gt;. Yep, right. Fedora 12 had it, for example, and every version since. It's ubiquitous on the GNU/Linux desktop. GTK3 has support for it.
&lt;/p&gt;
&lt;p&gt;
Being able to use two hands is quite useful, research papers on the benefits go back well over 20 years. Use cases are generally as dominant hand/non-dominant hand methods (e.g. an artist holding the palette with one hand while painting with the other one) or as equal bimanual interaction (aligning a rectangular mask around an object). All this isn't new, and as I said above this is all a standard feature in X since 2009. You really just [1] need to add it in your application. So Chrome's April fool's joke is pretty much a joke about not implementing a feature. Which, well, uhm... ok. Haha.
&lt;/p&gt;
&lt;p&gt;
The video is a bit outlandish, with a guy playing golf and a shooter simultaneously. However, listening to just the audio on the video largely makes sense (except the switching off your computer part). Using two mice became natural for me quite quickly. I even conducted a user-study about users using two browser windows simultaneously to research and gather information about a specific topic. Yep, they could do it, including typing up the results in a decidedly single-user Abiword without major conflicts.
&lt;/p&gt;
&lt;p&gt;
Now I'm waiting for next year's joke, maybe it's about how we drive cars with, wait for it, steering wheels.
&lt;/p&gt;
&lt;small&gt;[1] I say "just", but implementing it is really hard. It opens a can of worms about assumptions in user interface paradigms that aren't quite that simple to deal with. From a technical point of view, it's a "just" though...&lt;/small&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6112936277054198647-5200299418541852530?l=who-t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Who-t/~4/z8yCr8qqZh4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://who-t.blogspot.com/feeds/5200299418541852530/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6112936277054198647&amp;postID=5200299418541852530" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/5200299418541852530?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/5200299418541852530?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Who-t/~3/z8yCr8qqZh4/chromes-multitask-mode-april-fools-2.html" title="Chrome's multitask mode - an April fool's 2 years too late?" /><author><name>Peter Hutterer</name><uri>http://www.blogger.com/profile/17204066043271384535</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>5</thr:total><feedburner:origLink>http://who-t.blogspot.com/2012/04/chromes-multitask-mode-april-fools-2.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0cAQHY-eip7ImA9WhVSF0s.&quot;"><id>tag:blogger.com,1999:blog-6112936277054198647.post-7931983641898189896</id><published>2012-03-15T08:44:00.000+10:00</published><updated>2012-03-15T08:44:01.852+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-03-15T08:44:01.852+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="workflow" /><title>ssh and shared connections</title><content type="html">My job requires me to ssh into various boxes often, with several connections to the target host. Some people use screen on the target host but I work better if I have multiple terminal windows. But re-connecting to the same host can be annoying, a connection does take time and it should be instantaneous. Luckily, SSHv2 allows to share a connection, making reconnection a lot faster. Also, if you have password-authenticated connection instead of a key-based one you won't have to type the password for each new connection (but really, you should be using keys anyway).

The few lines you'll need in your $HOME/.ssh/config:

&lt;pre&gt;
ControlMaster auto
ControlPath ~/.ssh/sockets/ssh_mux_%h_%p_%r
ControlPersist 60
&lt;/pre&gt;

All three are extensively described in the ssh_config(5) man page, but here's a summary:
&lt;ul&gt;
&lt;li&gt;ControlMaster auto will create a new ssh connection when no matching socket exists. Otherwise, it will just use the existing connection. &lt;/li&gt;
&lt;li&gt;ControlPath is simply the path to the control socket, with %h, %p and %r being replaced with target host, port and username to keep the socket name unique. Having this in a user-specific location instead of /tmp is generally a good idea.&lt;/li&gt;
&lt;li&gt;ControlPersist defines how long the master connection should be kept open after exit. You can specify "yes" for indefinite or a number of idle seconds. If you reconnect within that idle time, it will again re-use the existing connection. Note that if you do not have ControlPersist and you quit the master connection, you will terminate all other connections too! ControlPersist was added in &lt;a href="http://lwn.net/Articles/401422/"&gt;OpenSSH 5.6&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

You can provide these options globally or inside a Host section of the config, depending on your needs.

A few final notes: since you essentially only have one connection now, you can only forward one X11 display, one ssh agent, etc. at a time. If you need a separate connection for a otherwise shared host, use "ssh -S none". Also, if you're doing heavy data transfer on laggy connections you're probably better off having separate connections.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6112936277054198647-7931983641898189896?l=who-t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Who-t/~4/F3ma3DKZpro" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://who-t.blogspot.com/feeds/7931983641898189896/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6112936277054198647&amp;postID=7931983641898189896" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/7931983641898189896?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/7931983641898189896?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Who-t/~3/F3ma3DKZpro/ssh-and-shared-connections.html" title="ssh and shared connections" /><author><name>Peter Hutterer</name><uri>http://www.blogger.com/profile/17204066043271384535</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://who-t.blogspot.com/2012/03/ssh-and-shared-connections.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0YGQX88fyp7ImA9WhVVEU0.&quot;"><id>tag:blogger.com,1999:blog-6112936277054198647.post-1867181930264233336</id><published>2012-02-07T22:27:00.000+10:00</published><updated>2012-05-04T14:18:40.177+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-05-04T14:18:40.177+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="multitouch" /><category scheme="http://www.blogger.com/atom/ns#" term="xorg" /><category scheme="http://www.blogger.com/atom/ns#" term="synaptics" /><title>Multitouch in X - Multitouch-touchpads</title><content type="html">This post is part of a series on multi-touch support in the X.Org X server.

&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="http://who-t.blogspot.com/2011/12/multitouch-in-x-getting-events.html"&gt;Multitouch in X - Getting events&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://who-t.blogspot.com/2011/12/multitouch-in-x-pointer-emulation.html"&gt;Multitouch in X - Pointer emulation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://who-t.blogspot.com/2012/01/multitouch-in-x-touch-grab-handling.html"&gt;Multitouch in X - Touch grab handling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://who-t.blogspot.com.au/2012/02/multitouch-in-x-multitouch-touchpads.html"&gt;Multitouch in X - Multitouch-touchpads&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
In this post, I'll outline the handling of touch events for multitouch-capable touchpads.
Multi-touch touchpads that are supported are those that provide position information for more than one finger. The current version of the synaptics X driver does some tricks to pretend two-finger interaction on single-finger touchpads - such devices are not applicable here.

&lt;br /&gt;
&lt;br /&gt;
Touchpads are primarily pointer devices and any multi-touch interaction is usually a gesture. In the protocol, such devices are of the type &lt;i&gt;XIDependentDevice&lt;/i&gt; and the server does adjust touch event delivery. I've already hinted at this &lt;a href="http://who-t.blogspot.com/2011/12/multitouch-in-x-getting-events.html"&gt;here&lt;/a&gt; but this time I'll give a more detailed explanation.

&lt;br /&gt;
&lt;h2&gt;
Touch event delivery&lt;/h2&gt;
Unlike for direct touch devices such as touchscreens, dependent devices have a different picking mechanism in the server. We assume that all gestures are semantically associated with the cursor position. For example, for scrolling, you would move the cursor on top of the window to be scrolled, then you would start scrolling. The server thus adjusts event delivery accordingly. Whereas for direct touch devices the touch events are delivered to whichever window is at the position of the touch, touch events from dependent devices are &lt;i&gt;always&lt;/i&gt; delivered to the window underneath the pointer (grab semantics are adjusted to follow the same rules). So if you start a gesture in the top-left corner of the touchpad, the window underneath the cursor gets the events with the top-left coordinates. Note that the event and root coordinates always reflect the pointer position.
&lt;br /&gt;
&lt;br /&gt;
The average multi-touch touchpad has two modes of operation: single-finger operation where the purpose is to move the visible cursor and multi-finger operation which is usually interpreted into a gesture on the client. These two modes are important, as they too affect event delivery. The protocol specifies that any interaction with the device that serves to move the visible cursor only should not generate touch events, and that touch events will start once that interaction becomes a true multi-touch interaction. This leaves the drivers a little bit of leeway, but the current implementation in the synaptics driver is the following:
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;A user places one finger on the touchpad and moves. The client will receive regular pointer events.&lt;/li&gt;
&lt;li&gt;The user places a second finger on the touchpad. The client will now receive a TouchBegin event for the &lt;b&gt;first and the second touch&lt;/b&gt;, at their respective current positions in device coordinate range.&lt;/li&gt;
&lt;li&gt;Movement of either finger now will generate touch events, but no pointer events.&lt;/li&gt;
&lt;li&gt;Any other fingers will generate touch events only.&lt;/li&gt;
&lt;li&gt;When one of two remaining fingers on the touchpoint ceases the touch, a TouchEnd is sent for &lt;b&gt;both the terminating touch and the remaining touch&lt;/b&gt;. The remaining finger will revert to sending pointer events.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
Legacy in-driver gestures&lt;/h2&gt;
As you are likely aware, the synaptics driver currently supports several pseudo gestures such as tap-to-click or two-finger scrolling. These gestures are interpreted in the driver, thus the server and client never see the raw data for them.

&lt;br /&gt;
&lt;br /&gt;
With proper multi-touch support these gestures are now somewhat misplaced. On the one hand, we want the clients to interpret multitouch, on the other hand we want the gestures to be handled in the same manner in all applications. (Coincidentally, this is also a problem that we need to solve for &lt;a href="http://wayland.freedesktop.org/"&gt;Wayland&lt;/a&gt;). 
&lt;br /&gt;
&lt;br /&gt;
We toyed with ideas of marking emulated events so clients can filter but since we do need to be compatible to the core and XI 1.x behaviours, we only found one solution: any in-driver gestures that alter event deliver must not generate touch events. Thus, if the driver is set to handle two-finger scrolling, the clients will only see the pointer events and scroll events, they will not see touch events from two-fingers. To get two-finger scrolling handled by the client, the in-driver gesture must be disabled. The obvious side-effect of that is that you then cannot scroll in applications that don't support the gestures. Oh well, it's the price we have to pay for having integrated gesture support in the wrong place.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6112936277054198647-1867181930264233336?l=who-t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Who-t/~4/0-aqIr3Mmko" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://who-t.blogspot.com/feeds/1867181930264233336/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6112936277054198647&amp;postID=1867181930264233336" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/1867181930264233336?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/1867181930264233336?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Who-t/~3/0-aqIr3Mmko/multitouch-in-x-multitouch-touchpads.html" title="Multitouch in X - Multitouch-touchpads" /><author><name>Peter Hutterer</name><uri>http://www.blogger.com/profile/17204066043271384535</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>4</thr:total><feedburner:origLink>http://who-t.blogspot.com/2012/02/multitouch-in-x-multitouch-touchpads.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUYDSHo-fCp7ImA9WhRUEE8.&quot;"><id>tag:blogger.com,1999:blog-6112936277054198647.post-8782642693717588379</id><published>2012-01-20T12:39:00.000+10:00</published><updated>2012-01-20T12:39:39.454+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-20T12:39:39.454+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="xkb" /><category scheme="http://www.blogger.com/atom/ns#" term="xorg" /><title>XKB breaking grabs - CVE-2012-0064</title><content type="html">Given that there is a copious amount of misinformation being spread, here is a summary of &lt;a href="https://www.redhat.com/security/data/cve/CVE-2012-0064.html"&gt;CVE-2012-0064&lt;/a&gt;, straight from a horse's mouth.

&lt;h2&gt;Outline of the issue&lt;/h2&gt;
The bug allows users to work around screen locking (e.g. gnome-screensaver) by hitting Control+Alt+keypad multiply or Control+Alt+keypad divide. This terminates the input grab the screensaver has and thus allows a user to interact with the desktop, skipping the password entry.

&lt;h2&gt;Affected versions&lt;/h2&gt;
Affected is anyone running X server 1.11 or later (or release candidates thereof). So if "Xorg -version" shows something else on your box, stop worrying. I doubt any distribution would have back-ported the patches.
&lt;br/&gt;&lt;br/&gt;
In Fedora/Red Hat land - the only distributions affected are Fedora 16 and current Fedora Rawhide. Both have been fixed, the F16 update is avaialble &lt;a href="https://admin.fedoraproject.org/updates/FEDORA-2012-0712/xkeyboard-config-2.3-3.fc16"&gt;here&lt;/a&gt;. Note that the update is to &lt;b&gt;xkeyboard-config&lt;/b&gt;, not to the server itself.
&lt;br/&gt;&lt;br/&gt;

Fedora 15 is not affected. RHEL 4, 5, 6 and thus CentOS 4, 5, 6 and other derivatives are not affected. I believe that most other distributions have now pushed out updates as well, if you want to link to the respective updates, please do so in the comments.
&lt;br/&gt;&lt;br/&gt;
Sergey has also pushed out &lt;a href="http://listserv.bat.ru/xkb/Message/8375.html"&gt;xkeyboard-config 2.5&lt;/a&gt; today with the fix included.

&lt;h2&gt;History of the feature&lt;/h2&gt;
The X protocol does not allow the server to break grabs. Once a client has a grab, the server must wait for that client to release the grab, terminate, or the grab window to become unviewable. This is an issue when debugging applications - if your client has a keyboard grab, you cannot use the debugger since all key events will go to the client being debugged. To avoid this issue, the X server has had two combinations to break grabs: Control+Alt+Keypad multiply and Control+Alt+Keypad divide. They forced grab termination inside the X server and although against the protocol it made debugging possible. The option required explicit enabling in the xorg.conf.
&lt;br/&gt;&lt;br/&gt;
These options were removed in server 1.4 and disabled since. Which made debugging hard, so last year we merged a patch to bring them back, together with some other features. They are triggered by XKB actions (as they used to be). The plan was to remove the XKB actions from the default keymap so that the action is available on request but not enabled by default. This is where a miscommunication happened, the removal from the default keymap never happened. So server 1.11 and vanilla xkeyboard-config ship with both the actions available and present in the current keymap. As a result, any user can break a grab from any application and thus get around screen locking.

&lt;h2&gt;Outline of the fix&lt;/h2&gt;
To shoot yourself in the foot, you need two items: a gun and a trigger. We have removed the trigger. The fix we've now pushed into xkeyboard-config removes the actions from the default keymap and into an XKB option instead. So the fix does not remove the gun, but it requires the user to screw the trigger in themselves before trying to hurt themselves. In a default configuration, it is thus no longer possible to break the grab of your screensaver.
&lt;br/&gt;&lt;br/&gt;
To re-enable grab debugging, run setxkbmap with "-option grab:break_actions" or enable "Allow breaking grabs with keyboard actions (warning: security risk)" in the "Miscellaneous compatibility options" in your keyboard layout configuration tool of choice.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6112936277054198647-8782642693717588379?l=who-t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Who-t/~4/KBUJeNOWYMM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://who-t.blogspot.com/feeds/8782642693717588379/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6112936277054198647&amp;postID=8782642693717588379" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/8782642693717588379?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/8782642693717588379?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Who-t/~3/KBUJeNOWYMM/xkb-breaking-grabs-cve-2012-0064.html" title="XKB breaking grabs - CVE-2012-0064" /><author><name>Peter Hutterer</name><uri>http://www.blogger.com/profile/17204066043271384535</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://who-t.blogspot.com/2012/01/xkb-breaking-grabs-cve-2012-0064.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMARHo_cSp7ImA9WhVTFkg.&quot;"><id>tag:blogger.com,1999:blog-6112936277054198647.post-8511630842963928276</id><published>2012-01-03T09:56:00.000+10:00</published><updated>2012-03-02T13:04:05.449+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-03-02T13:04:05.449+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="xi2" /><category scheme="http://www.blogger.com/atom/ns#" term="multitouch" /><category scheme="http://www.blogger.com/atom/ns#" term="tutorial" /><category scheme="http://www.blogger.com/atom/ns#" term="xorg" /><title>Multitouch in X - Touch grab handling</title><content type="html">This post is part of a series on multi-touch support in the X.Org X server.

&lt;ol&gt;
&lt;li&gt;&lt;a href="http://who-t.blogspot.com/2011/12/multitouch-in-x-getting-events.html"&gt;Multitouch in X - Getting events&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://who-t.blogspot.com/2011/12/multitouch-in-x-pointer-emulation.html"&gt;Multitouch in X - Pointer emulation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://who-t.blogspot.com/2012/01/multitouch-in-x-touch-grab-handling.html"&gt;Multitouch in X - Touch grab handling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://who-t.blogspot.com.au/2012/02/multitouch-in-x-multitouch-touchpads.html"&gt;Multitouch in X - Multitouch-touchpads&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

In this post, I'll outline how grabs on touch events work. This post assumes basic knowledge of the XI2 Xlib interfaces. 
&lt;h2&gt;Passive grabs&lt;/h2&gt;
The &lt;a
href="http://cgit.freedesktop.org/xorg/lib/libXi/tree/include/X11/extensions/XInput2.h"&gt;libXi
interface&lt;/a&gt; has one new passive grab call: &lt;i&gt;XIGrabTouchBegin&lt;/i&gt;, which
works pretty much like the existing passive grab APIs. As with event selection, you must
set all three event masks XI_TouchBegin, XI_TouchUpdate and XI_TouchEnd or a
BadValue error occurs. Once a passive grab activates in response to a touch,
the client &lt;b&gt;must&lt;/b&gt; choose to either &lt;b&gt;accept&lt;/b&gt; or &lt;b&gt;reject&lt;/b&gt; a touch.
Details on that below.
&lt;br/&gt; &lt;br/&gt;
Grabs activate on a TouchBegin event and due to the nature of multitouch,
multiple touch grabs may be active at any time - some of them for different
clients.

&lt;h2&gt;Active grabs&lt;/h2&gt;
Active grabs do not have a new call, they are handled through the event masks of the existing &lt;a href="http://www.x.org/archive/X11R7.5/doc/man/man3/XIGrabDevice.3.html"&gt;XIGrabDevice(3)&lt;/a&gt; call. If a client has an active touch grab on the device, it is automatically the owner of the touch sequence (ownership is described below). If a client has an active pointer or keyboard grab on the device, it is the owner of the touch sequence for pointer emulated touch events only. Other touch events are unaffected by the grab and are processed normally.

&lt;h2&gt;Acceptance and rejection&lt;/h2&gt;
Pointer grabs provide exclusive access to the device, but to some degree a
client can opt to replay the event it received on the next client. We expect
that touch sequences will often trigger gesture recognition, and a client may realise after a few events that it doesn't actually want that touch sequence. So we expanded
the replay semantics. clients with a touch
grab &lt;b&gt;must&lt;/b&gt; choose to either &lt;b&gt;accept&lt;/b&gt; or &lt;b&gt;reject&lt;/b&gt; a touch.
&lt;br/&gt; &lt;br/&gt;

Accepting a touch signals to the server that the touch sequence is meant for
this client and no-one else. The server then exclusively delivers to that
client until the terminating TouchEnd. &lt;br/&gt; &lt;br/&gt;

Rejecting a touch sequence signals that the touch sequence is not meant for
this client. Once a client rejects a touch sequence, the server sends the
TouchEnd event to that client (if the touch is still active) and &lt;i&gt;replays
the full touch sequence&lt;/i&gt; &lt;a href="#footnote_1"&gt;[1]&lt;/a&gt; on the next grab
or window. We use the term &lt;b&gt;owner&lt;/b&gt; of a touch sequence to talk about
the current recipient.
&lt;br/&gt;
&lt;br/&gt;
The order of events for two clients Cg and Cw, with Cg having a
grab and Cw having a regular touch event selection on a window, is thus:
&lt;pre style="background: #F0F0F0"&gt;
TouchBegin to Cg    → 
TouchUpdate to Cg   → 
TouchUpdate to Cg   → 
                    ← Cg rejects touch
                    ← Cw becomes new owner
TouchEnd+ to Cg     →
TouchBegin* to Cw   → 
TouchUpdate* to Cw  → 
TouchUpdate* to Cw  → 
#### physical touch ends #### 
TouchEnd to Cw      →
&lt;/pre&gt;
&lt;small&gt;Events with + mark an event created by the server, * mark events replayed by the server&lt;/small&gt;

&lt;br/&gt;
&lt;br/&gt;
For nested grabs, this sequence simply repeats for each client until either
a grabbing client accepts the touch or the client with the event selection
becomes the owner.
&lt;br/&gt;
&lt;br/&gt;
In the above case, the touch ended after Cg rejected the touch. If the touch
ends before the current owner accepted or rejected it, the owner gets the
TouchEnd event and the touch is left handing until the owner accepts or
rejects it. If accepted, that's it. If rejected, the new owner gets the
full sequence in one go, including the TouchEnd event. The sequence is thus:
&lt;pre style="background: #F0F0F0"&gt;
TouchBegin to Cg    → 
TouchUpdate to Cg   → 
TouchUpdate to Cg   → 
#### physical touch ends #### 
TouchEnd to Cg      →
                    ← Cg rejects touch
                    ← Cw becomes new owner
TouchBegin* to Cw   → 
TouchUpdate* to Cw  → 
TouchUpdate* to Cw  → 
TouchEnd* to Cw     →
&lt;/pre&gt;
&lt;h2&gt;Touch ownership handling&lt;/h2&gt;
One additional event type that XI 2.2 introduces is the
&lt;i&gt;XI_TouchOwnership&lt;/i&gt; event. Clients selecting for this event signal that
they need to receive touch events &lt;b&gt;before they're the owner of the
touch sequence&lt;/b&gt;. This  event type can be selected on both grabs and event
selections.
&lt;br/&gt;&lt;br/&gt;
First up: there are specific use-cases where you need this. If you don't
fall into them, you're better off just skipping on ownership events, they
make everything more complicated. And whether you need ownership events
depends not only on you, but also the stack you're running under.
On normal touch event selection, touch events are only delivered to the
current owner of the touch. With multiple grabs, the delivery is sequential
and delivery of touch events may be delayed.
&lt;br/&gt;&lt;br/&gt;
Clients selecting for touch ownership events get the events as they occur,
even if they are not the current owner. The XI_TouchOwnership event is
delivered if and when they become the current owner. The last part is
important: if you select for ownership events, you may receive touch events
but you may not become the owner of that sequence. So while you can start
reacting to that sequence, anything your app does must be undo-able in case
the e.g. window manager claims the touch sequence.
&lt;br/&gt;&lt;br/&gt;
If we look at the same sequence as above with two clients selecting for
ownership, the sequence looks like this:
&lt;br/&gt;
&lt;pre style="background: #F0F0F0"&gt;
TouchBegin to Cg     → 
TouchBegin to Cw     → 
TouchOwnership to Cg →
TouchUpdate to Cg    → 
TouchUpdate to Cw    → 
TouchUpdate to Cg    → 
TouchUpdate to Cw    → 
                     ← Cg rejects touch
                     ← Cw becomes new owner
TouchEnd+ to Cg      →
TouchOwnership to Cw →
#### physical touch ends #### 
TouchEnd to Cw      →
&lt;/pre&gt;
&lt;small&gt;Note: TouchOwnership events do not correspond to any physical event, they are always generated by the server&lt;/small&gt;&lt;br/&gt;&lt;br/&gt;
If a touch ends before the owner accepts, the current owner gets the
TouchEnd, all others get a TouchUpdate event instead. That TouchUpdate has a
flag &lt;b&gt;XITouchPendingEnd&lt;/b&gt; set, signalling that no more actual events
will arrive from this touch but the touch is still waiting for owner
acceptance.
&lt;pre style="background: #F0F0F0"&gt;
TouchBegin to Cg     → 
TouchBegin to Cw     → 
TouchOwnership to Cg →
TouchUpdate to Cg    → 
TouchUpdate to Cw    → 
TouchUpdate to Cg    → 
TouchUpdate to Cw    → 
#### physical touch ends #### 
TouchEnd to Cg       →
TouchUpdate to Cw    →  (XITouchPendingEnd flag set)
                     ← Cg rejects touch
                     ← Cw becomes new owner
TouchOwnership to Cw →
TouchEnd to Cw       →
&lt;/pre&gt;
In both cases, we dealt with a rejecting owner. For an accepting owner, the
sequences look like this:
&lt;pre style="background: #F0F0F0"&gt;
TouchBegin to Cg     → 
TouchBegin to Cw     → 
TouchOwnership to Cg →
TouchUpdate to Cg    → 
TouchUpdate to Cw    → 
TouchUpdate to Cg    → 
TouchUpdate to Cw    → 
                     ← Cg accepts touch
TouchEnd+ to Cw      →
TouchUpdate to Cg    → 
#### physical touch ends #### 
TouchEnd to Cg      →
&lt;/pre&gt;
or 
&lt;pre style="background: #F0F0F0"&gt;
TouchBegin to Cg     → 
TouchBegin to Cw     → 
TouchOwnership to Cg →
TouchUpdate to Cg    → 
TouchUpdate to Cw    → 
TouchUpdate to Cg    → 
TouchUpdate to Cw    → 
#### physical touch ends #### 
TouchEnd to Cg       →
TouchUpdate to Cw    →  (XITouchPendingEnd flag set)
                     ← Cg accepts touch
TouchEnd* to Cw      →
&lt;/pre&gt;
In the case of multiple grabs, the same strategy applies in order of grab
activation. Ownership events may be selected by some clients but not others.
In that case, each client is treated as requested, so the event sequence the
server deals with may actually look like this:
&lt;pre style="background: #F0F0F0"&gt;
TouchBegin to C1     → 
TouchBegin to C3     → 
TouchOwnership to C1 →
TouchUpdate to C1    → 
TouchUpdate to C3    → 
TouchUpdate to C1    → 
TouchUpdate to C3    → 
                     ← C1 rejects touch
                     ← C2 becomes new owner
TouchEnd+ to C1      →
TouchBegin* to C2    → 
TouchUpdate* to C2   → 
TouchUpdate* to C2   → 
                     ← C2 rejects touch
                     ← C3 becomes new owner
TouchEnd+ to C2      →
TouchOwnership to C3 →
#### physical touch ends #### 
TouchEnd to C3       →
&lt;/pre&gt;

&lt;br/&gt;
&lt;br/&gt;
&lt;small&gt;
&lt;a name="footnote_1"&gt;&lt;/a&gt;[1] obviously we need to store these events so
"full sequence" really means all events until the buffer was full
&lt;/small&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6112936277054198647-8511630842963928276?l=who-t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Who-t/~4/cfCLwsGqMbI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://who-t.blogspot.com/feeds/8511630842963928276/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6112936277054198647&amp;postID=8511630842963928276" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/8511630842963928276?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/8511630842963928276?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Who-t/~3/cfCLwsGqMbI/multitouch-in-x-touch-grab-handling.html" title="Multitouch in X - Touch grab handling" /><author><name>Peter Hutterer</name><uri>http://www.blogger.com/profile/17204066043271384535</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://who-t.blogspot.com/2012/01/multitouch-in-x-touch-grab-handling.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMBRXs6cSp7ImA9WhVTFkg.&quot;"><id>tag:blogger.com,1999:blog-6112936277054198647.post-7626048294161699148</id><published>2011-12-22T12:47:00.000+10:00</published><updated>2012-03-02T13:04:14.519+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-03-02T13:04:14.519+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="xi2" /><category scheme="http://www.blogger.com/atom/ns#" term="multitouch" /><category scheme="http://www.blogger.com/atom/ns#" term="tutorial" /><category scheme="http://www.blogger.com/atom/ns#" term="xorg" /><title>Multitouch in X - Pointer emulation</title><content type="html">This post is part of a series on multi-touch support in the X.Org X server. 

&lt;ol&gt;
&lt;li&gt;&lt;a href="http://who-t.blogspot.com/2011/12/multitouch-in-x-getting-events.html"&gt;Multitouch in X - Getting events&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://who-t.blogspot.com/2011/12/multitouch-in-x-pointer-emulation.html"&gt;Multitouch in X - Pointer emulation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://who-t.blogspot.com/2012/01/multitouch-in-x-touch-grab-handling.html"&gt;Multitouch in X - Touch grab handling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://who-t.blogspot.com.au/2012/02/multitouch-in-x-multitouch-touchpads.html"&gt;Multitouch in X - Multitouch-touchpads&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

In this post, I'll outline how pointer emulation on touch events works.

This post assumes basic knowledge of the XI2 Xlib interfaces.

&lt;h2&gt;Why pointer emulation?&lt;/h2&gt;
One of the base requirements of adding multitouch support to the X server
was that traditional, non-multitouch applications can still be used.
Multitouch should be a transparent addition, available where needed, not
required where not supported.
&lt;br/&gt;
&lt;br/&gt;
So we do pointer emulation for multitouch events, and it's actually
specified in the protocol how we do it. Mainly so it's reliable and
predictable for clients.

&lt;h2&gt;What is pointer emulation in X&lt;/h2&gt;
Pointer emulation simply means that for specific touch sequences, we
generate pointer events. The conditions for emulation are that the 
the touch sequence is eligible for pointer emulation (details
below) and that no other client has a touch selection on that window/grab.
&lt;br/&gt;
&lt;br/&gt;

The second condition is important: if your client selects for both touch and
pointer events on a window, you will never see the emulated pointer events.
If you are an XI 2.2 client and you select for pointer but not touch events,
you will see pointer events. These events are marked with the
&lt;i&gt;XIPointerEmulated&lt;/i&gt; so that you know they come from an emulated source.

&lt;h2&gt;Emulation on direct-touch devices&lt;/h2&gt;
For direct-touch devices, we emulate pointer events for a touch sequence provided the touch is the &lt;i&gt;first&lt;/i&gt; touch on the device, i.e. no other touch sequences were active for this device when the touch started. The touch sequence is emulated until it ends, even if other touches start and end while that sequence is active.

&lt;h2&gt;Emulation on dependent-touch devices&lt;/h2&gt;
Dependent touch devices do not emulate pointer events. Rather, we send the
normal mouse movements from the device as regular pointer events.

&lt;h2&gt;Button events and button state&lt;/h2&gt;
Pointer emulation triggers motion events and, more importantly, button
events. The button number for touches is hardcoded to 1 (any more specific
handling such as long-click for right buttons should be handled by
touch-aware clients instead), so the detail field of an emulated button
event is 1 (unless the button is logically mapped).
&lt;br/&gt;
&lt;br/&gt;

The button state field on emulated pointer events adjusts for pointer emulation as it would for regular button events. The button state is thus (usually) 0x0 for the emulated ButtonPress and 0x100 for the MotionNotify and ButtonRelease events.

&lt;br/&gt;
&lt;br/&gt;
Likewise, any request that returns the button state will have the appropriate
state set, &lt;b&gt;even if no emulated event actually got sent&lt;/b&gt;.
&lt;br/&gt;
&lt;br/&gt;

Grab handling works as for regular pointer events, though the interactions
between touch grabs and emulated pointer grabs are somewhat complex. I'll
get to that in a later post.

&lt;h2&gt;The confusing bit&lt;/h2&gt;
There is one behaviour about the pointer emulation that may be confusing,
even though the specs may seem logical and the behaviour is within the
specs.
&lt;br/&gt;
&lt;br/&gt;

If you put one finger down, it will emulate pointer events. If you then put
another finger down, the first finger will continue to emulate pointer
events. If you now lift the first finger (keeping the second down) and put
the first finger down again, that finger will not generate events. 
This is noticable mainly in bi-manual or multi-user interaction.
&lt;br/&gt;
&lt;br/&gt;

The reason this doesn't work is simple: to the X server, putting the first
finger down just looks like another touchpoint appearing when there is
already one present. The server does not know that this is the same finger
again, it doesn't know that your intention was to emulate again with that
finger. Most of the semantics for such interaction is in your head alone and
hard to guess. Guessing it wrong can be quite bad, since that new touchpoint
may have been part of a two-finger gesture with the second finger and whoops
- instead of scrolling you just closed a window, pasted your password
somewhere or killed a kitten. So we err on the side of
caution, because, well, think of the kittens.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6112936277054198647-7626048294161699148?l=who-t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Who-t/~4/SNSKUmogx84" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://who-t.blogspot.com/feeds/7626048294161699148/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6112936277054198647&amp;postID=7626048294161699148" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/7626048294161699148?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/7626048294161699148?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Who-t/~3/SNSKUmogx84/multitouch-in-x-pointer-emulation.html" title="Multitouch in X - Pointer emulation" /><author><name>Peter Hutterer</name><uri>http://www.blogger.com/profile/17204066043271384535</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://who-t.blogspot.com/2011/12/multitouch-in-x-pointer-emulation.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMCR345eip7ImA9WhVTFkg.&quot;"><id>tag:blogger.com,1999:blog-6112936277054198647.post-1128244402269092940</id><published>2011-12-22T10:23:00.000+10:00</published><updated>2012-03-02T13:04:26.022+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-03-02T13:04:26.022+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="xi2" /><category scheme="http://www.blogger.com/atom/ns#" term="multitouch" /><category scheme="http://www.blogger.com/atom/ns#" term="tutorial" /><category scheme="http://www.blogger.com/atom/ns#" term="xorg" /><title>Multitouch in X - Getting events</title><content type="html">This post is part of a series on multi-touch support in the X.Org X server.

&lt;ol&gt;
&lt;li&gt;&lt;a href="http://who-t.blogspot.com/2011/12/multitouch-in-x-getting-events.html"&gt;Multitouch in X - Getting events&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://who-t.blogspot.com/2011/12/multitouch-in-x-pointer-emulation.html"&gt;Multitouch in X - Pointer emulation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://who-t.blogspot.com/2012/01/multitouch-in-x-touch-grab-handling.html"&gt;Multitouch in X - Touch grab handling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://who-t.blogspot.com.au/2012/02/multitouch-in-x-multitouch-touchpads.html"&gt;Multitouch in X - Multitouch-touchpads&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

I recommend re-reading &lt;a href="http://who-t.blogspot.com/2010/10/thoughts-on-linux-multitouch.html"&gt;Thoughts on Linux multitouch&lt;/a&gt; from last year for some higher-level comments.&lt;br /&gt;
In this post, I'll outline how to identify touch devices and register for touch events.
&lt;br /&gt;&lt;br /&gt;
This post assumes basic knowledge of the XI2 Xlib interfaces. Code examples
should not be scrutinised for language-correctness.
&lt;br /&gt;
&lt;h2&gt;New event types&lt;/h2&gt;
XI 2.2 defines four new event types: &lt;i&gt;XI_TouchBegin&lt;/i&gt;, &lt;i&gt;XI_TouchUpdate&lt;/i&gt;, &lt;i&gt;XI_TouchEnd&lt;/i&gt; are the standard events that most applications will be using. The fourth event, &lt;i&gt;XI_TouchOwnership&lt;/i&gt; is mainly for handling specific situations where reaction speed is at a premium and gesture processing when grabs are active. I won't be covering those in this post.
&lt;h2&gt;
Identifying touch devices&lt;/h2&gt;
To use multitouch functionality from a client application, the client must announce support for the X Input Extension version 2.2 through the &lt;a href="http://www.x.org/archive/X11R7.5/doc/man/man3/XIQueryVersion.3.html"&gt;XIQueryVersion(3)&lt;/a&gt; request. 
&lt;pre&gt;
int major = 2, minor = 2;
XIQueryVersion(dpy, &amp;major, &amp;minor);
if (major * 1000 + minor &lt; 2002)
    printf("Server does not support XI 2.2\n");
&lt;/pre&gt;
Once announced, an &lt;a href="http://www.x.org/archive/X11R7.5/doc/man/man3/XIQueryDevice.3.html"&gt;XIQueryDevice(3)&lt;/a&gt; call may return a new class type, the &lt;i&gt;XITouchClass&lt;/i&gt;. If this class is present on a device, the device supports multitouch.The class struct itself is defined like this:&lt;br /&gt;
&lt;pre&gt;typedef struct
{
    int         type;
    int         sourceid;
    int         mode;
    int         num_touches;
} XITouchClassInfo;
&lt;/pre&gt;
The &lt;b&gt;num_touches&lt;/b&gt; field specifies the number of simultaneous touches supported by the device. If the number is 0, we simply don't know (likely) or the device supports an unlimited number of touches (less likely). Regardless of the value expect that some devices lie, so it's best to treat this value as a guide only.

&lt;br/&gt;
&lt;br/&gt;
The &lt;b&gt;mode&lt;/b&gt; field specifies the type of touch devices. We currently define two types and the server behaviour differs depending on the type:
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;XIDirectTouch&lt;/b&gt; for direct-input touch devices (e.g. your average touchscreen or tablet).&amp;nbsp; For this type of device, the touch events will be delivered to the windows at the of the touch point. Again, similar to what you would expect from a tablet interface - you press top left and the application top-left responds.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;XIDependentTouch&lt;/b&gt; for a indirect input devices with multi-touch functionality. Touchpads are the prime example here. Touch events on such devices will be sent to the window underneath the cursor and clients are expected to interpret the touchpoints as (semantically) relative to the cursor position. For example, if your cursor is inside a Firefox window and you touch with two fingers on the top-left corner of the touchpad, Firefox will get those events. It can then decide on how to interpret those touchpoints.&lt;/li&gt;
&lt;/ul&gt;
A device that has a TouchClass may send touch events, but these events use the same axes as pointer events. Having said that, a touch device may still send pointer events as well - if the physical device generates both.
&lt;br /&gt;
Your code to identify touch devices could roughly look like this:
&lt;br /&gt;
&lt;pre&gt;XIDeviceInfo *info;
int nevices;

info = XIQueryDevice(display, XIAllDevices, &amp;amp;ndevices);

for (i = 0; i &amp;lt; ndevices; i++)
{
    XIDeviceInfo *dev = &amp;amp;info[i];
    printf("Device name %d\n", dev-&amp;gt;name);
    for (j = 0; j &amp;lt; dev-&amp;gt;num_classes; j++)
    {
        XIAnyClassInfo *class = dev-&amp;gt;classes[j];
        XITouchClassInfo *t = (XITouchClassInfo*)class;

        if (class-&amp;gt;type != XITouchClass)
            continue;

        printf("%s touch device, supporting %d touches.\n",
               (t-&amp;gt;mode == XIDirectTouch) ?  "direct" : "dependent",
               t-&amp;gt;num_touches);
    }
}

&lt;/pre&gt;
&lt;h2&gt;
Selecting for touch events&lt;/h2&gt;
Selecting for touch events on a window is mostly identical to pointer events. A client creates an event mask and submits it with &lt;a href="http://www.x.org/archive/X11R7.5/doc/man/man3/XISelectEvents.3.html"&gt;XISelectEvents(3)&lt;/a&gt;. One exception applies: a client must always select for all three touch events &lt;a href="#footnote_1"&gt;[1]&lt;/a&gt;, &lt;i&gt;XI_TouchBegin&lt;/i&gt;, &lt;i&gt;XI_TouchUpdate&lt;/i&gt;, &lt;i&gt;XI_TouchEnd&lt;/i&gt;. Selecting for one or two only will result in a BadValue error.
&lt;br/&gt;&lt;br/&gt;
As for button events, only one client may select for touch events on any given window and the event delivery attempts traverse from the bottom-most window in the window tree up to the root window. Where a matching event selection is found, the event is delivered and the traversal stops.

&lt;br /&gt;
&lt;h2&gt;
Handling touch events&lt;/h2&gt;
The three event types &lt;a href="#footnote_1"&gt;[1]&lt;/a&gt; are &lt;i&gt;XIDeviceEvents&lt;/i&gt; like pointer and keyboard events. So from a client's point of view, in essence all we added was new event types.&lt;br /&gt;
&lt;br /&gt;
The &lt;b&gt;detail&lt;/b&gt; field of touch events specifies the touch ID, a unique ID for this particular touch for the lifetime of the touch sequence. Each touch sequence consists of a TouchBegin event, zero or more TouchUpdate events and one TouchEnd event. Since multiple touch sequences may be ongoing at any time, keeping track of the ID is important. The server guarantees that the touch ID is unique per device and that it will not be re-used &lt;a href="#footnote_2"&gt;[2]&lt;/a&gt;. Note that while touch IDs increase, they increase by an implementation-defined amount. Don't rely on the next touch ID to be the current ID + 1. 
&lt;br /&gt;
&lt;br /&gt;
The button state in a touch event is the state of the physical buttons only. A TouchUpdate or TouchEnd event will thus usually have a zero button state. &lt;a href="#footnote_3"&gt;[3]&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
That's pretty much it, otherwise the handling of touch events is identical to pointer or keyboard events. Touch event handling should be straightforward and the significant deviations from the current protocol are in the grab handling, something I'll handle in a future post.

&lt;br /&gt;
&lt;br /&gt;
&lt;small&gt;
&lt;a href="" name="footnote_1"&gt;&lt;/a&gt;[1] I know, it's four. Good that you're paying attention.&lt;br/&gt;
&lt;a href="" name="footnote_2"&gt;&lt;/a&gt;[2] Technically ID collision may occur. For that to happen, you'd need to hold at least one touch down while triggering enough touches to exhaust a 32 bit ID range. And hope that after the wraparound you will get the same ID. There are better ways to spend your weekend.&lt;br/&gt;
&lt;a href="" name="footnote_3"&gt;&lt;/a&gt;[3] pointer emulation changes this, but I'll get to that some other time.&lt;br/&gt;
&lt;/small&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6112936277054198647-1128244402269092940?l=who-t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Who-t/~4/34WFAyndvzs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://who-t.blogspot.com/feeds/1128244402269092940/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6112936277054198647&amp;postID=1128244402269092940" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/1128244402269092940?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/1128244402269092940?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Who-t/~3/34WFAyndvzs/multitouch-in-x-getting-events.html" title="Multitouch in X - Getting events" /><author><name>Peter Hutterer</name><uri>http://www.blogger.com/profile/17204066043271384535</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://who-t.blogspot.com/2011/12/multitouch-in-x-getting-events.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUYGQH46fCp7ImA9WhRXE04.&quot;"><id>tag:blogger.com,1999:blog-6112936277054198647.post-4647055768960313953</id><published>2011-12-15T13:04:00.000+10:00</published><updated>2011-12-20T08:18:41.014+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-20T08:18:41.014+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="xi2" /><category scheme="http://www.blogger.com/atom/ns#" term="multitouch" /><title>Multitouch patches posted</title><content type="html">After pulling way too many 12+ hour days, I've finally polished the patchset for native multitouch support in the X.Org server into a reasonable state. The &lt;a href="http://lists.freedesktop.org/archives/xorg-devel/2011-December/027775.html"&gt;full set of patches&lt;/a&gt; is now on the list. And I'm still expecting this to get merged for 1.12 (and thus in time for Fedora 17). &lt;br /&gt;
&lt;br /&gt;
The code is available from the &lt;i&gt;multitouch&lt;/i&gt; branches of the following repositories:&lt;br /&gt;
&lt;pre&gt;  git://people.freedesktop.org/~whot/xserver
  git://people.freedesktop.org/~whot/inputproto
  git://people.freedesktop.org/~whot/xf86-input-evdev
  git://people.freedesktop.org/~whot/libXi
&lt;/pre&gt;
Here's a screencast running Fedora 16 with the modified X server and a little multitouch event debugging application.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;object class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="http://i.ytimg.com/vi/TBZtSf3sgeQ/0.jpg" height="266" width="320"&gt;&lt;param name="movie" value="http://www.youtube.com/v/TBZtSf3sgeQ?version=3&amp;f=user_uploads&amp;c=google-webdrive-0&amp;app=youtube_gdata" /&gt;
&lt;param name="bgcolor" value="#FFFFFF" /&gt;
&lt;embed width="320" height="266"  src="http://www.youtube.com/v/TBZtSf3sgeQ?version=3&amp;f=user_uploads&amp;c=google-webdrive-0&amp;app=youtube_gdata" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;
&lt;br /&gt;
Below is a short summary of what multitouch in X actually means, but one thing is important: being the windowing system, X provides multitouch &lt;b&gt;support&lt;/b&gt;. That does not mean that every X application now supports multitouch, it merely means that they can now &lt;i&gt;use&lt;/i&gt; multitouch if they want to. That also includes gestures, they need application support.&lt;br /&gt;
&lt;br /&gt;
A car analogy: X provides a new road, the applications still have to opt to drive on it.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
Multitouch events&lt;/h2&gt;
XI 2.2 adds three main event types: XI_TouchBegin, XI_TouchUpdate and XI_TouchEnd. These three make up a touch sequence. X clients must subscribe to all three events at once and will then receive the events as they come in from the device (more or less, grabs can interfere here). Each touch event has a unique touch ID so clients can track the touches over time.&lt;br /&gt;
&lt;br /&gt;
We support two device types: XIDirectDevice includes tablets and touchscreens where the events are delivered to the position the touch occurs at. XIDependentDevice includes multitouch-capable touchpads. Such devices still control a normal pointer by default, but for multi-finger gestures are possible. For such devices, the touchpoints are delivered to the window underneath the pointer.&lt;br /&gt;
&lt;br /&gt;
That is pretty much the gist of it. I'll post more information over time as the release gets closer, so stay tuned.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
Pointer emulation&lt;/h2&gt;
Multitouch can be a compelling interaction method but as said above, X only provides &lt;b&gt;support&lt;/b&gt; for multitouch. It will take a while for applications to pick it up (&lt;a href="http://blogs.gnome.org/carlosg/"&gt;Carlos Garnacho is working on GTK3&lt;/a&gt;) and some never will. Since we still need to interact with those applications, we provide backwards-compatible pointer emulation. Again, the details are in the protocol but the gist of it is that for the first touchpoint we emulate pointer events.&lt;br /&gt;
&lt;br /&gt;
That's the really nasty bit, because you now have to sync up the grab event semantics of the core, XI 1.x and XI2 protocols and wrap it all around the new grab semantics. So that if you have a multitouch app running under a window manager without multitouch support everything still works as expected.&lt;br /&gt;
That framework is now in place too though I expect it to still have bugs, especially in the hairier corner cases.&lt;br /&gt;
&lt;br /&gt;
But other than that, it should work just as intended. I can interact with my GNOME3 desktop quite well and I get multitouch events to my test applications.&lt;br /&gt;
&lt;br /&gt;
[edit Dec 20: typo fix]&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6112936277054198647-4647055768960313953?l=who-t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Who-t/~4/C2iltvx4a74" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://who-t.blogspot.com/feeds/4647055768960313953/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6112936277054198647&amp;postID=4647055768960313953" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/4647055768960313953?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/4647055768960313953?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Who-t/~3/C2iltvx4a74/multitouch-patches-posted.html" title="Multitouch patches posted" /><author><name>Peter Hutterer</name><uri>http://www.blogger.com/profile/17204066043271384535</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://who-t.blogspot.com/2011/12/multitouch-patches-posted.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0YHQ3Y7fip7ImA9WhRQEk0.&quot;"><id>tag:blogger.com,1999:blog-6112936277054198647.post-1528783139374363600</id><published>2011-12-06T17:30:00.005+10:00</published><updated>2011-12-07T08:05:32.806+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-07T08:05:32.806+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="multitouch" /><category scheme="http://www.blogger.com/atom/ns#" term="xorg" /><title>A short update on multitouch</title><content type="html">For the last couple of weeks I've been pretty much working full-time on getting multitouch/XI 2.2 ready for the merge (well, I was on holidays for a bit too). So first of all - sorry if I've been ignoring bugs or emails, I'm working to a few deadlines here. Anyway, here's a bit of a status update.&lt;br /&gt;&lt;br /&gt;Right now, it looks like touch event delivery is working, including nested grabs.Chase Douglas started on the pointer emulation while I was away and we're now at the point where emulation works, except that pointer grabs on top of multitouch clients aren't handled yet. I'm still rather optimistic to get this into 1.12, though it's getting a bit unwieldly. Carlos Garnacho has already sent me some patches, so he's testing the lot against the GTK branches.&lt;br /&gt;&lt;br /&gt;However, since touch support cannot simply be bolted on top and needs to be integrated properly, this has triggered some extra rewrites here and there. I'm currently some 200 commits ahead of  master sync-point. I'm planning to get this number down to something sane before merging but meanwhile, sorry, I'll have to keep ignoring you until this is done.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6112936277054198647-1528783139374363600?l=who-t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Who-t/~4/-lcWDyWwL-Q" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://who-t.blogspot.com/feeds/1528783139374363600/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6112936277054198647&amp;postID=1528783139374363600" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/1528783139374363600?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/1528783139374363600?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Who-t/~3/-lcWDyWwL-Q/short-update-on-multitouch.html" title="A short update on multitouch" /><author><name>Peter Hutterer</name><uri>http://www.blogger.com/profile/17204066043271384535</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://who-t.blogspot.com/2011/12/short-update-on-multitouch.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak4NQXk6cCp7ImA9WhRRF0U.&quot;"><id>tag:blogger.com,1999:blog-6112936277054198647.post-7877096907711500974</id><published>2011-12-02T11:06:00.004+10:00</published><updated>2011-12-02T11:23:10.718+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-02T11:23:10.718+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="workflow" /><title>Improving code readability through temporary variables</title><content type="html">We don't always have the luxury of using library interfaces that are sensibly designed and enforce readability self-explanatory (see &lt;a href="http://cworth.org/~cworth/papers/guadec_2006/"&gt;this presentation&lt;/a&gt;). A fictional function may look like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;extern void foo(struct foo *f, &lt;br /&gt;                Bool check_device, &lt;br /&gt;                int max_devices, &lt;br /&gt;                Bool emulate);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;But a calls often end up like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;foo(mystruct, TRUE, 0, FALSE);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Or, even worse, the function call could be:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;foo(mystruct, !dev-&gt;invalid, 0, list_is_first_entry(dev-&gt;list));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The above is virtually unreadable and to understand it one needs to look at the function definition and the caller at the same time. The simple use of a temporary variable can do wonders here:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Bool check_device = !dev-&gt;invalid;&lt;br /&gt;Bool emulate_pointer = list_is_first_entry(dev-&gt;list));&lt;br /&gt;&lt;br /&gt;foo(mystruct, check_device, 0, emulate_pointer);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;It adds a few lines of code (though I suspect the compiler will mostly reduce the output anyway) but it improves readability. Especially in the cases where the source field name is vastly different to the implied effect. In the second example, it's immediately obvious that pointer emulation should happen for the first entry.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6112936277054198647-7877096907711500974?l=who-t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Who-t/~4/PYhYG28nVQc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://who-t.blogspot.com/feeds/7877096907711500974/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6112936277054198647&amp;postID=7877096907711500974" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/7877096907711500974?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/7877096907711500974?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Who-t/~3/PYhYG28nVQc/improving-code-readability-through.html" title="Improving code readability through temporary variables" /><author><name>Peter Hutterer</name><uri>http://www.blogger.com/profile/17204066043271384535</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>5</thr:total><feedburner:origLink>http://who-t.blogspot.com/2011/12/improving-code-readability-through.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkcHRXw8eSp7ImA9WhRTEUQ.&quot;"><id>tag:blogger.com,1999:blog-6112936277054198647.post-3710334564353642522</id><published>2011-11-02T09:07:00.004+10:00</published><updated>2011-11-02T09:27:14.271+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-02T09:27:14.271+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="workflow" /><title>The bugzilla attention span</title><content type="html">Some bugs are less important than others, and there's always a certain background noise of bugs that aren't complete deal-breakers. And there are always more of those to fix than I have time for.&lt;br /&gt;&lt;br /&gt;Every once in a while, I sweep through a list of open bugs and try to address as many as possible. Given the time constraints, I have a limited attention span for each bug. Anything that wastes time reduces the chance of a bug getting fixed. The bugs that tend to get fixed (or at least considered) are the ones with attachments: an xorg.conf, Xorg.log and whichever xorg.conf.d snippets were manually added. Always helpful is an evtest log of the device that's a problem.&lt;br /&gt;&lt;br /&gt;If it takes me 10 comments to get useful log from a bug reporter because they insist on philosophical discussions, ego-stroking, blame games, etc., chances are I've used up the allocated time for that bug before doing anything productive. And I've had it happen often enough that reporters eventually attached useful information but I just never went back to that bug. Such is life.&lt;br /&gt;&lt;br /&gt;So, in the interest of getting a bug fixed: attach the logs and stay on-topic. If something is interesting or important enough to have a philosophical discussion about it, then we can always start one later.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6112936277054198647-3710334564353642522?l=who-t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Who-t/~4/seMQBmWsbkM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://who-t.blogspot.com/feeds/3710334564353642522/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6112936277054198647&amp;postID=3710334564353642522" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/3710334564353642522?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/3710334564353642522?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Who-t/~3/seMQBmWsbkM/bugzilla-attention-span.html" title="The bugzilla attention span" /><author><name>Peter Hutterer</name><uri>http://www.blogger.com/profile/17204066043271384535</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://who-t.blogspot.com/2011/11/bugzilla-attention-span.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkIEQX0-cSp7ImA9WhdUEkg.&quot;"><id>tag:blogger.com,1999:blog-6112936277054198647.post-7816952953797099685</id><published>2011-09-29T08:55:00.001+10:00</published><updated>2011-09-29T08:55:00.359+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-29T08:55:00.359+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="workflow" /><title>Mediawiki for personal notes</title><content type="html">For years, I've had the problem of how to store my notes but finally found something that is usable.&lt;br /&gt;&lt;br /&gt;I've tried a few variations over time, but none suited my use-case sufficiently. Textfiles are too limited and become unmanageable quick. &lt;a href="http://orgmode.org"&gt;Org-Mode&lt;/a&gt; requires Emacs (Emacs and I disagree on how much pain I'm willing to accept in my hands), &lt;a href="http://zim-wiki.org"&gt;Zim&lt;/a&gt; wasn't available on RHEL and didn't scale well after a while. &lt;a href="http://live.gnome.org/Tomboy"&gt;TomBoy&lt;/a&gt; and &lt;a href="http://live.gnome.org/Gnote"&gt;Gnote&lt;/a&gt; require GNOME which doesn't work on the Mac*, aside from me always running into synchronization issues using it on three machines. I toyed with ideas like &lt;a href="http://www.evernote.com"&gt;Evernote&lt;/a&gt; but keeping notes in the cloud makes me slightly nervous and doesn't work for confidential stuff anyway. Other wikis I tried over the last few years were &lt;a href="http://dokuwiki.org"&gt;dokuwiki&lt;/a&gt;, &lt;a href="http://ikiwiki.info"&gt;ikiwiki&lt;/a&gt; and &lt;a href="http://www.tiddlywiki.com/"&gt;tiddlywiki&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Many moons ago, &lt;a href="http://www.hog3d.net"&gt;Aaron Stafford&lt;/a&gt; showed me how he used &lt;a href="http://mediawiki.org"&gt;MediaWiki&lt;/a&gt;. At first that didn't seem viable since it didn't cover a few things I wanted: portability, git-based backups that I can take to work and back and use on any machine I care about. Anyway, I've used this for well over a year now and it works for me.&lt;br /&gt;&lt;br /&gt;The ingredients:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;one usb stick&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.truecrypt.org/"&gt;truecrupt&lt;/a&gt; (realcrypt in Fedora's rpmfusion)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;mediawiki&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;(Note: I'm not giving step-by-step instructions because if you're setting this up, you should understand what you're doing instead of just copying commands from a random website)&lt;br /&gt;&lt;br /&gt;Preparing the USB stick is easy enough. Format it with FAT32 (if you're not suffering from having a Mac, you can use a better file system). Create a massive file with truecrypt, encrypt it. You can encrypt the entire stick but having the in-file option allows multiple encrypted files on the same stick. &lt;br /&gt;&lt;br /&gt;The filesystem for the encrypted file should be FAT32 again. Then install mediawiki in a directory, point apache to it and run through the mediawiki install process. Set the mediawiki up to use an sqlite database. Finally,  set up a cron job that essentially runs &lt;em&gt;git add * &amp;&amp; git commit -am "Autocommit $date"&lt;/em&gt; every hour. Backup is simply done by running &lt;em&gt;git push remote&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;I recommend writing a few scripts that automount the stick once you plug it in. Once that's done and on all machines you care about, you just need to plug the stick in, start httpd  and off you go. Of course, if you trust your hosting provider enough you could also set it up somewhere on the web and you can skip the USB stick madness.&lt;br /&gt;&lt;br /&gt;Now, is this setup perfect? No, by far not. Issues that I see with it:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;no text-based backend. Now that my X server is decidedly more stable that doesn't matter that much anymore&lt;/li&gt;&lt;br /&gt;&lt;li&gt;interface decidedly Web 1.0 (&lt;a href="http://tiddlywiki.org"&gt;TiddlyWiki&lt;/a&gt; is much nicer here)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;no real database merging, essentially requiring a single install instead of several synchronising ones&lt;/li&gt;&lt;br /&gt;&lt;li&gt;the mediawiki syntax is random at best, and chaotic at worst. As you get used to it becomes less of a problem&lt;/li&gt;&lt;br /&gt;&lt;li&gt;search hardly works. Not sure if that's a sqlite issue or a broken setup&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Lessons learned&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Forgetting the USB stick at work means you can't take notes at home for that evening or weekend. I now have a repeating event in my calendar to remind me to take it home.&lt;br /&gt;&lt;br /&gt;Databases don't merge and git won't help with a binary file. For a while, I kept two wikis, one for work notes, one for private stuff. But then you have something that overlaps both (e.g. a computer setup that you use at work and at home). Eventually I ended up &lt;a href="http://meta.wikimedia.org/wiki/Help:Export"&gt;dumping&lt;/a&gt; the smaller database and &lt;a href="http://meta.wikimedia.org/wiki/Help:Import"&gt;importing&lt;/a&gt; it into the other one before I had too much overlap.&lt;br /&gt;&lt;br /&gt;Categories are awesome. They're essentially tags, add &lt;span style="font-family:mono;"&gt;[[Category:Foobar]]&lt;/span&gt; to any page and the matching Category page lists all pages in that category (plus, that page can also be a page with other info). Categories can be nested.&lt;br /&gt;&lt;br /&gt;Everything must be written down. This is something of a golden rule for any note-taking attempt. Unless you take notes, your notes won't be useful.&lt;br /&gt;&lt;br /&gt;I still use a normal pencil and paper notebook. Especially when debugging I use pen and paper and then transfer the final result over to the mediawiki.&lt;br /&gt;&lt;br /&gt;Install &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/lazarus-form-recovery"&gt;Lazarus&lt;/a&gt;. It has saved me a few times.&lt;br /&gt;&lt;br /&gt;Redirects help finding pages. Whenever I search for a page with a certain title and it's not there, I add a redirect from that title to the real page. So next time, I'm sorted.&lt;br /&gt;&lt;br /&gt;I'm now re-learning how to navigate pages instead of just searching through them. This has one big benefit: on the path to a page you may encounter another page you've forgotten about and that you can now deal with again.&lt;br /&gt;&lt;br /&gt;Keep a "Log" (or "Diary") page, with short comments of what you did on each day. I've set this to my home page now and it consists of entries like "Looked at [[Fedora 16 Blocker Bugs]]". It's a quick way to jot down what you're doing, pointing to the pages that contain the actual information.&lt;br /&gt;&lt;br /&gt;As said above, I've been using this setup for quite a while now. It's not perfect but software hardly ever is. The final ingredient though I only found last week: the &lt;a href="http://www.lacie.com/products/product.htm?id=10425"&gt;LACIE MosKeyTo&lt;/a&gt;, a USB stick that sticks out by only a few mm. Before that I was always worried about breaking off the stick when I carried the laptop around.&lt;br /&gt;&lt;br /&gt;So if you're looking for note-taking software, I can't say mediawiki is perfect. But it is the most usable one I've found for me.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;small&gt;&lt;br /&gt;* My Mac is essentially a netbook and I don't really install anything on it. It keeps me from working too much at home.&lt;/small&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6112936277054198647-7816952953797099685?l=who-t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Who-t/~4/OHJUZYy2N-g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://who-t.blogspot.com/feeds/7816952953797099685/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6112936277054198647&amp;postID=7816952953797099685" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/7816952953797099685?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/7816952953797099685?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Who-t/~3/OHJUZYy2N-g/mediawiki-for-personal-notes.html" title="Mediawiki for personal notes" /><author><name>Peter Hutterer</name><uri>http://www.blogger.com/profile/17204066043271384535</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://who-t.blogspot.com/2011/09/mediawiki-for-personal-notes.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0QDQXczcCp7ImA9WhVXFUg.&quot;"><id>tag:blogger.com,1999:blog-6112936277054198647.post-6325460251092807973</id><published>2011-09-09T10:09:00.003+10:00</published><updated>2012-04-16T16:56:10.988+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-04-16T16:56:10.988+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="synaptics" /><title>Natural scrolling in the synaptics driver</title><content type="html">&lt;span style="font-size: x-small;"&gt;[updated Apr 16 2012 for smooth scrolling]&lt;/span&gt;&lt;br /&gt;
The latest version of Mac OSX (Lion) introduced a feature referred to &lt;a href="http://www.apple.com/macosx/whats-new/gestures.html"&gt;natural scrolling&lt;/a&gt;. Since I've been getting a few requests to add the same feature to the synaptics driver. At it's base natural scrolling is an inversion of the scroll direction*. We've had the ability to do this for years, though more by accident than intent.&lt;br /&gt;
The synaptics driver (until X server 1.12's &lt;a href="http://who-t.blogspot.com/2011/09/whats-new-in-xi-21-smooth-scrolling.html"&gt;smooth scrolling&lt;/a&gt;) uses buttons 4/5/6/7 for up/down/left/right scrolling. If you want up to scroll down, just swap them and you're good to go.
&lt;pre&gt;
xinput set-button-map &amp;lt;device name&amp;gt; 1 2 3 5 4&lt;/pre&gt;
Now down is up and up is down. The device name can be obtained as usual with &lt;span style="font-family: monospace;"&gt;xinput list&lt;/span&gt;. This will work for servers up to including 1.11.&lt;br /&gt;
As of synaptics 1.6RC3 (1.5.99.903), the options &lt;i&gt;VertScrollDelta&lt;/i&gt; and &lt;i&gt;HorizScrollDelta&lt;/i&gt; can now be set to a negative value. For servers supporting smooth scrolling (X server 1.12+), this effectively inverts the scroll direction.&lt;br /&gt;
* &lt;small&gt;I realise that natural scrolling in OSX may have a few other details to make it do whatever it does. Synaptics supports scroll inversion and scrolling inertia.&lt;/small&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6112936277054198647-6325460251092807973?l=who-t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Who-t/~4/Z-ilfAAXcng" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://who-t.blogspot.com/feeds/6325460251092807973/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6112936277054198647&amp;postID=6325460251092807973" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/6325460251092807973?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/6325460251092807973?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Who-t/~3/Z-ilfAAXcng/natural-scrolling-in-synaptics-driver.html" title="Natural scrolling in the synaptics driver" /><author><name>Peter Hutterer</name><uri>http://www.blogger.com/profile/17204066043271384535</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://who-t.blogspot.com/2011/09/natural-scrolling-in-synaptics-driver.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEIAQXczfCp7ImA9WhdWEUo.&quot;"><id>tag:blogger.com,1999:blog-6112936277054198647.post-7388346414248704762</id><published>2011-09-05T08:49:00.000+10:00</published><updated>2011-09-05T08:49:00.984+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-05T08:49:00.984+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="xi2" /><title>What's new in XI 2.1 - smooth scrolling</title><content type="html">This post is the last part of a series about new changes in XI 2.1. See also:
&lt;br /&gt;&lt;ul&gt;
&lt;br /&gt;&lt;li&gt;&lt;a href="http://who-t.blogspot.com/2011/09/whats-new-in-xi-21-versioning.html"&gt;What's new in XI 2.1 - versioning&lt;/a&gt;&lt;/li&gt;
&lt;br /&gt;&lt;li&gt;&lt;a href="http://who-t.blogspot.com/2011/09/whats-new-in-xi-21-xi2-defines.html"&gt;What's new in XI 2.1 - XI2 defines&lt;/a&gt;&lt;/li&gt;
&lt;br /&gt;&lt;li&gt;&lt;a href="http://who-t.blogspot.com/2011/09/whats-new-in-xi-21-raw-events.html"&gt;What's new in XI 2.1 - raw events&lt;/a&gt;&lt;/li&gt;
&lt;br /&gt;&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;The core protocol allows for up to 255 buttons but only two axes: x and y. When scroll wheels became ubiquitous, the solution was to send button events for the four scroll wheel directions. Even today, a &lt;a href="http://who-t.blogspot.com/2009/06/button-mapping-in-x.html"&gt;logical button click&lt;/a&gt; 4 results in scroll down, 5, 6, and 7 result in scroll up, left, and right, respectively.
&lt;br /&gt;
&lt;br /&gt;However, scrolling is more complex than that. Velocity information and subpixel scrolling are handy to have on scroll axes. With XI 2.1, servers may now mark some axes as axes providing scrolling information. These axes may represent real axes on the device (e.g. a mouse wheel) or be virtual axes (e.g. the edge scrolling on synaptics devices). For each scrolling axis, &lt;span style="font-style:italic;"&gt;XIQueryDevice(3)&lt;/span&gt; provides an &lt;span style="font-style:italic;"&gt;XIScrollClassInfo&lt;/span&gt;.
&lt;br /&gt;
&lt;br /&gt;&lt;pre&gt;XIDeviceInfo *info;
&lt;br /&gt;int ndevices;
&lt;br /&gt;
&lt;br /&gt;info = XIQueryDevice(display, XIAllDevices, &amp;amp;ndevices);
&lt;br /&gt;for (i = 0; i &amp;lt; ndevices; i++) {
&lt;br /&gt;     XIScrollClassInfo *scroll;
&lt;br /&gt;     for (j = 0; j &amp;lt; info[i].num_classes; j++) {
&lt;br /&gt;          scroll = info[i].classes[j];
&lt;br /&gt;          if (scroll-&amp;gt;type != XIScrollClass)
&lt;br /&gt;            continue; /* Not interested in others */
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;          printf("Valuator %d is a valuator for  ", scroll-&gt;number);
&lt;br /&gt;          switch(scroll-&gt;scroll_type) {
&lt;br /&gt;              case XIScrollTypeVertical: printf("vertical"); break;
&lt;br /&gt;              case XIScrollTypeHorizontal: printf("horizontal"); break;
&lt;br /&gt;          }
&lt;br /&gt;          printf(" scrolling\n");
&lt;br /&gt;          printf("Increment of %d is one scroll event\n", scroll-&gt;increment);
&lt;br /&gt;          if (scroll-&gt;flags &amp; XIScrollFlagsNoEmulation)
&lt;br /&gt;              printf("No emulated button events for this axis\n");
&lt;br /&gt;          if (scroll-&gt;flags &amp; XIScrollFlagsPreferred)
&lt;br /&gt;              printf("No emulated button events for this axis\n");
&lt;br /&gt;   }
&lt;br /&gt;}
&lt;br /&gt;
&lt;br /&gt;XIFreeDeviceInfo(info);
&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;The above code example runs through each class on each device, printing only the scrolling information bit. Note that for each &lt;span style="font-style:italic;"&gt;XIScrollClassInfo&lt;/span&gt;, a &lt;span style="font-style:italic;"&gt;XIValuatorClassInfo&lt;/span&gt; with the same axis number must be present. That valuator info then contains the actual details of the device.
&lt;br /&gt;
&lt;br /&gt;Let's say a &lt;span style="font-style:italic;"&gt;XIScrollClassInfo&lt;/span&gt; is available for valuator 3. This simply means that any coordinates on valuator 3 should be interpreted as scrolling events. The increment defines what delta the driver considers to be one scroll event. For an increment of +5, each delta of 5 should be regarded as one scroll unit down. For an increment of -3, each delta of 3 should be regarded as one scroll unit up (i.e. inverted).
&lt;br /&gt;
&lt;br /&gt;Note that a driver may change this at run-time. As always, a client should listen to &lt;span style="font-style:italic;"&gt;XIDeviceChangedEvents&lt;/span&gt;.
&lt;br /&gt;
&lt;br /&gt;&lt;h2&gt;Scroll button emulation&lt;/h2&gt;
&lt;br /&gt;If a driver provides smooth-scrolling valuators, the server provides two-way emulation of scroll events to remain backwards-compatible to existing X clients. For any button 4-7 event from the device, the server emulates a scroll event with the right increment on the respective axis. (Note that drivers are discouraged to use button events for scrolling if they support smooth scrolling). For any scroll event on a scroll axis axis, the server emulates the matching button 4-7 events. If the scroll event has an abs(value) less than the increment on this axis,  the server only emulates once the cumulative value of several events hits a multiple of the increment (positive or negative).
&lt;br /&gt;
&lt;br /&gt;For clients, this means they get two events for each hardware scrolling event. The one that was emulated by the server has the &lt;span style="font-style:italic;"&gt;XIPointerEmulated&lt;/span&gt; flag set and can be safely ignored by the client. The same flag is set for &lt;span style="font-style:italic;"&gt;XIRawEvents&lt;/span&gt; as well.
&lt;br /&gt;
&lt;br /&gt;A device may have multiple scoll axes of the same type. If so, one of them is marked as  &lt;span style="font-style:italic;"&gt;XIScrollFlagsPreferred&lt;/span&gt; and any legacy button events will be emulated on that axis. This bit is informative only, I don't think clients need to care about it. Plus, we're aiming for drivers to do smooth scrolling only, so hopefully we don't need to do button → scroll valuator emulation.
&lt;br /&gt;
&lt;br /&gt;&lt;h2&gt;Potential side-effects&lt;/h2&gt;
&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Pre-2.1 clients may now get valuator information from a scroll axis that they don't identify as scroll axis. For 1.x clients, this is not much of an issue. 1.x clients never knew what an axis represented anyway and needed a UI for users to select what an axis meant. 2.0 clients have axis labels and should act on those. So I think this is mostly a non-issue.
&lt;br /&gt;&lt;/li&gt;
&lt;br /&gt;&lt;li&gt;Clients that implement smooth-scrolling may act on information less than one increment. Permanent up/down movement of values less than one increment may then cause smooth scrolling events but no legacy events. I don't think this is an issue, users usually trigger the scrolling axis until they see the effect on-screen. The worst-case scenario here is that scrolling in one client requires more finger movement than in another client.
&lt;br /&gt;&lt;/li&gt;
&lt;br /&gt;&lt;li&gt;Clients cannot yet change the increment. I don't know if this will be an issue in the real world given that the actual interpretation is in the client anyway.
&lt;br /&gt;&lt;/li&gt;
&lt;br /&gt;&lt;/ul&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6112936277054198647-7388346414248704762?l=who-t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Who-t/~4/Eg7Bn2l3Jm8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://who-t.blogspot.com/feeds/7388346414248704762/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6112936277054198647&amp;postID=7388346414248704762" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/7388346414248704762?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/7388346414248704762?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Who-t/~3/Eg7Bn2l3Jm8/whats-new-in-xi-21-smooth-scrolling.html" title="What's new in XI 2.1 - smooth scrolling" /><author><name>Peter Hutterer</name><uri>http://www.blogger.com/profile/17204066043271384535</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://who-t.blogspot.com/2011/09/whats-new-in-xi-21-smooth-scrolling.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0cCQXw-eCp7ImA9WhdWEE0.&quot;"><id>tag:blogger.com,1999:blog-6112936277054198647.post-5123255977490748827</id><published>2011-09-03T09:11:00.000+10:00</published><updated>2011-09-03T09:11:00.250+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-03T09:11:00.250+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="xi2" /><title>What's new in XI 2.1 - raw events</title><content type="html">This post is part of a series about new changes in XI 2.1. See also:
&lt;br /&gt;&lt;ul&gt;
&lt;br /&gt;&lt;li&gt;&lt;a href="http://who-t.blogspot.com/2011/09/whats-new-in-xi-21-versioning.html"&gt;What's new in XI 2.1 - versioning&lt;/a&gt;&lt;/li&gt;
&lt;br /&gt;&lt;li&gt;&lt;a href="http://who-t.blogspot.com/2011/09/whats-new-in-xi-21-xi2-defines.html"&gt;What's new in XI 2.1 - XI2 defines&lt;/a&gt;&lt;/li&gt;
&lt;br /&gt;&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;Raw events were introduced in XI 2.0 to allow clients to track direct device data, before the server gets its hands on it. The prime target for these was games that needed relative mouse events.
&lt;br /&gt;
&lt;br /&gt;However, there was one flaw with raw events: they were delivered either to the root window &lt;span style="font-style:italic;"&gt;or&lt;/span&gt; to the grabbing client only. Which made them less-than-useful, since grabs are virtually everywhere: active grabs by clients, passive grabs whenever a popup or dropdown menu appears, implicit grabs whenever the button is down.
&lt;br /&gt;
&lt;br /&gt;This behaviour changes in XI 2.1. If a client announces support for XI 2.1, it will get raw events delivered to the root window &lt;span style="font-style:italic;"&gt;at all times&lt;/span&gt;.
&lt;br /&gt;
&lt;br /&gt;The second change to raw event behaviour is that the events now have the &lt;span style="font-style:italic;"&gt;sourceid&lt;/span&gt; set (&lt;a href="http://bugs.freedesktop.org/show_bug.cgi?id=34420"&gt;Bug 34420&lt;/a&gt;). The libXi interface catered for this but we never sent the value down the wire. This is fixed now in XI 2.1.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6112936277054198647-5123255977490748827?l=who-t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Who-t/~4/xCuJnUh8OlY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://who-t.blogspot.com/feeds/5123255977490748827/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6112936277054198647&amp;postID=5123255977490748827" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/5123255977490748827?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/5123255977490748827?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Who-t/~3/xCuJnUh8OlY/whats-new-in-xi-21-raw-events.html" title="What's new in XI 2.1 - raw events" /><author><name>Peter Hutterer</name><uri>http://www.blogger.com/profile/17204066043271384535</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://who-t.blogspot.com/2011/09/whats-new-in-xi-21-raw-events.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE8EQns5cSp7ImA9WhdXGUk.&quot;"><id>tag:blogger.com,1999:blog-6112936277054198647.post-3280075198686636639</id><published>2011-09-02T17:00:00.001+10:00</published><updated>2011-09-02T17:00:03.529+10:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-02T17:00:03.529+10:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="xi2" /><title>What's new in XI 2.1 - XI2 defines</title><content type="html">This post is part of a series about new changes in XI 2.1. See also:
&lt;br /&gt;&lt;ul&gt;
&lt;br /&gt;&lt;li&gt;&lt;a href="http://who-t.blogspot.com/2011/09/whats-new-in-xi-21-versioning.html"&gt;What's new in XI 2.1 - versioning&lt;/a&gt;&lt;/li&gt;
&lt;br /&gt;&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;A while ago, I spent some time staring at gdb wondering why a passive grab didn't activate. Turns out it wasn't a bug in the server after all, it was a bug in the program. The modifiers were set like this:
&lt;br /&gt;
&lt;br /&gt;&lt;pre&gt;
&lt;br /&gt;XIGrabModifiers modifiers[1];
&lt;br /&gt;modifiers[0].modifiers = AnyModifier;
&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;AnyModifier is a define that comes from the core protocol:
&lt;br /&gt;&lt;pre&gt;#define AnyModifier             (1&lt;&lt;15)  /* used in GrabButton, GrabKey */&lt;/pre&gt;
&lt;br /&gt;but XI2 provides its own define:
&lt;br /&gt;&lt;pre&gt;#define XIAnyModifier           (1U &lt;&lt; 31)&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;Passive grabs only activate if the modifiers match the current modifier state. An XI2 grab that uses AnyModifier won't activate as expected - AnyModifier looks like a normal modifier bitmask to the server.
&lt;br /&gt;
&lt;br /&gt;I wanted to reply to the reporter with "don't mix core and XI2 defines" but there's one problem: you couldn't currently write an XI2 application without using &lt;i&gt;some&lt;/i&gt; core defines (e.g. &lt;i&gt;GrabModeAsync&lt;/i&gt;). I've looked through the protocol spec and added those defines that previously forced clients to mix input-related constants. New defines now available are:
&lt;br /&gt;
&lt;br /&gt;&lt;ul&gt;
&lt;br /&gt;&lt;li&gt;XIPropModeReplace, XIPropModePrepend, and XIPropModeAppend&lt;/li&gt;
&lt;br /&gt;&lt;li&gt;XIAnyPropertyType&lt;/li&gt;
&lt;br /&gt;&lt;li&gt;XIGrabModeSync and XIGrabModeAsync&lt;/li&gt;
&lt;br /&gt;&lt;li&gt;XIGrabSuccess, XIAlreadyGrabbed, XIGrabInvalidTime, XIGrabNotViewable, and
&lt;br /&gt;XIGrabFrozen&lt;/li&gt;
&lt;br /&gt;&lt;li&gt;XIOwnerEvents, XINoOwnerEvents&lt;/li&gt;
&lt;br /&gt;&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;These will be available to any application compiling against XI 2.1 headers. All the above are identical to the core defines. Clients are still expected to use &lt;i&gt;CurrentTime&lt;/i&gt; and &lt;i&gt;None&lt;/i&gt; from the core protocol headers since neither of those two is input-related. For applications building against 2.1, the guideline to using XI2 can only be summarised as: Only use a define &lt;span style="font-style:italic;"&gt;Foo&lt;/span&gt; if there is no equivalent &lt;span style="font-style:italic;"&gt;XIFoo&lt;/span&gt; version.
&lt;br /&gt;
&lt;br /&gt;The libXi man pages have also been updated where applicable to point out the new defines. 
&lt;br /&gt;Many thanks to Timur Kristóf for uncovering this.
&lt;br /&gt;
&lt;br /&gt;XIOwnerEvents and XINoOwnerEvents are new additions to improve readability. They simply map to True/False.
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6112936277054198647-3280075198686636639?l=who-t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Who-t/~4/-cJos9qj5co" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://who-t.blogspot.com/feeds/3280075198686636639/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6112936277054198647&amp;postID=3280075198686636639" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/3280075198686636639?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6112936277054198647/posts/default/3280075198686636639?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Who-t/~3/-cJos9qj5co/whats-new-in-xi-21-xi2-defines.html" title="What's new in XI 2.1 - XI2 defines" /><author><name>Peter Hutterer</name><uri>http://www.blogger.com/profile/17204066043271384535</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://who-t.blogspot.com/2011/09/whats-new-in-xi-21-xi2-defines.html</feedburner:origLink></entry></feed>

