One more step along the Wayland

Tue, 12 Mar 2013 13:57:03 +0000

Yesterday’s lunchtime hacking was all about splitting the project into multiple files and getting it into git and onto Github – note that the mere fact of it being publically browsable does not 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 SSD to molten slag. Nor that I’m not still ashamed of it. It just keeps me slightly more honest.

Today I implemented enough of pack-message to be able to recreate the initial client→compositor message that we observed weston-info 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?).

Lessons, puzzles

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 in the wrong place. My working hypothesis is that it assumes there is one namespace for each file, and that any reference to a namespace it doesn’t know about it can be satisfied by loading a file with that name.

If I type (in-ns 'psadan.core) at the repl and that ns does not include a (:refer-clojure) form, I can’t use the symbols in clojure.core at the repl. I have not observed a similar issue wrt uses of clojure.core/foo in core.clj itself, just at the repl.

atoms! An atom is dead simple, really – conceptually at least, if not also under the hood: it’s a wrapper for an object that lets you look inside with deref and lets you change what’s inside with swap!. 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 wl_display 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.

(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))

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).

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 weston-info