<?xml version="1.0"?>
<rss version="2.0">
  <channel>
    <title>Advogato blog for dan</title>
    <link>http://www.advogato.org/person/dan/</link>
    <description>Advogato blog for dan</description>
    <language>en-us</language>
    <generator>mod_virgule</generator>
    <pubDate>Sat, 25 May 2013 04:28:34 GMT</pubDate>
    <item>
      <pubDate>Tue, 2 Apr 2013 22:10:06 GMT</pubDate>
      <title>Way(land) back when</title>
      <link>http://www.advogato.org/person/dan/diary.html?start=171</link>
      <guid>http://ww.telent.net/2013/4/2/way_land_back_when</guid>
      <description>&lt;p&gt;It&#x2019;s been a little while since I made progress on psadan ($dayjob and
daddy duty), but from looking at the commit log I see it&#x2019;s even longer
since I wrote about any of it.  So:&lt;/p&gt;
&lt;p&gt;I wrote a macro.  &lt;code&gt;with-sync&lt;/code&gt; does what he name suggests: it executes
its body, then sends a &lt;code&gt;sync&lt;/code&gt; message to the &lt;code&gt;wl_display&lt;/code&gt;, then waits
for the callback.  This is the standard Wayland way to make sure that
stuff has finished happening before doing more stuff.  The actual
macro implementation was pretty similar to writing macros in CL except
that the quasiquote escape is &lt;code&gt;~&lt;/code&gt; not &lt;code&gt;,&lt;/code&gt; &#x2013; and that this is a Lisp-1,
so declaring a local variable called &lt;code&gt;promise&lt;/code&gt; turns out to be a bad
idea when you also want to call the function &lt;code&gt;(promise)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;We refactored the &lt;code&gt;handle-message&lt;/code&gt; and &lt;code&gt;listen&lt;/code&gt; functions to return the
new state of the agent that runs them, instead of keeping the globals
in an atom inside it.  Bcause we only update globals through the
agent, this saves us from having to keep them in an atom, which felt
kind of ugly.&lt;/p&gt;
&lt;p&gt;And finally: psadan now parses the &lt;code&gt;wl_drm&lt;/code&gt; protocol as well as the
regular one &#x2013; that bit was easy, it&#x2019;s just another file of &lt;span&gt;XML&lt;/span&gt; to
parse.  This is however where I got bogged down quite comprehensively
in how we actually use the stuff though: there are a lot of bits.  I&#x2019;m
hoping that &lt;a href="https://jogamp.org/jogl/www/" &gt;&lt;span&gt;JOGL&lt;/span&gt;&lt;/a&gt; , possibly in
conjunction with its
&lt;a href="http://download.java.net/media/jogl/jogl-2.x-docs/javax/media/opengl/GLPbuffer.html" &gt;Pbuffer&lt;/a&gt;
support, is (a) relevant, (b) sufficient, but even then there&#x2019;s
titting around with ioctls to be done which is not readily doable in
the &lt;span&gt;JVM&lt;/span&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <pubDate>Thu, 21 Mar 2013 14:10:17 GMT</pubDate>
      <title>In mysterious way(land)s</title>
      <link>http://www.advogato.org/person/dan/diary.html?start=170</link>
      <guid>http://ww.telent.net/2013/3/21/in_mysterious_way_land_s</guid>
      <description>&lt;p&gt;Why are our &lt;code&gt;bind&lt;/code&gt; messages to &lt;code&gt;wl_registry&lt;/code&gt; erroring out?&lt;/p&gt;
&lt;pre&gt; 
15:19 &amp;amp;lt; daniels&amp;gt; yeah, wl_registry_bind is a special case - i think it's the 
                 one non-autogenerated marshaller we have
15:32 &amp;amp;lt; daniels&amp;gt; actually no, sorry, i'm lying through my teeth
15:32 &amp;amp;lt; daniels&amp;gt; it's no longer autogenerated
15:32 &amp;amp;lt; daniels&amp;gt; but the parser expands new_id to interface + version + id
15:33 &amp;amp;lt; daniels&amp;gt; it used to be hand-written, but is now autogenerated
15:33 &amp;amp;lt; daniels&amp;gt; http://cgit.freedesktop.org/wayland/wayland/tree/src/scanner.c#n614
16:28 &amp;amp;lt; jekstrand&amp;gt; dan_b: It is a somewhat-special case.  Basically, every time 
                   there's a new_id that does not have any type information 
                   specified, two aditional pieces of information (interface 
                   name and version) get added.
16:29 &amp;amp;lt; jekstrand&amp;gt; dan_b: That really should be documented, but it's not.  I 
                   had to grep through the scanner.c file to find it all.

&lt;/pre&gt;
&lt;p&gt;Armed with this additional info the fix was fairly straightforward: I
&lt;a href="https://github.com/telent/psadan/commit/e0b94aede0959adbe51a7f4ace863492b8db6033" &gt;augmented the &lt;span&gt;XML&lt;/span&gt; parsing/protocol generation&lt;/a&gt; to stick an additional
pair of arguments into each message that contains a new_id and no interface.&lt;/p&gt;
&lt;p&gt;Thanks to both daniels and jekstrand on irc for clearing it up.&lt;/p&gt;</description>
    </item>
    <item>
      <pubDate>Mon, 18 Mar 2013 22:10:11 GMT</pubDate>
      <title>The long way(land) round</title>
      <link>http://www.advogato.org/person/dan/diary.html?start=169</link>
      <guid>http://ww.telent.net/2013/3/18/the_long_way_land_round</guid>
      <description>&lt;p&gt;The latest round of psadan hacking was motivated by two goals&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;that it would be good to actually &lt;strong&gt;remember&lt;/strong&gt; the globals we&#x2019;re
  receiving when we send &lt;code&gt;get_registry&lt;/code&gt; to the magic registry object&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;that if we&#x2019;re going to ask for a callback when all the globals are
  notified, we should wait for it before continuing.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;We went down a couple or three dead ends on our way to this goal, but
eventually we settled on creating an agent responsible for listening
to the connection (I called it &lt;code&gt;channel&lt;/code&gt;, in the absence of any better
ideas) and dispatching (using a &lt;code&gt;handle-message&lt;/code&gt; multimethod) to some
code appropriate for each kind of message we&#x2019;re receiving.&lt;/p&gt;
&lt;h2&gt;Learnings&lt;/h2&gt;
&lt;ul&gt;&lt;li&gt;multimethods the clojure way are pretty versatile: you can dispatch
  on pretty much any property &#x2013; or derived property &#x2013; of the function
  argument, not just on type.  In our case that&#x2019;s the interface name
  and the message (event) name:
&lt;pre&gt;
 (defmulti handle-message 
   (fn [conn m] 
     [(:name (:interface m)) (:message m)]))
&#xA0;
 (defmethod handle-message [:wl_registry :global] [conn m]
   (let [[name interface version] (:args m)]
     (conn/register-global conn name interface version)))
&#xA0;
 (defmethod handle-message [:wl_callback :done] [conn m]
   (let [object (conn/get-object  conn (:object-id m))
	 promise (:promise object)]
     (when promise
       (deliver promise m))))
&#xA0;
 (defmethod handle-message :default [conn m]
   (println [&#x201C;unknown message&#x201D; (:name (:interface m)) (:message m)]))
&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;we handle the &#x201C;tell me when you&#x2019;re done&#x201D; requirement with a
  promise.  The &lt;code&gt;get-globals&lt;/code&gt; code adds &lt;a href=":https://github.com/telent/psadan/blob/a54f6d366477c85940d20164d6f5ed279a604fd0/src/psadan/channel.clj#L53" &gt;an unfulfilled
  promise&lt;/a&gt; to the callback object it creates, then once it has sent out
  its messages it &lt;a href="https://github.com/telent/psadan/blob/a54f6d366477c85940d20164d6f5ed279a604fd0/src/psadan/channel.clj#L63" &gt;derefs the promise&lt;/a&gt; , causing it to wait until
  something delivers the promise.  That something is the
  &lt;code&gt;handle-message&lt;/code&gt; implementation for &lt;code&gt;wl_callback&lt;/code&gt;, for which, see above.&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;we were trying to map &lt;code&gt;handle-message&lt;/code&gt; onto each of the messages
  parsed out of the buffer, but not doing anything with the result.
  Given that &lt;code&gt;map&lt;/code&gt; is lazy, this meant our &lt;code&gt;handle-message&lt;/code&gt; code was
  for the most part not being called.  Surrounding the &lt;code&gt;map&lt;/code&gt; form with
  a &lt;code&gt;dorun&lt;/code&gt; fixed this.&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;you send work to an agent with &lt;code&gt;(send fn ...)&lt;/code&gt; or &lt;code&gt;(send-off fn ...)&lt;/code&gt;
  which invoke the fn with the current state of the agent, &lt;em&gt;not&lt;/em&gt; with
  the agent itself.  Which is fine but offers no facility for the
  agent to send work to itself &#x2013; happily, the global/magic/special
  variable &lt;code&gt;*agent*&lt;/code&gt;, which evaluates to the currently running agent
  if any is, works nicely for this purpose
&lt;pre&gt;
(defn listen [conn]
  (let [buf (conn/read-buffer conn)
        messages (buf/parse-messages buf conn :events)]
    (dorun (map #(handle-message conn %) messages)))
  (send-off &lt;strong&gt;agent&lt;/strong&gt; listen)
  conn)
(send-off channel listen)
&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;the &#x2018;name&#x2019; field in a global is (confusingly) a number, and (more
  confusingly still) not an object id. Object number 3 in our client is a
  &lt;code&gt;wl_callback&lt;/code&gt; object, whereas the global named 3 is .. well, let&#x2019;s
  check &#x2026;
&lt;pre&gt;
psadan.core&amp;gt; (def channel (chan/open-channel &#x201C;/home/dan/private/wayland-0&#x201D;))
#&#x2019;psadan.core/channel
psadan.core&amp;gt; (chan/get-registry channel)
;; [debug output elided]
{:object-id 3, :bytes 12, :interface {:index 2, :name :wl_callback, :requests (), :events ({:index 0, :name :done, :summary nil, :args ({:name &#x201C;serial&#x201D;, :type :uint, :interface nil})}), :enums ()}, :message :done, :args (-115)}
psadan.core&amp;gt; (get @(:globals @channel) 3)
{:interface :screenshooter, :version 1}
&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Next up? At some point we need to decide whether &lt;em&gt;sending&lt;/em&gt; messages
should be done by the channel or whether it&#x2019;s OK to carry on doing
that directly in whatever thread we happen to be in.  But what would
be much more fun is to see if we can actually render a window&#x2026;&lt;/p&gt;</description>
    </item>
    <item>
      <pubDate>Thu, 14 Mar 2013 18:09:16 GMT</pubDate>
      <title>Finding a Way(land)</title>
      <link>http://www.advogato.org/person/dan/diary.html?start=168</link>
      <guid>http://ww.telent.net/2013/3/14/finding_a_way_land</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;In the next round we shall be sending it the messages we have so lovingly composed from whole cloth and see if it reacts the same way as it did when the same bytes were sent from weston-info&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And the answer is &#x2026; yes, pretty much.  We had to fix up our string
parsing to make sense of the replies, but watch:&lt;/p&gt;
&lt;pre&gt;
psadan.core&amp;gt; (def connection (conn/open-connection "/home/dan/private/wayland-0"))
#'psadan.core/connection
psadan.core&amp;gt; (defn test-send-message []
  (let [registry
        (conn/remember-object
         connection
         {:id 2 :interface (proto/find-interface-by-name :wl_registry)})
        done-cb
        (conn/remember-object
         connection
         {:id 3 :interface (proto/find-interface-by-name :wl_callback)})
        ]
    (conn/write-buffer connection
                       (buf/pack-message connection (:display connection)
                                         :requests :get_registry [registry]))
    (conn/write-buffer connection
                       (buf/pack-message connection (:display connection)
                                         :requests :sync [done-cb]))
    registry))

#'psadan.core/test-send-message
psadan.core&amp;gt; (test-send-message)
{:id 2, :interface {:index 1, :name :wl_registry, :requests ({:index 0, :name :bind, :summary "bind an object to the display", :args ({:name "name", :type :uint, :interface nil} {:name "id", :type :new_id, :interface nil})}), :events ({:index 0, :name :global, :summary "announce global object", :args ({:name "name", :type :uint, :interface nil} {:name "interface", :type :string, :interface nil} {:name "version", :type :uint, :interface nil})} {:index 1, :name :global_remove, :summary "announce removal of global object", :args ({:name "name", :type :uint, :interface nil})}), :enums ()}}
psadan.core&amp;gt; (def received (read-buffer connection))
#'psadan.core/received
psadan.core&amp;gt; (pprint (map (fn [x] [(:object-id x) (:message x) (:args x)]) (buf/parse-messages received connection :events)))
nil
([2 :global (1 "wl_display" 1)]
 [2 :global (2 "wl_compositor" 2)]
 [2 :global (3 "screenshooter" 1)]
 [2 :global (4 "text_cursor_position" 1)]
 [2 :global (5 "text_model_factory" 1)]
 [2 :global (6 "wl_data_device_manager" 1)]
 [2 :global (7 "wl_shm" 1)]
 [2 :global (8 "wl_seat" 1)]
 [2 :global (9 "input_method" 1)]
 [2 :global (10 "wl_output" 1)]
 [2 :global (11 "wl_drm" 1)]
 [2 :global (12 "wl_shell" 1)]
 [2 :global (13 "desktop_shell" 1)]
 [2 :global (14 "screensaver" 1)]
 [2 :global (15 "input_panel" 1)]
 [2 :global (16 "workspace_manager" 1)]
 [3 :done (58)]
 [1 :delete_id (3)])
&lt;/pre&gt;
&lt;p&gt;My interpretation of what&#x2019;s happening here is that we&#x2019;re sending to
the server a &#x2018;tell object 2 about all your global objects&#x2019; message,
followed by a &#x2018;tell object 3 &lt;code&gt;done&lt;/code&gt; when you&#x2019;re finished doing stuff&#x2019;
message, and as you can see from the output, the reply is a bunch of
ids for global objects sent to object 2, a &lt;code&gt;done&lt;/code&gt; event sent to object
3, and then a &lt;code&gt;delete_id&lt;/code&gt; event for object 3 sent to object 1.  I&#x2019;m
actually not sure why that last one triggers, as I don&#x2019;t think I asked
it to.  Perhaps it&#x2019;s just tidying up for me.&lt;/p&gt;
&lt;p&gt;I&#x2019;m also handwaving &#x2013; if not actually handdrowning &#x2013; a litle bit,
because really &#x2026; are these &lt;code&gt;:global&lt;/code&gt; messages sent &lt;em&gt;to&lt;/em&gt; object 2 or 
&lt;em&gt;from&lt;/em&gt; object 2?  For the moment, I am using the two directions
interchangeably, which is probably not a recipe for an easier future
life, but in the meantime I can continue to tread water.&lt;/p&gt;
&lt;p&gt;It&#x2019;s instructive, or at least reassuring, to compare this stuff with
what &lt;code&gt;weston-info&lt;/code&gt; says:&lt;/p&gt;
&lt;pre&gt;
interface: 'wl_display', version: 1, name: 1
interface: 'wl_compositor', version: 2, name: 2
interface: 'screenshooter', version: 1, name: 3
interface: 'text_cursor_position', version: 1, name: 4
interface: 'text_model_factory', version: 1, name: 5
interface: 'wl_data_device_manager', version: 1, name: 6
interface: 'wl_shm', version: 1, name: 7
	formats: XRGB8888 ARGB8888
interface: 'wl_seat', version: 1, name: 8
	capabilities: pointer keyboard
interface: 'input_method', version: 1, name: 9
interface: 'wl_output', version: 1, name: 10
	x: 0, y: 0,
	physical_width: 1024 mm, physical_height: 640 mm,
	make: 'xwayland', model: 'none',
	subpixel_orientation: unknown, output_tranform: normal,
	mode:
		width: 1024 px, height: 640 px, refresh: 60 Hz,
		flags: current preferred
interface: 'wl_drm', version: 1, name: 11
interface: 'wl_shell', version: 1, name: 12
interface: 'desktop_shell', version: 1, name: 13
interface: 'screensaver', version: 1, name: 14
interface: 'input_panel', version: 1, name: 15
interface: 'workspace_manager', version: 1, name: 16
&lt;/pre&gt;
&lt;p&gt;Top Wayland tip for today: it appears to be the case that you can make
the C library clients log protocol exchanges to stderr by putting
&lt;code&gt;WAYLAND_DEBUG=client&lt;/code&gt; in the environment.  When doing that it&#x2019;s clear
to see that &lt;code&gt;weston-info&lt;/code&gt; is making a couple of additional requests
that we&#x2019;re not.  We could add them, but I think the more pressing
concern is to make it do something with the events we&#x2019;re getting
already &#x2013; if it&#x2019;s sending us details of global objects that we might
need to know about, we should at a minimum be storing those details
somewhere instead of throwing them away &#x2026;&lt;/p&gt;</description>
    </item>
    <item>
      <pubDate>Tue, 12 Mar 2013 17:08:47 GMT</pubDate>
      <title>One more step along the Wayland</title>
      <link>http://www.advogato.org/person/dan/diary.html?start=167</link>
      <guid>http://ww.telent.net/2013/3/12/one_more_step_along_the_wayland</guid>
      <description>&lt;p&gt;Yesterday&#x2019;s lunchtime hacking was all about splitting the project into
multiple files and getting it into git and &lt;a href="https://github.com/telent/psadan" &gt;onto Github&lt;/a&gt; &#x2013; note that the mere fact of
it being publically browsable does &lt;em&gt;not&lt;/em&gt; imply that it will run,
build, walk, make tea, perform any other useful function, or even
forbear from exploding inside your computer and rendering the &lt;span&gt;SSD&lt;/span&gt; to
molten slag.  Nor that I&#x2019;m not still ashamed of it.  It just keeps me
slightly more honest.&lt;/p&gt;
&lt;p&gt;Today I implemented enough of &lt;code&gt;pack-message&lt;/code&gt; to be able to recreate
the initial client&#x2192;compositor message that we observed &lt;code&gt;weston-info&lt;/code&gt;
send last week.  Still taking extraordinary liberties with signed vs
unsigned longs, and plase note that all this code will work only on
little-endian machines (there are any big-endian machines left?).&lt;/p&gt;
&lt;h2&gt;Lessons, puzzles&lt;/h2&gt;
&lt;p&gt;Leiningen does not need you to list the source files in your
repository individually: it finds them magically.  I believed
otherwise for a while, but it turned out (slightly embarrassingly)
that I had a parenthesis i the wrong place.  My working hypothesis is
that it assumes there is one namespace for each file, and any
reference to a namespace it doesn&#x2019;t know about it can be satisfied by
loading a file with that name.&lt;/p&gt;
&lt;p&gt;If I type &lt;code&gt;(in-ns 'psadan.core)&lt;/code&gt; at the repl and that ns does not
include a &lt;code&gt;(:refer-clojure)&lt;/code&gt; form, I can&#x2019;t use the symbols in
&lt;code&gt;clojure.core&lt;/code&gt; at the repl. I have not observed a similar issue wrt
uses of &lt;code&gt;clojure.core/foo&lt;/code&gt; in core.clj itself, just at the repl.&lt;/p&gt;
&lt;p&gt;atoms!  An atom is dead simple, really &#x2013; conceptually at least, if not
also under the hood: it&#x2019;s a wrapper for an object that lets you look
inside with &lt;code&gt;deref&lt;/code&gt; and lets you change what&#x2019;s inside with &lt;code&gt;swap!&lt;/code&gt;.
For each connection we use an atom holding a mapping from object ids
to the corresponding objects, which starts out holding the singleton
object for &lt;code&gt;wl_display&lt;/code&gt; and then needs to be updated each time we
generate an object locally and each time we learn of a new object from
the peer.&lt;/p&gt;
&lt;pre&gt;
(defn open-connection [name]
  (let [s (cx.ath.matthew.unix.UnixSocket. name)
        in (. s getInputStream)
        out (. s getOutputStream)
        wl-display (global-object-factory)
        ]
    {:socket s
     :input in
     :output out
     :display wl-display
     :objects (atom (assoc {} 1 wl-display))
     }))

(defn remember-object [conn id object]
  ;; (swap r fn args...) gets the current value of the atom inside r,
  ;; which for the sake of argument we shall call oldval, then sets the atom
  ;; to the result of calling (fn oldval args...)
  (swap! (:objects conn) assoc id object)
  object)

(defn get-object [conn id]
  ;; @foo is another way to write (deref foo)
  (let [o (get @(:objects conn) id)]
    o))
&lt;/pre&gt;
&lt;p&gt;I have probably not chosen the fastest possible way of building up the
messages I plan to send, in terms of fiddling around sticking vectors
of bytes together.  Will worry about that later if it turns out to be
a bottleneck (but suggestions are welcome).&lt;/p&gt;
&lt;p&gt;There was not a lot of Wayland learning this time.  In the next round
we shall be sending it the messages we have so lovingly composed from
whole cloth and see if it reacts the same way as it did when the same
bytes were sent from &lt;code&gt;weston-info&lt;/code&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <pubDate>Thu, 7 Mar 2013 23:09:03 GMT</pubDate>
      <title>Still some way(land) to go</title>
      <link>http://www.advogato.org/person/dan/diary.html?start=166</link>
      <guid>http://ww.telent.net/2013/3/7/still_some_way_land_to_go</guid>
      <description>&lt;p&gt;Ignoring, because I can, this whole Ubuntu Mir thing completely, I
have begun to learn stuff about the &lt;a href="http://wayland.freedesktop.org/docs/html/sect-Protocol-Wire-Format.html" &gt;Wayland protocol&lt;/a&gt; (and about
Clojure, with which I am still at the
constantly-having-to-google-stuff stage).  Some random notes on what I
have learnt so far&lt;/p&gt;
&lt;p&gt;First off: Java has no builtin support for talking to unix-domain
(&lt;code&gt;AF_FILE&lt;/code&gt;) sockets. And nobody seems to make a Maven-packaged library
that does it either.  This is a shame because Leiningen makes Maven
manageable, but anything unmavened involved tedious mucking around.
Eventually I did&lt;/p&gt;
&lt;pre&gt;
:; apt-get install libunixsocket-java
:; cat project.clj
(defproject psadan "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :resource-paths ["/usr/share/java/unix-0.5.jar"]
  :url "http://example.com/FIXME"
  :jvm-opts ["-Djava.library.path=native/:/usr/lib/jni/"]
  :main psadan.core
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.3.0"]
                 [org.clojure/data.zip "0.1.1"]
                 ])
&lt;/pre&gt;
&lt;p&gt;which seems to be holding up.  Then I opened a socket and tried reading from it
in the hope of getting some lovely protocoly stuff
&lt;/p&gt;&lt;pre&gt;
(defn open-socket [name]
  (let [s (cx.ath.matthew.unix.UnixSocket. name)
        in (. s getInputStream)
        out (. s getOutputStream)
        ]
    {:socket s :input in :output out}))
&lt;p&gt;(def socket (open-socket &#x201C;/home/dan/private/wayland-0&#x201D;))&lt;/p&gt;
&lt;p&gt;(defn rd []
  (let [buf (byte-array 1024)]
    (. (:input socket) (read buf))
    buf))
&lt;/p&gt;&lt;/pre&gt;
&lt;p&gt;and watched it hang.  After some time looking at documentation and
mucking about with strace to see if it was trying to read the full
buffer instead of doing the dhort read I wanted it to, I eventually
thought to use &lt;code&gt;socat&lt;/code&gt; instead of clojure.  It turns out that the
client is expected to make the first request before the server sends
anything, and with the use of &lt;code&gt;strace weston-info&lt;/code&gt; I was able to find
out what.&lt;/p&gt;
&lt;pre&gt;
26335 sendmsg(3, {msg_name(0)=NULL, msg_iov(1)=[{"\1\0\0\0\1\0\f\0\2\0\0\0\1\0\0\0\0\0\f\0\3\0\0\0", 24}], msg_controllen=0, msg_flags=0}, MSG_DONTWAIT|MSG_NOSIGNAL) = 24
&lt;/pre&gt;
&lt;p&gt;Time to start writing some code to parse
&lt;a href="http://cgit.freedesktop.org/wayland/wayland/tree/protocol/wayland.xml?id=ae6f3001a51cce102422e4ccbeb394fe90945a12" &gt;wayland.xml&lt;/a&gt;
so we can actually find out what this means. The usual way to do &lt;span&gt;XML&lt;/span&gt; parsing in clojure seems to be using
zippers and the easy examples seem to be somewhat lacking or slightly
ungooglable.  You need a project dependency on org.clojure/data.zip
and a bunch of package requires, then you call clojure.zip/xml-zip on
the return value of clojure.xml/parse and that gets you a zipper&lt;/p&gt;
&lt;pre&gt;
(ns psadan.core
  (:require [clojure.xml]
            [clojure.data.zip :as dz]
            [clojure.data.zip.xml :as x]
            [clojure.walk]
            [clojure.zip :as z]))

;; [...]

(def the-protocol
  (-&amp;gt;
   "/home/dan/wayland/source/wayland/protocol/wayland.xml"
   clojure.xml/parse
   z/xml-zip
   parse-protocol))

&lt;/pre&gt;
&lt;p&gt;where I have conveniently left out the definition of parse-protocol
and everything it calls because it&#x2019;s longwinded and tedious (but the
code will be on github as soon as I&#x2019;m not ashamed of it) but it might
hypothetically do things like&lt;/p&gt;
&lt;pre&gt;(x/xml-&amp;gt; my-zipper :protocol :interface :request)&lt;/pre&gt;
&lt;p&gt;to descend the tree through &amp;lt;protocol&amp;gt; &amp;lt;interface&amp;gt; &amp;lt;request&amp;gt;
and return all the elements.  Use the similarly named &lt;code&gt;x/xml1-&amp;gt;&lt;/code&gt; to
get the first matching element.  The return values from these things
are themselves zippers and you can call &lt;code&gt;up&lt;/code&gt;, &lt;code&gt;down&lt;/code&gt; etc &#x2013; or &lt;code&gt;xml-&amp;gt;&lt;/code&gt;
again &#x2013; to traverse the tree further, then eventually call &lt;code&gt;node&lt;/code&gt; when
you want to get the element itself.  So e.g.&lt;/p&gt;
&lt;pre&gt;
(defn parse-interface [i n]
  ;; n is a badly named zippered xml object thingy
  (let [el (z/node n)
        requests (map-indexed parse-message (x/xml-&amp;gt; n :request))
        events (map-indexed parse-message (x/xml-&amp;gt; n :event))
        enums (map parse-enum (x/xml-&amp;gt; n :enum))]
    {:index i
     :name (:name (:attrs el))
     :requests requests
     :events events
     :enums enums
     }))
&lt;/pre&gt;
&lt;p&gt;So let&#x2019;s handwave over the details and take it on trust that I have
parsed the whole file.  There are two other things I discovered -
mostly thanks to the #wayland &lt;span&gt;IRC&lt;/span&gt; channel participants &#x2013; about the
wayland wire protocol that the docs don&#x2019;t mention:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;where it says &#x201C;The first word is the sender&#x2019;s object id (32-bit)&#x201D;,
when it&#x2019;s describing a message sent from client to compositor, what it
&lt;em&gt;means&lt;/em&gt; is &#x201C;The first word is the &lt;em&gt;target object&#x2019;s&lt;/em&gt; id (32-bit)&#x201D;.&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;object id 1 is special: it refers to the core global singleton
  object, which implements the interface &lt;code&gt;wl_display&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Given which, we can attempt to parse that first client&#x2192;compositor message&lt;/p&gt;
&lt;pre&gt;
psadan.core&amp;gt; (parse-messages-from-buf (vec (.getBytes "\1\0\0\0\1\0\f\0\2\0\0\0\1\0\0\0\0\0\f\0\3\0\0\0")) :requests)
({:object-id 1, :bytes 12, :interface "wl_display", :message "get_registry", :opcode 1, :args (2)} {:object-id 1, :bytes 12, :interface "wl_display", :message "sync", :opcode 0, :args (3)})
&lt;/pre&gt;
&lt;p&gt;Looks plausible so far &#x2026;&lt;/p&gt;
&lt;p&gt;Next up, some code to create messages.  And something, which may
involve an atom, to map object ids to their corresponding interfaces
as we learn them.  After that, we find out what the &lt;a href="http://wayland.freedesktop.org/faq.html#heading_toc_j_3" &gt;Wayland &lt;span&gt;FAQ&lt;/span&gt;&lt;/a&gt;
&lt;em&gt;really&lt;/em&gt; means by &#x201C;shareable buffer&#x201D;&lt;/p&gt;</description>
    </item>
    <item>
      <pubDate>Fri, 1 Mar 2013 12:10:13 GMT</pubDate>
      <title>Puppets at work</title>
      <link>http://www.advogato.org/person/dan/diary.html?start=165</link>
      <guid>http://ww.telent.net/2013/3/1/puppets_at_work</guid>
      <description>&lt;p&gt;Another huge long gap between updates.  I&#x2019;d say that you might as well
get used to it, but you probably are already.  This is a short note to say that I have developed a Capistrano extension which runs Puppet as part of an app deploy, and you can read about it on the &lt;a href="http://tech.simplybusiness.co.uk/2013/02/install-all-the-things-a-capistrano-extension-to-run-puppet/" &gt;Simply Business tech blog&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In other news, having confirmed that the &lt;a href="http://lwn.net/Articles/485484/" &gt;X11 touchpad
support&lt;/a&gt; is broken by design &#x2013; the
choice of whether to emulate mouse events (left click, middle click,
drag etc) is set at a global level in the driver and cannot be overridden
per client, so legacy mouse-only clients cannot meaningfully coexist
with clients that usefully &lt;em&gt;could&lt;/em&gt; handle touch events directly &#x2013; I am
working on a client implementation of the Wayland protocol in Clojure.
I hope this will eventually will turn into a habitable text editor.&lt;/p&gt;</description>
    </item>
    <item>
      <pubDate>Mon, 8 Oct 2012 22:09:35 GMT</pubDate>
      <title>Something old, something new</title>
      <link>http://www.advogato.org/person/dan/diary.html?start=164</link>
      <guid>http://ww.telent.net/2012/10/8/something_old_something_new</guid>
      <description>&lt;p&gt;Sorry for the silence.  This has been a scheduling thing mostly: I
managed to schedule &#x2018;breaking my arm&#x2019; for about three days after
&#x2018;starting a new job&#x2019;, and together with the ongoing project of &#x2018;being
a new Dad&#x2019; (I plan to pivot that one into just &#x2018;being a Dad&#x2019; if and
when I finally feel like I know what I&#x2019;m doing &#x2013; so maybe in about 20
years or so) this has left not much time for discretionary writing.&lt;/p&gt;
&lt;p&gt;Something old: a couple of months ago Vsevolod Dyomkin emailed me to
ask if I wanted to be featured in his series of interviews with 
&lt;a href="http://lisp-univ-etc.blogspot.co.uk/search/label/lisp-hackers" &gt;Lisp hackers&lt;/a&gt;
(or, in my case, former Lisp hackers).  After keeping him
waiting for unsnsionably long &#x2013; partly due, of course, to the
aforementioned bone breakage &#x2013; finally I have sent him my answers and
he has &lt;a href="http://lisp-univ-etc.blogspot.co.uk/2012/10/lisp-hackers-daniel-barlow.html" &gt;posted them&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;(I can&#x2019;t decide if I&#x2019;m actually serious about writing something
justifying the existence of &lt;span&gt;ASDF&lt;/span&gt;, or if I&#x2019;m just going to let it lie.
It can probably be summarised as &#x201C;it made sense at the time&#x201D;)&lt;/p&gt;
&lt;p&gt;Something new:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;New job: I&#x2019;m now working at &lt;a href="http://www.simplybusiness.co.uk" &gt;Simply Business&lt;/a&gt;, nominally
as a Ruby programmer but in practice so far mostly doing Puppet and
Vagrant and general devops-y deployment-y stuff. It&#x2019;s slightly odd
having a commute further than the spare bedroom (which is no longer
actually &lt;strong&gt;spare&lt;/strong&gt; now, please note) but I seem to have adjusted mostly
to having to get up in the morning, and the walk to work is podcast
time. Except when it&#x2019;s Spotify time.  Or when I take a bike, but for a
2km journey that often seems a bit like overkill.&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;New consumer toys.  After dropping the Desire S and breaking the
screen on it twice, I gave up and sniped a second hand Galaxy Nexus on
Ebay. It&#x2019;s a bit like running an Android phone, except that it has no
stupid skins or preloaded apps, and it gets timely updates to the
newest OS version.  Seriously, there is a certain irony in the
fact that a phone I chose because it was open and easy to reflash or
root turns out to be the first Android phone I&#x2019;ve owned that I haven&#x2019;t
&lt;strong&gt;needed&lt;/strong&gt; to reflash or root.  Flushed with that success (and, for the
first time in a while, flush also with some ready cash), I bagged a
tablet too.  Nexus 7, Jelly Bean again, it&#x2019;s basically like a big
version of the phone except that it doesn&#x2019;t make phone calls.&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    <item>
      <pubDate>Mon, 28 May 2012 13:07:32 GMT</pubDate>
      <title>Debian on the Samsung Series 9 NP900X3B</title>
      <link>http://www.advogato.org/person/dan/diary.html?start=163</link>
      <guid>http://ww.telent.net/2012/5/28/debian_on_the_samsung_series_9_np900x3b</guid>
      <description>&lt;p&gt;There are other guides to getting Linux going on the Samsung Series 9
NP900X3B, but both that I&#x2019;ve found are for Fedora.  Mostly it&#x2019;s the
same in Debian, but here are some of the things I&#x2019;ve spotted.&lt;/p&gt;
&lt;h2&gt;Install media&lt;/h2&gt;
&lt;p&gt;Recent versions of Debian install media images are created as hybrid
&lt;span&gt;ISO&lt;/span&gt; images, which means you can download them and dd them directly to
a &lt;span&gt;USB&lt;/span&gt; stick.  This is what I did, with the Squeeze netinst image. The
computer&#x2019;s &lt;span&gt;BIOS&lt;/span&gt; settings needed changing to look at &lt;span&gt;USB&lt;/span&gt; before the
internal &lt;span&gt;SSD&lt;/span&gt;, but that&#x2019;s not hard.  I deselected all packages which
resulted in a very minimal basic install, then added &lt;code&gt;xfce4&lt;/code&gt; and a few
essential utilities using &lt;code&gt;apt-get&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;Networking&lt;/h2&gt;
&lt;p&gt;The wired network works out of the box.&lt;/p&gt;
&lt;p&gt;The wireless networking is courtesy of an Intel 6230 adapter 
&#x201C;&lt;code&gt;Intel Corporation Centrino Advanced-N 6230 [8086:0091] (rev 34)&lt;/code&gt;&#x201D;
(apparently this also does Bluetooth, but I haven&#x2019;t tried that
yet).  This is &lt;em&gt;not&lt;/em&gt; supported in Squeeze&#x2019;s default kernel, but is
available in Wheezy.  After much swearing at backports I decided to
do the &lt;code&gt;apt-get upgrade&lt;/code&gt; dance&lt;/p&gt;
&lt;h2&gt;Touchpad&lt;/h2&gt;
&lt;p&gt;Touchpad handling worked in Squeeze and partially broke when I
upgraded to get working wifi.  Pointer movement worked fine, but
tapping (for the uninitiated, &#x201C;tapping&#x201D; on the touchpad is simulating
button presses by briefly touching the pressure-sensitive area instead
of the hardware buttons below it) didn&#x2019;t.  On this system tapping is
infinitely preferable to the hardware buttons, because it appears
impossible to move the pointer while one of the hardware buttons is
pressed &#x2013; this makes window placement pretty tricky.  The fix here is&lt;/p&gt;
&lt;pre&gt;synclient TapButton1=1 
synclient TapButton2=2 
synclient TapButton2=3 
synclient PalmDetect=1
&lt;/pre&gt;
&lt;p&gt;which means you can use one finger to simulate button 1, two fingers
simultaneously (note: not double-clicking, as I foolishly initially
thought) to simulate button 2, and three for button 3.  It also turns
on palm detection, so that accidentally brushing the pad as you type
won&#x2019;t send your cursor off into the wild blue yonder.&lt;/p&gt;
&lt;p&gt;This affect the current session only.  To make it permanent you need to
edit files: copy
&lt;code&gt;/usr/share/X11/xorg.conf.d/50-synaptics.conf&lt;/code&gt; to
&lt;code&gt;/etc/X11/xorg.conf.d&lt;/code&gt; and add the lines&lt;/p&gt;
&lt;pre&gt;
        Option "TapButton1" "1"
        Option "TapButton2" "2"
        Option "TapButton3" "3"
        Option "PalmDetect" "1"
&lt;/pre&gt;
&lt;p&gt;in the first &lt;code&gt;Section "InputClass"&lt;/code&gt; stanza&lt;/p&gt;
&lt;h2&gt;Suspend and hibernate&lt;/h2&gt;
&lt;p&gt;I had the same problem with suspend as 
&lt;a href="http://jtes.net/2012/03/23/samsung-series-9-2012-np900x3b/" &gt;John Teslade&lt;/a&gt; :
it appears not to resume but in fact it works perfectly except for the
display backlight.  However, I had it harder because my Fn-F2 and
Fn-F3 keys didn&#x2019;t do anything.  After determining with &lt;code&gt;acpi_listen&lt;/code&gt;
that Linux is listening to those keys (they send &lt;span&gt;ACPI&lt;/span&gt; events
&lt;code&gt;video/brightnessdown&lt;/code&gt; and &lt;code&gt;video/brightnessup&lt;/code&gt; respectively) and is
capable of controlling the brightness (try e.g. &lt;code&gt;xrandr --output eDP1
--set BACKLIGHT 1&lt;/code&gt;) I decided this must clearly be a 90% solved
problem and that the missing link was probably somewhere in the Debian
package archive.  It was, it was &lt;code&gt;xfce4-power-manager&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;After that, suspend and hibernate are both usable.&lt;/p&gt;
&lt;h2&gt;Battery life&lt;/h2&gt;
&lt;p&gt;Pretty poor right now (looks like about 3 hours), but I&#x2019;ve just
installed &lt;code&gt;laptop-mode-tools&lt;/code&gt; which has turned most of the PowerTOP
tunables from &#x201C;Bad&#x201D; to &#x201C;Good&#x201D;, so I will be disappointed if that
doesn&#x2019;t make a significant difference.  We&#x2019;ll see &#x2026;&lt;/p&gt;</description>
    </item>
    <item>
      <pubDate>Sat, 5 May 2012 16:09:16 GMT</pubDate>
      <title>Changing sort order with ActiveRecord find_in_batches</title>
      <link>http://www.advogato.org/person/dan/diary.html?start=162</link>
      <guid>http://ww.telent.net/2012/5/4/changing_sort_order_with_activerecord_find_in_batches</guid>
      <description>&lt;p&gt;The subject is Googlebait pure and simple, because the short version
is that you can&#x2019;t.  The very slightly longer and significantly more
defensible version is that you may be able to but &lt;a href="https://rails.lighthouseapp.com/projects/8994/tickets/2502-patch-arbase-reverse-find_in_batches" &gt;they don&#x2019;t want you
to&lt;/a&gt;
apparently because you might get the wrong answer if you mutate the
data as you&#x2019;re traversing it (and because it&#x2019;s fast in MySql).&lt;/p&gt;
&lt;p&gt;Personally I think the answer there is Well Don&#x2019;t Do That Then (and
who cares about MySql) but that&#x2019;s just my opinion.  If you want to order by,
say, &lt;code&gt;created_at descending&lt;/code&gt;, and perhaps you want to paginate the
results, the only sensible conclusion to draw is that
&lt;code&gt;find_in_batches&lt;/code&gt; is just not intended for this use.&lt;/p&gt;
&lt;p&gt;But it&#x2019;s not an unreasonable use.  So I wrote
&lt;a href="https://github.com/telent/ar-as-batches/blob/master/README.md" &gt;ar-as-batches&lt;/a&gt; 
which lets you do&lt;/p&gt;
&lt;pre&gt;
Users.where(country_id: 44).order(:joined_at).offset(200).as_batches do |user|
  user.party_all_night!
end
&lt;/pre&gt;
&lt;p&gt;and it all works as you&#x2019;d expect.  I should of course caution you that&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;you might get the wrong answer if you mutate the data as you&#x2019;re
traversing it (so Don&#x2019;t Do That Then), and that&lt;/li&gt;
	&lt;li&gt;ordering by something other than &lt;code&gt;id ascending&lt;/code&gt; may be slower in MySql.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;I don&#x2019;t know whether to be proud or ashamed of the
&lt;a href="https://github.com/telent/ar-as-batches/blob/master/test/as-batches-test.rb" &gt;tests&lt;/a&gt;
, which check
the generated queries by assigning a &lt;code&gt;StringIO&lt;/code&gt; logger to
&lt;code&gt;ActiveRecord::Base.logger&lt;/code&gt; and then matching regexps in it after each
test runs.  There ought to be a  better way.  Perhaps there &lt;em&gt;is&lt;/em&gt; a
better way.  Don&#x2019;t know what though.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
