[Haskell-cafe] X Haskell Bindings

Antoine Latter aslatter at gmail.com
Sat Aug 16 17:07:25 EDT 2008


I'm slowly porting XCB (the X C Bindings) to Haskell, and I would like
input from any interested parties.

The following is a summary of my plan so far.  I'm interested in
hearing any suggestions or concerns about what a Haskell library for
writing X clients should look like.  This is not a release
announcement, and I can't make any promises about when this will be

Code is available in darcs:
--  darcs get http://community.haskell.org/~aslatter/code/xhb

Some of the  advantages XCB claims over xlib are:
  + smaller API
  + latency hiding when communicating with the X server
  + direct access to the X protocol
  + improved threading support
  + easier to extend

What I plan for the X Haskell Bindings (XHB) are as follows:

 + All requests to the server are non-blocking (under most circumstances)

 + Requests which produce a reply from the server return a "token" or "receipt"

 + The caller may then, at a time of their choosing, query the receipt
for the response (or error) from the
    server.  This query is blocking.

The API will look something like:

> -- | Create a window as specified
> createWindow :: Connection -> CreateWindow -> IO ()

> -- | Instruct the server that it should begin displaying the named window
> mapWindow :: Connection -> WINDOW -> IO ()

> -- | List all of the extensions supported by the server
> listExtensions :: Connection -> IO (Receipt (ListExtensionsReply))

> -- | Query a receipt for a response
> getReply :: Receipt a -> IO (Either XError a)

Note that the first two requests do not have replies, whereas the
third request expects a reply from the server.

Since the request to create a window has so many parameters, these
parameters are all wrapped up into a "CreateWindow" data type, which
is only ever used by the "createWindow" function.  The "mapWindow"
request only has one parameter, so it does not need it's own
"MapWindow" data type.

What I don't have planned out is what to do with the stream of events
and errors that come back from the server.

If an error is related to an outstanding receipt, it gets dumped there
for the caller to examine directly.  Other errors go into an error

Events go into a similar event queue.

How should this queue be exposed in the API?  Should the user of the
library register an error/event callback?

> registerErrorCallback :: Connection -> (XError -> IO ()) -> IO ()

Or is something like this enough:

> pollForError :: Connection -> IO (Maybe (XError))

> waitForError :: Connection -> IO XError

Each X extension defines its own set of errors and events
(potentially).  Should all of these be lumped together into one giant
sum-type for errors and one for events?

Take care,

More information about the Haskell-Cafe mailing list