This repository has been archived on 2025-03-02. You can view files and clone it, but cannot push or open issues or pull requests.
phi/lib/Phi/X11/Util.hs

127 lines
5.1 KiB
Haskell
Raw Normal View History

2011-09-07 16:38:36 +02:00
module Phi.X11.Util ( getReply'
, changeProperty8
, changeProperty16
, changeProperty32
, getProperty8
, getProperty16
, getProperty32
, findVisualtype
2011-09-09 03:20:16 +02:00
, serializeClientMessage
2011-09-07 16:38:36 +02:00
) where
2011-09-09 03:20:16 +02:00
import Control.Exception (assert)
2011-09-07 16:38:36 +02:00
import Control.Monad
import Data.Int
import Data.List
import Data.Maybe
import Data.Word
2011-09-09 03:20:16 +02:00
import Foreign.C.Types
2011-09-07 16:38:36 +02:00
import Foreign.Marshal.Array
2011-09-09 03:20:16 +02:00
import Foreign.Marshal.Utils
2011-09-07 16:38:36 +02:00
import Foreign.Ptr
2011-09-09 03:20:16 +02:00
import Foreign.Storable
2011-09-07 16:38:36 +02:00
import Graphics.XHB
import Graphics.XHB.Gen.Xproto
import System.IO.Unsafe
2011-10-10 23:22:59 +02:00
getReply' :: String -> Receipt a -> IO a
2011-09-07 16:38:36 +02:00
getReply' m = getReply >=> return . fromRight
where
fromRight (Left _) = error m
fromRight (Right a) = a
castWord16to8 :: [Word16] -> [Word8]
castWord16to8 input = unsafePerformIO $
withArray input $ \ptr ->
peekArray (2 * length input) (castPtr ptr)
castWord32to8 :: [Word32] -> [Word8]
castWord32to8 input = unsafePerformIO $
withArray input $ \ptr ->
peekArray (4 * length input) (castPtr ptr)
castWord8to16 :: [Word8] -> [Word16]
castWord8to16 input = unsafePerformIO $
withArray input $ \ptr ->
peekArray (length input `div` 2) (castPtr ptr)
castWord8to32 :: [Word8] -> [Word32]
castWord8to32 input = unsafePerformIO $
withArray input $ \ptr ->
peekArray (length input `div` 4) (castPtr ptr)
2011-09-09 03:20:16 +02:00
castToCChar :: Storable s => s -> [CChar]
castToCChar input = unsafePerformIO $
with input $ \ptr ->
peekArray (sizeOf input) (castPtr ptr)
2011-09-07 16:38:36 +02:00
2011-10-10 23:22:59 +02:00
changeProperty8 :: ConnectionClass c => c -> PropMode -> WINDOW -> ATOM -> ATOM -> [Word8] -> IO ()
2011-09-07 16:38:36 +02:00
changeProperty8 conn mode win prop proptype propdata = changeProperty conn $ MkChangeProperty mode win prop proptype 8 (genericLength propdata) propdata
2011-10-10 23:22:59 +02:00
changeProperty16 :: ConnectionClass c => c -> PropMode -> WINDOW -> ATOM -> ATOM -> [Word16] -> IO ()
2011-09-07 16:38:36 +02:00
changeProperty16 conn mode win prop proptype propdata = changeProperty conn $ MkChangeProperty mode win prop proptype 16 (genericLength propdata) (castWord16to8 propdata)
2011-10-10 23:22:59 +02:00
changeProperty32 :: ConnectionClass c => c -> PropMode -> WINDOW -> ATOM -> ATOM -> [Word32] -> IO ()
2011-09-07 16:38:36 +02:00
changeProperty32 conn mode win prop proptype propdata = changeProperty conn $ MkChangeProperty mode win prop proptype 32 (genericLength propdata) (castWord32to8 propdata)
2011-10-10 23:22:59 +02:00
getProperty' :: ConnectionClass c => Word8 -> c -> WINDOW -> ATOM -> IO (Maybe [Word8])
2011-09-07 16:38:36 +02:00
getProperty' format conn win prop = do
reply <- getProperty conn (MkGetProperty False win prop (fromXid xidNone) 0 4) >>= getReply
case reply of
Left _ -> return Nothing
Right (MkGetPropertyReply {format_GetPropertyReply = format'}) | format' /= format -> return Nothing
Right (MkGetPropertyReply {bytes_after_GetPropertyReply = 0, value_GetPropertyReply = value}) -> return $ Just value
Right (MkGetPropertyReply {bytes_after_GetPropertyReply = bytes_after}) -> do
reply' <- getProperty conn (MkGetProperty False win prop (fromXid xidNone) 0 (4+bytes_after)) >>= getReply
case reply' of
Left _ -> return Nothing
Right (MkGetPropertyReply {format_GetPropertyReply = format'}) | format' /= format -> return Nothing
Right (MkGetPropertyReply {value_GetPropertyReply = value}) -> return $ Just value
2011-10-10 23:22:59 +02:00
getProperty8 :: ConnectionClass c => c -> WINDOW -> ATOM -> IO (Maybe [Word8])
2011-09-07 16:38:36 +02:00
getProperty8 = getProperty' 8
2011-10-10 23:22:59 +02:00
getProperty16 :: ConnectionClass c => c -> WINDOW -> ATOM -> IO (Maybe [Word16])
2011-09-07 16:38:36 +02:00
getProperty16 conn win prop = getProperty' 16 conn win prop >>= return . fmap castWord8to16
2011-10-10 23:22:59 +02:00
getProperty32 :: ConnectionClass c => c -> WINDOW -> ATOM -> IO (Maybe [Word32])
2011-09-07 16:38:36 +02:00
getProperty32 conn win prop = getProperty' 32 conn win prop >>= return . fmap castWord8to32
findVisualtype :: SCREEN -> VISUALID -> Maybe VISUALTYPE
2011-09-09 03:20:16 +02:00
findVisualtype screen id = listToMaybe . filter ((== id) . visual_id_VISUALTYPE) . join . map visuals_DEPTH . allowed_depths_SCREEN $ screen
instance Storable ClientMessageData where
sizeOf _ = 20
alignment _ = 1
peek _ = error "ClientMessageData: peek not implemented"
poke ptr (ClientData8 d) = assert (length d == 20) $ pokeArray (castPtr ptr) d
poke ptr (ClientData16 d) = assert (length d == 10) $ pokeArray (castPtr ptr) d
poke ptr (ClientData32 d) = assert (length d == 5) $ pokeArray (castPtr ptr) d
instance Storable ClientMessageEvent where
sizeOf _ = 32
alignment _ = 1
peek _ = error "ClientMessageEvent: peek not implemented"
poke ptr ev = do
poke' 0 (33 :: Word8) -- ClientMessage == 33 -- response_type
poke' 1 (format_ClientMessageEvent ev) -- format
poke' 2 (0 :: Word16) -- sequence
poke' 4 (fromXid . toXid . window_ClientMessageEvent $ ev :: Word32) -- window
poke' 8 (fromXid . toXid . type_ClientMessageEvent $ ev :: Word32) -- type
poke' 12 (data_ClientMessageEvent ev) -- data
where
poke' :: Storable s => Int -> s -> IO ()
poke' = poke . plusPtr ptr
serializeClientMessage :: ClientMessageEvent -> [CChar]
serializeClientMessage = castToCChar