diff options
author | Alexander Shabalin <shabalyn.a@gmail.com> | 2014-09-02 21:15:00 +0400 |
---|---|---|
committer | Alexander Shabalin <shabalyn.a@gmail.com> | 2014-09-03 23:55:38 +0400 |
commit | 1d8a1955dd719846e51596b573ee5a6e2bcbcf5a (patch) | |
tree | 6c839290278baf7078c515fda2c7665cd94f2d68 /src/XPMFile.hsc | |
parent | 557f5dbf2863f85c9e39c90d38a28d4870110afe (diff) | |
download | xmobar-1d8a1955dd719846e51596b573ee5a6e2bcbcf5a.tar.gz xmobar-1d8a1955dd719846e51596b573ee5a6e2bcbcf5a.tar.bz2 |
Add .xpm support for <icon> via libXpm.
* Adds a new flag with_xpm to enable compilation with xpm support
* Adds a module XPMFile only exporting readXPMFile which almost mirrors
Graphics.X11.Xlib.Misc.readBitmapFile
* During loadBitmap a file is first tried with readBitmapFile and if it
fails with readXPMFile
Diffstat (limited to 'src/XPMFile.hsc')
-rw-r--r-- | src/XPMFile.hsc | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/src/XPMFile.hsc b/src/XPMFile.hsc new file mode 100644 index 0000000..2284e4a --- /dev/null +++ b/src/XPMFile.hsc @@ -0,0 +1,44 @@ +{-# LANGUAGE FlexibleContexts, ForeignFunctionInterface #-} +module XPMFile(readXPMFile) where + +import Control.Monad.Except(MonadError(..)) +import Control.Monad.Trans(MonadIO(..)) +import Graphics.X11.Xlib(Dimension, Display(..), Drawable, Pixmap) +import Foreign.C.String(CString, withCString) +import Foreign.C.Types(CInt(..), CLong) +import Foreign.Ptr(Ptr) +import Foreign.Marshal.Alloc(alloca, allocaBytes) +import Foreign.Storable(peek, peekByteOff, pokeByteOff) + +#include <X11/xpm.h> + +foreign import ccall "XpmReadFileToPixmap" + xpmReadFileToPixmap :: Display -> Drawable -> CString -> Ptr Pixmap -> Ptr Pixmap -> Ptr () -> IO CInt + +readXPMFile + :: (MonadError String m, MonadIO m) + => Display + -> Drawable + -> String + -> m (Dimension, Dimension, Pixmap, Maybe Pixmap) +readXPMFile display d filename = + toError $ withCString filename $ \c_filename -> + alloca $ \pixmap_return -> + alloca $ \shapemask_return -> + allocaBytes (#size XpmAttributes) $ \attributes -> do + (#poke XpmAttributes, valuemask) attributes ((#const XpmReturnAllocPixels) :: CLong) + res <- xpmReadFileToPixmap display d c_filename pixmap_return shapemask_return attributes + case res of + 0 -> do + width <- (#peek XpmAttributes, width) attributes + height <- (#peek XpmAttributes, height) attributes + pixmap <- peek pixmap_return + shapemask <- peek shapemask_return + return $ Right (width, height, pixmap, if shapemask == 0 then Nothing else Just shapemask) + 1 -> return $ Left "readXPMFile: XpmColorError" + -1 -> return $ Left "readXPMFile: XpmOpenFailed" + -2 -> return $ Left "readXPMFile: XpmFileInvalid" + -3 -> return $ Left "readXPMFile: XpmNoMemory" + -4 -> return $ Left "readXPMFile: XpmColorFailed" + _ -> return $ Left "readXPMFile: Unknown error" + where toError m = either throwError return =<< liftIO m |