summaryrefslogtreecommitdiff
path: root/wayland/Wayland/Server/Object.hs
diff options
context:
space:
mode:
Diffstat (limited to 'wayland/Wayland/Server/Object.hs')
-rw-r--r--wayland/Wayland/Server/Object.hs63
1 files changed, 42 insertions, 21 deletions
diff --git a/wayland/Wayland/Server/Object.hs b/wayland/Wayland/Server/Object.hs
index b56bbaf..b13e36f 100644
--- a/wayland/Wayland/Server/Object.hs
+++ b/wayland/Wayland/Server/Object.hs
@@ -41,6 +41,7 @@ import Data.Kind (Type)
import Data.Hashable (Hashable(..))
import Data.IORef (readIORef, newIORef, IORef, writeIORef)
import Data.Typeable (Proxy(..), TypeRep, typeRep, Typeable)
+import Data.ByteString (ByteString, useAsCStringLen, packCStringLen)
import Foreign
import Foreign.C (withCString, peekCString, CInt)
import Lens.Micro.Mtl (use, (%=), zoom)
@@ -113,28 +114,32 @@ class MessageClass e => EventClass e where
-- For libwayland, the arguments are stored into wl_arguments. It is considered a programmer error to write more
-- arguments than expected by an event or different argument types than the ones specified.
class Monad m => ArgumentMarshaller m where
- marshalInt :: Int -> m ()
- marshalUInt :: Word -> m ()
- marshalFixed :: Float -> m ()
- marshalString :: String -> m ()
- marshalObject :: Object o => o -> m ()
- marshalNewID :: Object o => NewObject o -> m ()
- marshalArray :: Storable a => [a] -> m ()
- marshalFD :: Fd -> m ()
+ marshalInt :: Int -> m ()
+ marshalUInt :: Word -> m ()
+ marshalFixed :: Float -> m ()
+ marshalString :: String -> m ()
+ marshalMaybeString :: Maybe String -> m ()
+ marshalObject :: Object o => o -> m ()
+ marshalMaybeObject :: Object o => Maybe o -> m ()
+ marshalNewID :: Object o => NewObject o -> m ()
+ marshalArray :: ByteString -> m ()
+ marshalFD :: Fd -> m ()
-- | A monad providing an environment for reading a fixed number of arguments of various types.
--
-- For libwayland, the arguments are read from wl_arguments. It is considered a programmer error to read more arguments
-- than expected by a request or different argument types than the ones specified.
class Monad m => ArgumentDemarshaller m where
- demarshalInt :: m Int
- demarshalUInt :: m Word
- demarshalFixed :: m Float
- demarshalString :: m String
- demarshalObject :: Object o => m o
- demarshalNewID :: Object o => m (NewObject o)
- demarshalArray :: Storable a => m [a]
- demarshalFD :: m Fd
+ demarshalInt :: m Int
+ demarshalUInt :: m Word
+ demarshalFixed :: m Float
+ demarshalString :: m String
+ demarshalMaybeString :: m (Maybe String)
+ demarshalObject :: Object o => m o
+ demarshalMaybeObject :: Object o => m (Maybe o)
+ demarshalNewID :: Object o => m (NewObject o)
+ demarshalArray :: m ByteString
+ demarshalFD :: m Fd
-- | An opaque handle to a Wayland object.
--
@@ -202,6 +207,9 @@ instance Show AnyObject where
instance Show (NewObject o) where
show o = "NewObject " ++ show (newClient o) ++ " " ++ show (newID o)
+instance Eq (NewObject o) where
+ a == b = newObject a == newObject b
+
-- | Create a handle to an object that has yet to be created.
createNewObject :: Client -> Word32 -> IO (NewObject o)
createNewObject client objID = do
@@ -366,19 +374,26 @@ instance ArgumentMarshaller (ArgumentWriter r) where
arg <- advanceIterator
str <- liftCont $ withCString v
liftIO $ wlArgumentPokeString arg str
+ marshalMaybeString (Just v) = marshalString v
+ marshalMaybeString Nothing = do
+ arg <- advanceIterator
+ liftIO $ wlArgumentPokeString arg nullPtr
marshalObject v = do
arg <- advanceIterator
obj <- liftIO $ unwrapResource v
liftIO $ wlArgumentPokeObject arg obj
+ marshalMaybeObject (Just v) = marshalObject v
+ marshalMaybeObject Nothing = do
+ arg <- advanceIterator
+ liftIO $ wlArgumentPokeObject arg (WLResource nullPtr)
marshalNewID v = do
arg <- advanceIterator
liftIO $ wlArgumentPokeNewID arg (newID v)
marshalArray v = do
arg <- advanceIterator
- let len = fromIntegral $ length v * sizeOf (head v)
- buf <- liftCont $ withArray v
- arr <- liftCont $ with $ WLArray { arrSize = len
- , arrAlloc = len
+ (buf, len) <- liftCont $ useAsCStringLen v
+ arr <- liftCont $ with $ WLArray { arrSize = fromIntegral len
+ , arrAlloc = fromIntegral len
, arrData = castPtr buf
}
liftIO $ wlArgumentPokeArray arg arr
@@ -390,9 +405,15 @@ instance ArgumentDemarshaller ArgumentReader where
demarshalString = do
ptr <- advanceIterator >>= liftIO . wlArgumentPeekString
liftIO $ peekCString ptr
+ demarshalMaybeString = do
+ ptr <- advanceIterator >>= liftIO . wlArgumentPeekString
+ if ptr == nullPtr then pure Nothing else Just <$> liftIO (peekCString ptr)
demarshalObject = do
ptr <- advanceIterator >>= liftIO . wlArgumentPeekObject
liftIO $ wrapResource ptr
+ demarshalMaybeObject = do
+ ptr <- advanceIterator >>= liftIO . wlArgumentPeekObject
+ if ptr == WLResource nullPtr then pure Nothing else Just <$> liftIO (wrapResource ptr)
demarshalNewID = do
objID <- advanceIterator >>= liftIO . wlArgumentPeekNewID
client <- ask
@@ -400,5 +421,5 @@ instance ArgumentDemarshaller ArgumentReader where
demarshalArray = do
ptr <- advanceIterator >>= liftIO . wlArgumentPeekArray
arr <- liftIO $ peek ptr
- liftIO $ peekArray (fromIntegral (arrSize arr)) (castPtr (arrData arr))
+ liftIO $ packCStringLen (castPtr (arrData arr), fromIntegral (arrSize arr))
demarshalFD = Fd . fromIntegral <$> (advanceIterator >>= liftIO . wlArgumentPeekFD)