diff --git a/CHANGES.md b/CHANGES.md index 346f2d7..1853998 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,11 @@ # Change Log / Release Notes +## _unreleased_ + + * `xftOpenFont` and `xftOpenFontXlfd` now throw exceptions if opening a + font fails. (They used to return a null pointer, usually leading to + crashes.) + ## 0.3.4 (2021-12-11) * Dropped support for GHC 7.10. diff --git a/Graphics/X11/Xft.hsc b/Graphics/X11/Xft.hsc index c86918e..54443f4 100644 --- a/Graphics/X11/Xft.hsc +++ b/Graphics/X11/Xft.hsc @@ -1,4 +1,5 @@ {-# LANGUAGE ForeignFunctionInterface #-} +{-# LANGUAGE FlexibleContexts #-} ----------------------------------------------------------------------------- -- Module : Graphics.X11.Xft @@ -58,6 +59,7 @@ import Codec.Binary.UTF8.String as UTF8 import Control.Arrow ((&&&)) import Control.Monad (void) import Data.Char (ord) +import Data.Coerce (coerce, Coercible) import Data.Function (on) import Data.List (foldl') import Data.List.NonEmpty (NonEmpty) @@ -68,6 +70,11 @@ import Foreign.C.Types #include +-- I wonder how many times this has been reinvented... +-- (upstream won't accept it because of the GHCisms, I suspect) +throwIfNullXft :: Coercible a (Ptr b) => String -> IO a -> IO a +throwIfNullXft fn op = coerce $ throwIfNull fn (coerce op) + ----------------------- -- Color Handling -- ----------------------- @@ -172,14 +179,15 @@ foreign import ccall "XftFontOpenName" xftFontOpen :: Display -> Screen -> String -> IO XftFont xftFontOpen dpy screen fontname = withCAString fontname $ - \cfontname -> cXftFontOpen dpy (fi (screenNumberOfScreen screen)) cfontname + \cfontname -> throwIfNullXft "xftFontOpen" $ cXftFontOpen dpy (fi (screenNumberOfScreen screen)) cfontname foreign import ccall "XftFontOpenXlfd" cXftFontOpenXlfd :: Display -> CInt -> CString -> IO XftFont xftFontOpenXlfd :: Display -> Screen -> String -> IO XftFont xftFontOpenXlfd dpy screen fontname = - withCAString fontname $ \cfontname -> cXftFontOpenXlfd dpy (fi (screenNumberOfScreen screen)) cfontname + withCAString fontname $ \cfontname -> throwIfNullXft "xftFontOpenXlfd" $ + cXftFontOpenXlfd dpy (fi (screenNumberOfScreen screen)) cfontname foreign import ccall "XftLockFace" xftLockFace :: XftFont -> IO () -- FIXME XftLockFace returns FT_face not void diff --git a/X11-xft.cabal b/X11-xft.cabal index 622ad88..abf68ec 100644 --- a/X11-xft.cabal +++ b/X11-xft.cabal @@ -1,6 +1,6 @@ cabal-version: 1.24 name: X11-xft -version: 0.3.4 +version: 0.3.5 license: BSD3 license-file: LICENSE author: Clemens Fruhwirth