[Haskell-cafe] X Haskell Bindings
spencerjanssen at gmail.com
Sun Aug 17 20:34:42 EDT 2008
On Sat, Aug 16, 2008 at 04:07:25PM -0500, Antoine Latter wrote:
> 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.
I think this is a nice idea. This type signature from the X11 library is
createWindow :: Display -> Window -> Position -> Position -> Dimension
-> Dimension -> CInt -> CInt -> WindowClass -> Visual ->
AttributeMask -> Ptr SetWindowAttributes -> IO Window
> 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 ()
Classic libX11 does this, and it is rather inconvenient to program with.
Occasionally it is necessary to handle an error thrown by a specific request,
yielding code like this:
do h <- getHandler c -- save the old handler so we can restore it later
setHandler c myHandlingFn
setHandler c h
Not only is this code ugly, it does not work correctly when the connection may
be concurrently used by several threads.
> Or is something like this enough:
> > pollForError :: Connection -> IO (Maybe (XError))
> > waitForError :: Connection -> IO XError
I think XCB's error system is particularly nice. Requests with no
corresponding responses have two variants: unchecked (the default), and
checked. Unchecked requests have a void return type, and any errors they
generate go in the error queue. Checked requests return a cookie (the same
mechanism used for requests with responses) which can be used to collect any
errors generated by that response.
> 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