    {-# LINE 1 "Graphics/X11/Xlib/Font.hsc" #-}
    {-# LANGUAGE DeriveDataTypeable #-}
    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Graphics.X11.Xlib.Font
    -- Copyright   :  (c) Alastair Reid, 1999-2003
    -- License     :  BSD-style (see the file libraries/base/LICENSE)
    --
    -- Maintainer  :  libraries@haskell.org
    -- Stability   :  provisional
    -- Portability :  portable
    --
    -- A collection of FFI declarations for interfacing with Xlib Fonts.
    --
    -----------------------------------------------------------------------------

    module Graphics.X11.Xlib.Font(

            Glyph,
            queryFont,
            fontFromGC,
            loadQueryFont,
            freeFont,
            FontStruct,
            fontFromFontStruct,
            ascentFromFontStruct,
            descentFromFontStruct,
            CharStruct,
            textExtents,
            textWidth,

            ) where

    import Graphics.X11.Types
    import Graphics.X11.Xlib.Types

    import Foreign (Ptr, Int32, alloca, allocaBytes, peekByteOff, Word16, Word64, peek, throwIfNull)
    {-# LINE 39 "Graphics/X11/Xlib/Font.hsc" #-}
    import Foreign.C

    import System.IO.Unsafe

    {-# LINE 44 "Graphics/X11/Xlib/Font.hsc" #-}
    import Data.Data

    {-# LINE 46 "Graphics/X11/Xlib/Font.hsc" #-}

    ----------------------------------------------------------------
    -- Fonts
    ----------------------------------------------------------------

    -- A glyph (or Char2b) is a 16 bit character identification.
    -- The top 8 bits are zero in many fonts.
    type Glyph = Word16

    -- | pointer to an X11 @XFontStruct@ structure
    newtype FontStruct = FontStruct (Ptr FontStruct)

    {-# LINE 58 "Graphics/X11/Xlib/Font.hsc" #-}
            deriving (Eq, Ord, Show, Typeable, Data)

    {-# LINE 62 "Graphics/X11/Xlib/Font.hsc" #-}

    -- Disnae exist: %fun LoadFont       :: Display -> String -> IO Font
    -- Disnae exist: %fun UnloadFont     :: Display -> Font -> IO ()

    -- Argument can be a Font or a GContext.
    -- But, if it's a GContext, the fontStruct will use the GContext as the
    -- FontID - which will cause most things to break so it's probably
    -- safer using XGetGCValues to get a genuine font ID

    -- | interface to the X11 library function @XQueryFont()@.
    foreign import ccall unsafe "HsXlib.h XQueryFont"
            queryFont     :: Display -> Font -> IO FontStruct

    -- Note that this _WILL NOT WORK_ unless you have explicitly set the font.
    -- I'm slowly but surely coming to the conclusion that Xlib is a pile of
    -- steaming shit.

    -- | interface to the X11 library function @XGetGCValues()@.
    fontFromGC :: Display -> GC -> IO Font
    fontFromGC display gc =
            allocaBytes (128) $ \ values -> do
    {-# LINE 83 "Graphics/X11/Xlib/Font.hsc" #-}
            throwIfZero "fontFromGC" $
                    xGetGCValues display gc 16384 values
    {-# LINE 85 "Graphics/X11/Xlib/Font.hsc" #-}
            (\hsc_ptr -> peekByteOff hsc_ptr 88) values
    {-# LINE 86 "Graphics/X11/Xlib/Font.hsc" #-}
    foreign import ccall unsafe "HsXlib.h XGetGCValues"
            xGetGCValues :: Display -> GC -> ValueMask -> Ptr GCValues -> IO CInt

    type ValueMask = Word64
    {-# LINE 90 "Graphics/X11/Xlib/Font.hsc" #-}

    -- | interface to the X11 library function @XLoadQueryFont()@.
    loadQueryFont :: Display -> String -> IO FontStruct
    loadQueryFont display name =
            withCString name $ \ c_name -> do
            fs <- throwIfNull "loadQueryFont" $ xLoadQueryFont display c_name
            return (FontStruct fs)
    foreign import ccall unsafe "HsXlib.h XLoadQueryFont"
            xLoadQueryFont :: Display -> CString -> IO (Ptr FontStruct)

    -- | interface to the X11 library function @XFreeFont()@.
    foreign import ccall unsafe "HsXlib.h XFreeFont"
            freeFont      :: Display -> FontStruct -> IO ()
    -- %fun XSetFontPath  :: Display -> ListString  -> IO () using XSetFontPath(arg1,arg2,arg2_size)

    fontFromFontStruct :: FontStruct -> Font
    fontFromFontStruct (FontStruct fs) = unsafePerformIO $
            (\hsc_ptr -> peekByteOff hsc_ptr 8) fs
    {-# LINE 108 "Graphics/X11/Xlib/Font.hsc" #-}

    ascentFromFontStruct :: FontStruct -> Int32
    ascentFromFontStruct (FontStruct fs) = unsafePerformIO $
            (\hsc_ptr -> peekByteOff hsc_ptr 88) fs
    {-# LINE 112 "Graphics/X11/Xlib/Font.hsc" #-}

    descentFromFontStruct :: FontStruct -> Int32
    descentFromFontStruct (FontStruct fs) = unsafePerformIO $
            (\hsc_ptr -> peekByteOff hsc_ptr 92) fs
    {-# LINE 116 "Graphics/X11/Xlib/Font.hsc" #-}

    -- %prim XGetFontPath :: Display -> IO ListString
    --Int r_size;
    --String* r = XGetFontPath(arg1,&r_size);
    -- %update(r);
    --XFreeFontPath(r);
    --return;

    -- %prim XListFonts :: Display -> String -> Int -> IO ListString
    --Int r_size;
    --String *r = XListFonts(arg1,arg2,arg3,&r_size);
    -- %update(r);
    --XFreeFontNames(r);
    --return;

    -- XListFontsWithInfo omitted (no support for FontStruct yet)

    -- XQueryTextExtents omitted (no support for CharStruct yet)
    -- XQueryTextExtents16 omitted (no support for CharStruct yet)

    -- We marshall this across right away because it's usually one-off info
    type CharStruct =
            ( CInt            -- lbearing (origin to left edge of raster)
            , CInt            -- rbearing (origin to right edge of raster)
            , CInt            -- width    (advance to next char's origin)
            , CInt            -- ascent   (baseline to top edge of raster)
            , CInt            -- descent  (baseline to bottom edge of raster)
            -- attributes omitted
            )

    peekCharStruct :: Ptr CharStruct -> IO CharStruct
    peekCharStruct p = do
            lbearing <- (\hsc_ptr -> peekByteOff hsc_ptr 0) p
    {-# LINE 149 "Graphics/X11/Xlib/Font.hsc" #-}
            rbearing <- (\hsc_ptr -> peekByteOff hsc_ptr 2) p
    {-# LINE 150 "Graphics/X11/Xlib/Font.hsc" #-}
            width    <- (\hsc_ptr -> peekByteOff hsc_ptr 4) p
    {-# LINE 151 "Graphics/X11/Xlib/Font.hsc" #-}
            ascent   <- (\hsc_ptr -> peekByteOff hsc_ptr 6) p
    {-# LINE 152 "Graphics/X11/Xlib/Font.hsc" #-}
            descent  <- (\hsc_ptr -> peekByteOff hsc_ptr 8) p
    {-# LINE 153 "Graphics/X11/Xlib/Font.hsc" #-}
            return (fromIntegral (lbearing::CShort),
                    fromIntegral (rbearing::CShort),
                    fromIntegral (width::CShort),
                    fromIntegral (ascent::CShort),
                    fromIntegral (descent::CShort))

    -- No need to put this in the IO monad - this info is essentially constant

    -- | interface to the X11 library function @XTextExtents()@.
    textExtents :: FontStruct -> String -> (FontDirection, Int32, Int32, CharStruct)
    textExtents font_struct string = unsafePerformIO $
            withCStringLen string $ \ (c_string, nchars) ->
            alloca $ \ direction_return ->
            alloca $ \ font_ascent_return ->
            alloca $ \ font_descent_return ->
            allocaBytes (12) $ \ overall_return -> do
    {-# LINE 169 "Graphics/X11/Xlib/Font.hsc" #-}
            _ <- xTextExtents font_struct c_string (fromIntegral nchars) direction_return
                    font_ascent_return font_descent_return overall_return
            direction <- peek direction_return
            ascent <- peek font_ascent_return
            descent <- peek font_descent_return
            cs <- peekCharStruct overall_return
            return (direction, ascent, descent, cs)
    foreign import ccall unsafe "HsXlib.h XTextExtents"
            xTextExtents :: FontStruct -> CString -> CInt ->
                    Ptr FontDirection -> Ptr Int32 -> Ptr Int32 ->
                    Ptr CharStruct -> IO CInt

    -- No need to put ths in the IO monad - this info is essentially constant

    -- | interface to the X11 library function @XTextWidth()@.
    textWidth :: FontStruct -> String -> Int32
    textWidth font_struct string = unsafePerformIO $
            withCStringLen string $ \ (c_string, len) ->
            xTextWidth font_struct c_string (fromIntegral len)
    foreign import ccall unsafe "HsXlib.h XTextWidth"
            xTextWidth :: FontStruct -> CString -> CInt -> IO Int32

    -- XTextExtents16 omitted
    -- XTextWidth16 omitted

    -- XGetFontProperty omitted
    -- XFreeFontInfo omitted
    -- XFreeFontNames omitted

    -- XCreateFontSet omitted (no documentation available)
    -- XFreeFontSet omitted (no documentation available)
    -- XFontsOfFontSet omitted (no documentation available)
    -- XBaseFontNameListOfFontSet omitted (no documentation available)
    -- XLocaleOfFontSet omitted (no documentation available)
    -- XExtentsOfFontSet omitted (no documentation available)

    -- XContextDependentDrawing omitted
    -- XDirectionalDependentDrawing omitted
    -- XContextualDrawing omitted

    -- XmbTextEscapement omitted
    -- XwcTextEscapement omitted
    -- XmbTextExtents omitted
    -- XwcTextExtents omitted
    -- XmbTextPerCharExtents omitted
    -- XwcTextPerCharExtents omitted
    -- XmbDrawText omitted
    -- XwcDrawText omitted
    -- XmbDrawString omitted
    -- XwcDrawString omitted
    -- XmbDrawImageString omitted
    -- XwcDrawImageString omitted

    -- XOpenIM omitted
    -- XCloseIM omitted
    -- XGetIMValues omitted
    -- XSetIMValues omitted
    -- DisplayOfIM omitted
    -- XLocaleOfIM omitted

    -- XCreateIC omitted
    -- XDestroyIC omitted
    -- XSetICFocus omitted
    -- XUnsetICFocus omitted
    -- XwcResetIC omitted
    -- XmbResetIC omitted
    -- XSetICValues omitted
    -- XGetICValues omitted
    -- XIMOfIC omitted

    -- XRegisterIMInstantiateCallback omitted
    -- XUnregisterIMInstantiateCallback omitted

    -- XInternalConnectionNumbers omitted
    -- XProcessInternalConnection omitted
    -- XAddConnectionWatch omitted
    -- XRemoveConnectionWatch omitted

    -- XmbLookupString omitted
    -- XwcLookupString omitted

    ----------------------------------------------------------------
    -- End
    ----------------------------------------------------------------