2003-05-22

# HSX11 Guide

Alastair
Reid

    alastair@reid-consulting-uk.ltd.uk

1999-2003
Alastair Reid

This document describes HSX11, the Haskell binding to X11, version 1.00.

## Introduction

`HSX11` is a Haskell binding to the popular `X11` library.

The library aims to provide a direct translation of the X binding into Haskell so the most important pieces of documentation you should read are the `X11` documents which can be obtained from the XFree86 website. Let me say that again because it is very important. Get hold of this documentation and read it: it tells you almost everything you need to know to use this library.

## Changes from X11 documentation

In making a Haskell binding to a C library, there are certain necessary and/or desirable changes in the interface.

These can be divided into systematic changes which are applied uniformly throughout the library and ad-hoc changes which are applied to particular parts of the interface.

### Systematic Changes

Naming Conventions

  In translating the library, we had to change names to conform with Haskell's lexical syntax: function names and names of constants must start with a lowercase letter; type names must start with an uppercase letter.

  In addition, we chose to take advantage of Haskell's module system to allow us to drop common prefixes (`X`, `XA_`, etc.) attached to X11 identifiers. For example, we translate some C functions, constants and types as follows:

  C Name | Haskell Name
  `XWindowEvent` | `windowEvent`
  `XCheckWindowEvent` | `checkWindowEvent`
  `QueuedAlready` | `queuedAlready`
  `XA_WM_ICON_NAME` | `wM_ICON_NAME`
  `XA_WM_ICON_SIZE` | `wM_ICON_SIZE`

Types

  We translate type names as follows...

  C Type | Haskell Type | Haskell Expansion
  `Display*` | `Display`
  `Screen*` | `Screen`
  `Visual*` | `Visual`
  `XFontStruct*` | `FontStruct`
  `XPoint` | `Point` | `(Position,Position)`
  `XSegment` | `Segment` | `(Position,Position,Position,Position)`
  `XRectangle` | `Rectangle` | `(Position,Position,Dimension,Dimension)`
  `XArc` | `Arc` | `(Position,Position,Dimension,Dimension,Int,Int)`
  `XColor` | `Color` | `(Pixel,Word16, Word16, Word16, Word8)`

  We systematically use a type of the form `ListFoo` as a synonym for `[Foo]` and `MbFoo` as a synonym for `Maybe Foo`. This is an unfortunate side-effect of the tool we used to generate the bindings.

  We named enumeration types so that function types would be easier to understand. For example, we added ... Note that the types are synonyms for `Int` so no extra typesafety was obtained.

Exception Handling

  We consistently raise exceptions when a function returns an error code. In practice, this only affects the following functions because most Xlib functions do not return error codes.

      allocColor
      allocNamedColor
      fetchBuffer
      fetchBytes
      fontFromGC
      getGeometry
      getIconName
      iconifyWindow
      loadQueryFont
      lookupColor
      openDisplay
      parseColor
      queryBestCursor
      queryBestSize
      queryBestStipple
      queryBestTile
      rotateBuffers
      selectInput
      storeBuffer
      storeBytes
      withdrawWindow

  The Xlib library reports most errors by invoking a user-provided error handler. The function

      setDefaultErrorHandler :: IO ()

  installs this error handler.

      int defaultErrorHandler(Display *d, XErrorEvent *ev)
      {
          char buffer[1000];
          XGetErrorText(d,ev->error_code,buffer,1000);
          printf("Error: %s\n", buffer);
          return 0;
      }

As an example of how these rules are applied in generating a function type, the C function with type:

    XDrawPoints(Display *display,
                Drawable d,
                GC gc,
                XPoint *points,
                int npoints,
                int mode)

is given the Haskell type:

    drawPoints :: Display
               -> Drawable
               -> GC
               -> [Point]
               -> CoordinateMode
               -> IO ()

### Ad hoc Changes

Finally, we chose to make some changes in the interface to better conform with idiomatic Haskell style or to allow a typesafe interface.

waitForEvent

  The function

      waitForEvent :: Display -> Word32 -> IO Bool

  reads an event with a timeout (in microseconds). It is sometimes useful in conjunction with this function:

      gettimeofday_in_milliseconds :: IO Integer

WindowAttribute operations

  We provide the following operations on WindowsAttributes:

      set_background_pixmap :: XSetWindowAttributesPtr -> Pixmap -> IO ()
      set_background_pixel  :: XSetWindowAttributesPtr -> Pixel -> IO ()
      set_border_pixmap     :: XSetWindowAttributesPtr -> Pixmap -> IO ()
      set_border_pixel      :: XSetWindowAttributesPtr -> Pixel -> IO ()
      set_bit_gravity       :: XSetWindowAttributesPtr -> BitGravity -> IO ()
      set_win_gravity       :: XSetWindowAttributesPtr -> WindowGravity -> IO ()
      set_backing_store     :: XSetWindowAttributesPtr -> BackingStore -> IO ()
      set_backing_planes    :: XSetWindowAttributesPtr -> Pixel -> IO ()
      set_backing_pixel     :: XSetWindowAttributesPtr -> Pixel -> IO ()
      set_save_under        :: XSetWindowAttributesPtr -> Bool -> IO ()
      set_event_mask        :: XSetWindowAttributesPtr -> EventMask -> IO ()
      set_do_not_propagate_mask :: XSetWindowAttributesPtr -> EventMask -> IO ()
      set_override_redirect :: XSetWindowAttributesPtr -> Bool -> IO ()
      set_colormap          :: XSetWindowAttributesPtr -> Colormap -> IO ()
      set_cursor            :: XSetWindowAttributesPtr -> Cursor -> IO ()