ymonad-0.1.0.0: src/YMonad/Protocol/Wayland/Types.hs
module YMonad.Protocol.Wayland.Types (
MessageRole (..),
ArgType (..),
ArgSpec (..),
MessageSpec (..),
InterfaceSpec (..),
ProtocolSpec (..),
ArgValue (..),
WireMessage (..),
RawFrame (..),
mkInterfaceSpec,
mergeProtocolSpecs,
lookupInterface,
lookupRequest,
lookupEventByOpcode,
) where
import Data.Map.Strict qualified as M
data MessageRole
= MessageRequest
| MessageEvent
deriving stock (Eq, Ord, Show)
data ArgType
= ArgInt
| ArgUint
| ArgString
| ArgObject (Maybe Text)
| ArgNewId (Maybe Text)
deriving stock (Eq, Ord, Show)
data ArgSpec = ArgSpec
{ argSpecName :: Text
, argSpecType :: ArgType
, argSpecAllowNull :: Bool
}
deriving stock (Eq, Ord, Show)
data MessageSpec = MessageSpec
{ messageSpecName :: Text
, messageSpecOpcode :: Word16
, messageSpecRole :: MessageRole
, messageSpecArgs :: [ArgSpec]
}
deriving stock (Eq, Ord, Show)
data InterfaceSpec = InterfaceSpec
{ interfaceName :: Text
, interfaceVersion :: Word32
, interfaceRequestsByName :: Map Text MessageSpec
, interfaceRequestsByOpcode :: Map Word16 MessageSpec
, interfaceEventsByName :: Map Text MessageSpec
, interfaceEventsByOpcode :: Map Word16 MessageSpec
}
deriving stock (Eq, Ord, Show)
data ProtocolSpec = ProtocolSpec
{ protocolName :: Text
, protocolInterfaces :: Map Text InterfaceSpec
}
deriving stock (Eq, Ord, Show)
data ArgValue
= ArgIntValue Int32
| ArgUintValue Word32
| ArgStringValue (Maybe Text)
| ArgObjectValue (Maybe Word32)
| ArgNewIdValue Word32
deriving stock (Eq, Ord, Show)
data WireMessage = WireMessage
{ wireObjectId :: Word32
, wireInterface :: Text
, wireMessageName :: Text
, wireOpcode :: Word16
, wireArgs :: [ArgValue]
}
deriving stock (Eq, Ord, Show)
data RawFrame = RawFrame
{ rawObjectId :: Word32
, rawOpcode :: Word16
, rawPayload :: !ByteString
}
deriving stock (Eq, Ord, Show)
mkInterfaceSpec :: Text -> Word32 -> [MessageSpec] -> [MessageSpec] -> InterfaceSpec
mkInterfaceSpec name version requests events =
InterfaceSpec
{ interfaceName = name
, interfaceVersion = version
, interfaceRequestsByName = M.fromList [(messageSpecName msg, msg) | msg <- requests]
, interfaceRequestsByOpcode = M.fromList [(messageSpecOpcode msg, msg) | msg <- requests]
, interfaceEventsByName = M.fromList [(messageSpecName msg, msg) | msg <- events]
, interfaceEventsByOpcode = M.fromList [(messageSpecOpcode msg, msg) | msg <- events]
}
mergeProtocolSpecs :: ProtocolSpec -> ProtocolSpec -> ProtocolSpec
mergeProtocolSpecs a b =
ProtocolSpec
{ protocolName = protocolName a
, protocolInterfaces = M.union (protocolInterfaces a) (protocolInterfaces b)
}
lookupInterface :: ProtocolSpec -> Text -> Maybe InterfaceSpec
lookupInterface spec name = M.lookup name (protocolInterfaces spec)
lookupRequest :: ProtocolSpec -> Text -> Text -> Maybe MessageSpec
lookupRequest spec ifaceName msgName = do
iface <- lookupInterface spec ifaceName
M.lookup msgName (interfaceRequestsByName iface)
lookupEventByOpcode :: ProtocolSpec -> Text -> Word16 -> Maybe MessageSpec
lookupEventByOpcode spec ifaceName opcode = do
iface <- lookupInterface spec ifaceName
M.lookup opcode (interfaceEventsByOpcode iface)