module System.Terminal.MonadInput where

import           Control.Applicative ((<|>))
import           Control.Monad.IO.Class
import           Control.Monad.STM
import           Data.Bits
import           Data.List

import           System.Terminal.MonadScreen

-- | This monad describes an environment that maintains a stream of `Event`s
--   and offers out-of-band signaling for interrupts.
--
--  * An interrupt shall occur if the user either presses CTRL+C
--    or any other mechanism the environment designates for that purpose.
--  * Implementations shall maintain an interrupt flag that is set
--    when an interrupt occurs. Computations in this monad shall check and
--    reset this flag regularly. If the execution environment finds this
--    flag still set when trying to signal another interrupt, it shall
--    throw `Control.Exception.AsyncException.UserInterrupt` to the
--    seemingly unresponsive computation.
class (MonadIO m) => MonadInput m where
    -- | Wait for the next interrupt or next event transformed by a given mapper.
    --
    -- * The first mapper parameter is a transaction that succeeds as
    --   soon as an interrupt occurs. Executing this transaction
    --   resets the interrupt flag. When a second interrupt occurs before
    --   the interrupt flag has been reset, the current thread shall
    --   receive an `Control.Exception.AsyncException.UserInterrupt`.
    -- * The second mapper parameter is a transaction that succeeds as
    --   as soon as the next event arrives and removes that event from the
    --   stream of events. It shall be executed at most once within a single
    --   transaction or the transaction would block until the requested number
    --   of events is available.
    -- * The mapper may also be used in order to additionally wait on external
    --   events (like an `Control.Monad.Async.Async` to complete).
    awaitWith :: (STM Interrupt -> STM Event -> STM a) -> m a

-- | Wait for the next event.
--
-- * Returns as soon as an interrupt or a regular event occurs.
-- * This operation resets the interrupt flag, signaling responsiveness to
--   the execution environment.
awaitEvent :: MonadInput m => m (Either Interrupt Event)
awaitEvent :: forall (m :: * -> *). MonadInput m => m (Either Interrupt Event)
awaitEvent = (STM Interrupt -> STM Event -> STM (Either Interrupt Event))
-> m (Either Interrupt Event)
forall a. (STM Interrupt -> STM Event -> STM a) -> m a
forall (m :: * -> *) a.
MonadInput m =>
(STM Interrupt -> STM Event -> STM a) -> m a
awaitWith((STM Interrupt -> STM Event -> STM (Either Interrupt Event))
 -> m (Either Interrupt Event))
-> (STM Interrupt -> STM Event -> STM (Either Interrupt Event))
-> m (Either Interrupt Event)
forall a b. (a -> b) -> a -> b
$ \STM Interrupt
intr STM Event
ev ->
    (Interrupt -> Either Interrupt Event
forall a b. a -> Either a b
Left (Interrupt -> Either Interrupt Event)
-> STM Interrupt -> STM (Either Interrupt Event)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> STM Interrupt
intr) STM (Either Interrupt Event)
-> STM (Either Interrupt Event) -> STM (Either Interrupt Event)
forall a. STM a -> STM a -> STM a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Event -> Either Interrupt Event
forall a b. b -> Either a b
Right (Event -> Either Interrupt Event)
-> STM Event -> STM (Either Interrupt Event)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> STM Event
ev)

-- | Check whether an interrupt is pending.
--
-- * This operation resets the interrupt flag, signaling responsiveness
--   to the execution environment.
checkInterrupt :: MonadInput m => m Bool
checkInterrupt :: forall (m :: * -> *). MonadInput m => m Bool
checkInterrupt = (STM Interrupt -> STM Event -> STM Bool) -> m Bool
forall a. (STM Interrupt -> STM Event -> STM a) -> m a
forall (m :: * -> *) a.
MonadInput m =>
(STM Interrupt -> STM Event -> STM a) -> m a
awaitWith ((STM Interrupt -> STM Event -> STM Bool) -> m Bool)
-> (STM Interrupt -> STM Event -> STM Bool) -> m Bool
forall a b. (a -> b) -> a -> b
$ \STM Interrupt
intr STM Event
_ ->
    (STM Interrupt
intr STM Interrupt -> STM Bool -> STM Bool
forall a b. STM a -> STM b -> STM b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Bool -> STM Bool
forall a. a -> STM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True) STM Bool -> STM Bool -> STM Bool
forall a. STM a -> STM a -> STM a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Bool -> STM Bool
forall a. a -> STM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
False

-- | Events emitted by the terminal.
--
-- * Event decoding might be ambique. In case of ambiqueness all
--   possible meaning shall be emitted. The user is advised to only
--   match on events expected in a certain context and ignore all
--   others.
-- * Key events are highly ambique: I.e. when the user presses @space@
--   it might either be meant as a regular text element (like @a@,@b@,@c@)
--   or the focus is on the key itself (like in "Press space to continue...").
-- * The story is even more complicated: Depending on terminal type and
--   @termios@ settings, certain control codes have special meaning or not
--   (@Ctrl+C@ sometimes means interrupt, but not if the environment supports
--   delivering it as a signal). Don't wait for @Ctrl+C@ when you mean `Interrupt`!
--   Example: The tab key will likely emit @KeyEvent (CharKey 'I') ctrlKey@ and
--   @KeyEvent TabKey mempty@ in most settings.
data Event
    = KeyEvent Key Modifiers
    | MouseEvent MouseEvent
    | WindowEvent WindowEvent
    | DeviceEvent DeviceEvent
    | OtherEvent String
    deriving (Event -> Event -> Bool
(Event -> Event -> Bool) -> (Event -> Event -> Bool) -> Eq Event
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Event -> Event -> Bool
== :: Event -> Event -> Bool
$c/= :: Event -> Event -> Bool
/= :: Event -> Event -> Bool
Eq,Eq Event
Eq Event =>
(Event -> Event -> Ordering)
-> (Event -> Event -> Bool)
-> (Event -> Event -> Bool)
-> (Event -> Event -> Bool)
-> (Event -> Event -> Bool)
-> (Event -> Event -> Event)
-> (Event -> Event -> Event)
-> Ord Event
Event -> Event -> Bool
Event -> Event -> Ordering
Event -> Event -> Event
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Event -> Event -> Ordering
compare :: Event -> Event -> Ordering
$c< :: Event -> Event -> Bool
< :: Event -> Event -> Bool
$c<= :: Event -> Event -> Bool
<= :: Event -> Event -> Bool
$c> :: Event -> Event -> Bool
> :: Event -> Event -> Bool
$c>= :: Event -> Event -> Bool
>= :: Event -> Event -> Bool
$cmax :: Event -> Event -> Event
max :: Event -> Event -> Event
$cmin :: Event -> Event -> Event
min :: Event -> Event -> Event
Ord,Int -> Event -> ShowS
[Event] -> ShowS
Event -> String
(Int -> Event -> ShowS)
-> (Event -> String) -> ([Event] -> ShowS) -> Show Event
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Event -> ShowS
showsPrec :: Int -> Event -> ShowS
$cshow :: Event -> String
show :: Event -> String
$cshowList :: [Event] -> ShowS
showList :: [Event] -> ShowS
Show)

-- | Events triggered by key press.
data Key
    = CharKey Char
    | TabKey
    | SpaceKey
    | BackspaceKey
    | EnterKey
    | InsertKey
    | DeleteKey
    | HomeKey
    | BeginKey
    | EndKey
    | PageUpKey
    | PageDownKey
    | EscapeKey
    | PrintKey
    | PauseKey
    | ArrowKey Direction
    | FunctionKey Int
    deriving (Key -> Key -> Bool
(Key -> Key -> Bool) -> (Key -> Key -> Bool) -> Eq Key
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Key -> Key -> Bool
== :: Key -> Key -> Bool
$c/= :: Key -> Key -> Bool
/= :: Key -> Key -> Bool
Eq,Eq Key
Eq Key =>
(Key -> Key -> Ordering)
-> (Key -> Key -> Bool)
-> (Key -> Key -> Bool)
-> (Key -> Key -> Bool)
-> (Key -> Key -> Bool)
-> (Key -> Key -> Key)
-> (Key -> Key -> Key)
-> Ord Key
Key -> Key -> Bool
Key -> Key -> Ordering
Key -> Key -> Key
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Key -> Key -> Ordering
compare :: Key -> Key -> Ordering
$c< :: Key -> Key -> Bool
< :: Key -> Key -> Bool
$c<= :: Key -> Key -> Bool
<= :: Key -> Key -> Bool
$c> :: Key -> Key -> Bool
> :: Key -> Key -> Bool
$c>= :: Key -> Key -> Bool
>= :: Key -> Key -> Bool
$cmax :: Key -> Key -> Key
max :: Key -> Key -> Key
$cmin :: Key -> Key -> Key
min :: Key -> Key -> Key
Ord,Int -> Key -> ShowS
[Key] -> ShowS
Key -> String
(Int -> Key -> ShowS)
-> (Key -> String) -> ([Key] -> ShowS) -> Show Key
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Key -> ShowS
showsPrec :: Int -> Key -> ShowS
$cshow :: Key -> String
show :: Key -> String
$cshowList :: [Key] -> ShowS
showList :: [Key] -> ShowS
Show)

-- | Modifier keys.
newtype Modifiers = Modifiers Int
    deriving (Modifiers -> Modifiers -> Bool
(Modifiers -> Modifiers -> Bool)
-> (Modifiers -> Modifiers -> Bool) -> Eq Modifiers
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Modifiers -> Modifiers -> Bool
== :: Modifiers -> Modifiers -> Bool
$c/= :: Modifiers -> Modifiers -> Bool
/= :: Modifiers -> Modifiers -> Bool
Eq, Eq Modifiers
Eq Modifiers =>
(Modifiers -> Modifiers -> Ordering)
-> (Modifiers -> Modifiers -> Bool)
-> (Modifiers -> Modifiers -> Bool)
-> (Modifiers -> Modifiers -> Bool)
-> (Modifiers -> Modifiers -> Bool)
-> (Modifiers -> Modifiers -> Modifiers)
-> (Modifiers -> Modifiers -> Modifiers)
-> Ord Modifiers
Modifiers -> Modifiers -> Bool
Modifiers -> Modifiers -> Ordering
Modifiers -> Modifiers -> Modifiers
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Modifiers -> Modifiers -> Ordering
compare :: Modifiers -> Modifiers -> Ordering
$c< :: Modifiers -> Modifiers -> Bool
< :: Modifiers -> Modifiers -> Bool
$c<= :: Modifiers -> Modifiers -> Bool
<= :: Modifiers -> Modifiers -> Bool
$c> :: Modifiers -> Modifiers -> Bool
> :: Modifiers -> Modifiers -> Bool
$c>= :: Modifiers -> Modifiers -> Bool
>= :: Modifiers -> Modifiers -> Bool
$cmax :: Modifiers -> Modifiers -> Modifiers
max :: Modifiers -> Modifiers -> Modifiers
$cmin :: Modifiers -> Modifiers -> Modifiers
min :: Modifiers -> Modifiers -> Modifiers
Ord, Eq Modifiers
Modifiers
Eq Modifiers =>
(Modifiers -> Modifiers -> Modifiers)
-> (Modifiers -> Modifiers -> Modifiers)
-> (Modifiers -> Modifiers -> Modifiers)
-> (Modifiers -> Modifiers)
-> (Modifiers -> Int -> Modifiers)
-> (Modifiers -> Int -> Modifiers)
-> Modifiers
-> (Int -> Modifiers)
-> (Modifiers -> Int -> Modifiers)
-> (Modifiers -> Int -> Modifiers)
-> (Modifiers -> Int -> Modifiers)
-> (Modifiers -> Int -> Bool)
-> (Modifiers -> Maybe Int)
-> (Modifiers -> Int)
-> (Modifiers -> Bool)
-> (Modifiers -> Int -> Modifiers)
-> (Modifiers -> Int -> Modifiers)
-> (Modifiers -> Int -> Modifiers)
-> (Modifiers -> Int -> Modifiers)
-> (Modifiers -> Int -> Modifiers)
-> (Modifiers -> Int -> Modifiers)
-> (Modifiers -> Int)
-> Bits Modifiers
Int -> Modifiers
Modifiers -> Bool
Modifiers -> Int
Modifiers -> Maybe Int
Modifiers -> Modifiers
Modifiers -> Int -> Bool
Modifiers -> Int -> Modifiers
Modifiers -> Modifiers -> Modifiers
forall a.
Eq a =>
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> a
-> (Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> Bool)
-> (a -> Maybe Int)
-> (a -> Int)
-> (a -> Bool)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int -> a)
-> (a -> Int)
-> Bits a
$c.&. :: Modifiers -> Modifiers -> Modifiers
.&. :: Modifiers -> Modifiers -> Modifiers
$c.|. :: Modifiers -> Modifiers -> Modifiers
.|. :: Modifiers -> Modifiers -> Modifiers
$cxor :: Modifiers -> Modifiers -> Modifiers
xor :: Modifiers -> Modifiers -> Modifiers
$ccomplement :: Modifiers -> Modifiers
complement :: Modifiers -> Modifiers
$cshift :: Modifiers -> Int -> Modifiers
shift :: Modifiers -> Int -> Modifiers
$crotate :: Modifiers -> Int -> Modifiers
rotate :: Modifiers -> Int -> Modifiers
$czeroBits :: Modifiers
zeroBits :: Modifiers
$cbit :: Int -> Modifiers
bit :: Int -> Modifiers
$csetBit :: Modifiers -> Int -> Modifiers
setBit :: Modifiers -> Int -> Modifiers
$cclearBit :: Modifiers -> Int -> Modifiers
clearBit :: Modifiers -> Int -> Modifiers
$ccomplementBit :: Modifiers -> Int -> Modifiers
complementBit :: Modifiers -> Int -> Modifiers
$ctestBit :: Modifiers -> Int -> Bool
testBit :: Modifiers -> Int -> Bool
$cbitSizeMaybe :: Modifiers -> Maybe Int
bitSizeMaybe :: Modifiers -> Maybe Int
$cbitSize :: Modifiers -> Int
bitSize :: Modifiers -> Int
$cisSigned :: Modifiers -> Bool
isSigned :: Modifiers -> Bool
$cshiftL :: Modifiers -> Int -> Modifiers
shiftL :: Modifiers -> Int -> Modifiers
$cunsafeShiftL :: Modifiers -> Int -> Modifiers
unsafeShiftL :: Modifiers -> Int -> Modifiers
$cshiftR :: Modifiers -> Int -> Modifiers
shiftR :: Modifiers -> Int -> Modifiers
$cunsafeShiftR :: Modifiers -> Int -> Modifiers
unsafeShiftR :: Modifiers -> Int -> Modifiers
$crotateL :: Modifiers -> Int -> Modifiers
rotateL :: Modifiers -> Int -> Modifiers
$crotateR :: Modifiers -> Int -> Modifiers
rotateR :: Modifiers -> Int -> Modifiers
$cpopCount :: Modifiers -> Int
popCount :: Modifiers -> Int
Bits)

instance Semigroup Modifiers where
    Modifiers Int
a <> :: Modifiers -> Modifiers -> Modifiers
<> Modifiers Int
b = Int -> Modifiers
Modifiers (Int
a Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Int
b)

instance Monoid Modifiers where
    mempty :: Modifiers
mempty = Int -> Modifiers
Modifiers Int
0

instance Show Modifiers where
    show :: Modifiers -> String
show (Modifiers Int
0) = String
"mempty"
    show (Modifiers Int
1) = String
"shiftKey"
    show (Modifiers Int
2) = String
"ctrlKey"
    show (Modifiers Int
4) = String
"altKey"
    show (Modifiers Int
8) = String
"metaKey"
    show Modifiers
i = String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
" <> " [String]
ls String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
        where
        ls :: [String]
ls = ([String] -> Modifiers -> [String])
-> [String] -> [Modifiers] -> [String]
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (\[String]
acc Modifiers
x-> if Modifiers
x Modifiers -> Modifiers -> Modifiers
forall a. Bits a => a -> a -> a
.&. Modifiers
i Modifiers -> Modifiers -> Bool
forall a. Eq a => a -> a -> Bool
/= Modifiers
forall a. Monoid a => a
mempty then Modifiers -> String
forall a. Show a => a -> String
show Modifiers
xString -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
acc else [String]
acc) []
                    [Modifiers
metaKey, Modifiers
altKey, Modifiers
ctrlKey, Modifiers
shiftKey]

shiftKey, ctrlKey, altKey, metaKey :: Modifiers
shiftKey :: Modifiers
shiftKey = Int -> Modifiers
Modifiers Int
1
ctrlKey :: Modifiers
ctrlKey  = Int -> Modifiers
Modifiers Int
2
altKey :: Modifiers
altKey   = Int -> Modifiers
Modifiers Int
4
metaKey :: Modifiers
metaKey  = Int -> Modifiers
Modifiers Int
8

-- | Events triggered by mouse action.
--
-- * Mouse event reporting must be activated before (TODO).
data MouseEvent
    = MouseMoved          Position
    | MouseButtonPressed  Position MouseButton
    | MouseButtonReleased Position MouseButton
    | MouseButtonClicked  Position MouseButton
    | MouseWheeled        Position Direction
    deriving (MouseEvent -> MouseEvent -> Bool
(MouseEvent -> MouseEvent -> Bool)
-> (MouseEvent -> MouseEvent -> Bool) -> Eq MouseEvent
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MouseEvent -> MouseEvent -> Bool
== :: MouseEvent -> MouseEvent -> Bool
$c/= :: MouseEvent -> MouseEvent -> Bool
/= :: MouseEvent -> MouseEvent -> Bool
Eq,Eq MouseEvent
Eq MouseEvent =>
(MouseEvent -> MouseEvent -> Ordering)
-> (MouseEvent -> MouseEvent -> Bool)
-> (MouseEvent -> MouseEvent -> Bool)
-> (MouseEvent -> MouseEvent -> Bool)
-> (MouseEvent -> MouseEvent -> Bool)
-> (MouseEvent -> MouseEvent -> MouseEvent)
-> (MouseEvent -> MouseEvent -> MouseEvent)
-> Ord MouseEvent
MouseEvent -> MouseEvent -> Bool
MouseEvent -> MouseEvent -> Ordering
MouseEvent -> MouseEvent -> MouseEvent
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: MouseEvent -> MouseEvent -> Ordering
compare :: MouseEvent -> MouseEvent -> Ordering
$c< :: MouseEvent -> MouseEvent -> Bool
< :: MouseEvent -> MouseEvent -> Bool
$c<= :: MouseEvent -> MouseEvent -> Bool
<= :: MouseEvent -> MouseEvent -> Bool
$c> :: MouseEvent -> MouseEvent -> Bool
> :: MouseEvent -> MouseEvent -> Bool
$c>= :: MouseEvent -> MouseEvent -> Bool
>= :: MouseEvent -> MouseEvent -> Bool
$cmax :: MouseEvent -> MouseEvent -> MouseEvent
max :: MouseEvent -> MouseEvent -> MouseEvent
$cmin :: MouseEvent -> MouseEvent -> MouseEvent
min :: MouseEvent -> MouseEvent -> MouseEvent
Ord,Int -> MouseEvent -> ShowS
[MouseEvent] -> ShowS
MouseEvent -> String
(Int -> MouseEvent -> ShowS)
-> (MouseEvent -> String)
-> ([MouseEvent] -> ShowS)
-> Show MouseEvent
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MouseEvent -> ShowS
showsPrec :: Int -> MouseEvent -> ShowS
$cshow :: MouseEvent -> String
show :: MouseEvent -> String
$cshowList :: [MouseEvent] -> ShowS
showList :: [MouseEvent] -> ShowS
Show)

data MouseButton
    = LeftMouseButton
    | RightMouseButton
    | OtherMouseButton
    deriving (MouseButton -> MouseButton -> Bool
(MouseButton -> MouseButton -> Bool)
-> (MouseButton -> MouseButton -> Bool) -> Eq MouseButton
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MouseButton -> MouseButton -> Bool
== :: MouseButton -> MouseButton -> Bool
$c/= :: MouseButton -> MouseButton -> Bool
/= :: MouseButton -> MouseButton -> Bool
Eq,Eq MouseButton
Eq MouseButton =>
(MouseButton -> MouseButton -> Ordering)
-> (MouseButton -> MouseButton -> Bool)
-> (MouseButton -> MouseButton -> Bool)
-> (MouseButton -> MouseButton -> Bool)
-> (MouseButton -> MouseButton -> Bool)
-> (MouseButton -> MouseButton -> MouseButton)
-> (MouseButton -> MouseButton -> MouseButton)
-> Ord MouseButton
MouseButton -> MouseButton -> Bool
MouseButton -> MouseButton -> Ordering
MouseButton -> MouseButton -> MouseButton
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: MouseButton -> MouseButton -> Ordering
compare :: MouseButton -> MouseButton -> Ordering
$c< :: MouseButton -> MouseButton -> Bool
< :: MouseButton -> MouseButton -> Bool
$c<= :: MouseButton -> MouseButton -> Bool
<= :: MouseButton -> MouseButton -> Bool
$c> :: MouseButton -> MouseButton -> Bool
> :: MouseButton -> MouseButton -> Bool
$c>= :: MouseButton -> MouseButton -> Bool
>= :: MouseButton -> MouseButton -> Bool
$cmax :: MouseButton -> MouseButton -> MouseButton
max :: MouseButton -> MouseButton -> MouseButton
$cmin :: MouseButton -> MouseButton -> MouseButton
min :: MouseButton -> MouseButton -> MouseButton
Ord,Int -> MouseButton -> ShowS
[MouseButton] -> ShowS
MouseButton -> String
(Int -> MouseButton -> ShowS)
-> (MouseButton -> String)
-> ([MouseButton] -> ShowS)
-> Show MouseButton
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MouseButton -> ShowS
showsPrec :: Int -> MouseButton -> ShowS
$cshow :: MouseButton -> String
show :: MouseButton -> String
$cshowList :: [MouseButton] -> ShowS
showList :: [MouseButton] -> ShowS
Show)

data Direction
    = Upwards
    | Downwards
    | Leftwards
    | Rightwards
    deriving (Direction -> Direction -> Bool
(Direction -> Direction -> Bool)
-> (Direction -> Direction -> Bool) -> Eq Direction
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Direction -> Direction -> Bool
== :: Direction -> Direction -> Bool
$c/= :: Direction -> Direction -> Bool
/= :: Direction -> Direction -> Bool
Eq,Eq Direction
Eq Direction =>
(Direction -> Direction -> Ordering)
-> (Direction -> Direction -> Bool)
-> (Direction -> Direction -> Bool)
-> (Direction -> Direction -> Bool)
-> (Direction -> Direction -> Bool)
-> (Direction -> Direction -> Direction)
-> (Direction -> Direction -> Direction)
-> Ord Direction
Direction -> Direction -> Bool
Direction -> Direction -> Ordering
Direction -> Direction -> Direction
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Direction -> Direction -> Ordering
compare :: Direction -> Direction -> Ordering
$c< :: Direction -> Direction -> Bool
< :: Direction -> Direction -> Bool
$c<= :: Direction -> Direction -> Bool
<= :: Direction -> Direction -> Bool
$c> :: Direction -> Direction -> Bool
> :: Direction -> Direction -> Bool
$c>= :: Direction -> Direction -> Bool
>= :: Direction -> Direction -> Bool
$cmax :: Direction -> Direction -> Direction
max :: Direction -> Direction -> Direction
$cmin :: Direction -> Direction -> Direction
min :: Direction -> Direction -> Direction
Ord,Int -> Direction -> ShowS
[Direction] -> ShowS
Direction -> String
(Int -> Direction -> ShowS)
-> (Direction -> String)
-> ([Direction] -> ShowS)
-> Show Direction
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Direction -> ShowS
showsPrec :: Int -> Direction -> ShowS
$cshow :: Direction -> String
show :: Direction -> String
$cshowList :: [Direction] -> ShowS
showList :: [Direction] -> ShowS
Show)

data WindowEvent
    = WindowLostFocus
    | WindowGainedFocus
    | WindowSizeChanged
    deriving (WindowEvent -> WindowEvent -> Bool
(WindowEvent -> WindowEvent -> Bool)
-> (WindowEvent -> WindowEvent -> Bool) -> Eq WindowEvent
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: WindowEvent -> WindowEvent -> Bool
== :: WindowEvent -> WindowEvent -> Bool
$c/= :: WindowEvent -> WindowEvent -> Bool
/= :: WindowEvent -> WindowEvent -> Bool
Eq, Eq WindowEvent
Eq WindowEvent =>
(WindowEvent -> WindowEvent -> Ordering)
-> (WindowEvent -> WindowEvent -> Bool)
-> (WindowEvent -> WindowEvent -> Bool)
-> (WindowEvent -> WindowEvent -> Bool)
-> (WindowEvent -> WindowEvent -> Bool)
-> (WindowEvent -> WindowEvent -> WindowEvent)
-> (WindowEvent -> WindowEvent -> WindowEvent)
-> Ord WindowEvent
WindowEvent -> WindowEvent -> Bool
WindowEvent -> WindowEvent -> Ordering
WindowEvent -> WindowEvent -> WindowEvent
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: WindowEvent -> WindowEvent -> Ordering
compare :: WindowEvent -> WindowEvent -> Ordering
$c< :: WindowEvent -> WindowEvent -> Bool
< :: WindowEvent -> WindowEvent -> Bool
$c<= :: WindowEvent -> WindowEvent -> Bool
<= :: WindowEvent -> WindowEvent -> Bool
$c> :: WindowEvent -> WindowEvent -> Bool
> :: WindowEvent -> WindowEvent -> Bool
$c>= :: WindowEvent -> WindowEvent -> Bool
>= :: WindowEvent -> WindowEvent -> Bool
$cmax :: WindowEvent -> WindowEvent -> WindowEvent
max :: WindowEvent -> WindowEvent -> WindowEvent
$cmin :: WindowEvent -> WindowEvent -> WindowEvent
min :: WindowEvent -> WindowEvent -> WindowEvent
Ord, Int -> WindowEvent -> ShowS
[WindowEvent] -> ShowS
WindowEvent -> String
(Int -> WindowEvent -> ShowS)
-> (WindowEvent -> String)
-> ([WindowEvent] -> ShowS)
-> Show WindowEvent
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> WindowEvent -> ShowS
showsPrec :: Int -> WindowEvent -> ShowS
$cshow :: WindowEvent -> String
show :: WindowEvent -> String
$cshowList :: [WindowEvent] -> ShowS
showList :: [WindowEvent] -> ShowS
Show)

data DeviceEvent
    = DeviceAttributesReport String
    | CursorPositionReport Position
    deriving (DeviceEvent -> DeviceEvent -> Bool
(DeviceEvent -> DeviceEvent -> Bool)
-> (DeviceEvent -> DeviceEvent -> Bool) -> Eq DeviceEvent
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DeviceEvent -> DeviceEvent -> Bool
== :: DeviceEvent -> DeviceEvent -> Bool
$c/= :: DeviceEvent -> DeviceEvent -> Bool
/= :: DeviceEvent -> DeviceEvent -> Bool
Eq, Eq DeviceEvent
Eq DeviceEvent =>
(DeviceEvent -> DeviceEvent -> Ordering)
-> (DeviceEvent -> DeviceEvent -> Bool)
-> (DeviceEvent -> DeviceEvent -> Bool)
-> (DeviceEvent -> DeviceEvent -> Bool)
-> (DeviceEvent -> DeviceEvent -> Bool)
-> (DeviceEvent -> DeviceEvent -> DeviceEvent)
-> (DeviceEvent -> DeviceEvent -> DeviceEvent)
-> Ord DeviceEvent
DeviceEvent -> DeviceEvent -> Bool
DeviceEvent -> DeviceEvent -> Ordering
DeviceEvent -> DeviceEvent -> DeviceEvent
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: DeviceEvent -> DeviceEvent -> Ordering
compare :: DeviceEvent -> DeviceEvent -> Ordering
$c< :: DeviceEvent -> DeviceEvent -> Bool
< :: DeviceEvent -> DeviceEvent -> Bool
$c<= :: DeviceEvent -> DeviceEvent -> Bool
<= :: DeviceEvent -> DeviceEvent -> Bool
$c> :: DeviceEvent -> DeviceEvent -> Bool
> :: DeviceEvent -> DeviceEvent -> Bool
$c>= :: DeviceEvent -> DeviceEvent -> Bool
>= :: DeviceEvent -> DeviceEvent -> Bool
$cmax :: DeviceEvent -> DeviceEvent -> DeviceEvent
max :: DeviceEvent -> DeviceEvent -> DeviceEvent
$cmin :: DeviceEvent -> DeviceEvent -> DeviceEvent
min :: DeviceEvent -> DeviceEvent -> DeviceEvent
Ord, Int -> DeviceEvent -> ShowS
[DeviceEvent] -> ShowS
DeviceEvent -> String
(Int -> DeviceEvent -> ShowS)
-> (DeviceEvent -> String)
-> ([DeviceEvent] -> ShowS)
-> Show DeviceEvent
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DeviceEvent -> ShowS
showsPrec :: Int -> DeviceEvent -> ShowS
$cshow :: DeviceEvent -> String
show :: DeviceEvent -> String
$cshowList :: [DeviceEvent] -> ShowS
showList :: [DeviceEvent] -> ShowS
Show)

-- | Interrupt is a special type of event that needs
--   to be treated with priority. It is therefor not
--   included in the regular event stream.
data Interrupt
    = Interrupt
    deriving (Interrupt -> Interrupt -> Bool
(Interrupt -> Interrupt -> Bool)
-> (Interrupt -> Interrupt -> Bool) -> Eq Interrupt
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Interrupt -> Interrupt -> Bool
== :: Interrupt -> Interrupt -> Bool
$c/= :: Interrupt -> Interrupt -> Bool
/= :: Interrupt -> Interrupt -> Bool
Eq, Eq Interrupt
Eq Interrupt =>
(Interrupt -> Interrupt -> Ordering)
-> (Interrupt -> Interrupt -> Bool)
-> (Interrupt -> Interrupt -> Bool)
-> (Interrupt -> Interrupt -> Bool)
-> (Interrupt -> Interrupt -> Bool)
-> (Interrupt -> Interrupt -> Interrupt)
-> (Interrupt -> Interrupt -> Interrupt)
-> Ord Interrupt
Interrupt -> Interrupt -> Bool
Interrupt -> Interrupt -> Ordering
Interrupt -> Interrupt -> Interrupt
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Interrupt -> Interrupt -> Ordering
compare :: Interrupt -> Interrupt -> Ordering
$c< :: Interrupt -> Interrupt -> Bool
< :: Interrupt -> Interrupt -> Bool
$c<= :: Interrupt -> Interrupt -> Bool
<= :: Interrupt -> Interrupt -> Bool
$c> :: Interrupt -> Interrupt -> Bool
> :: Interrupt -> Interrupt -> Bool
$c>= :: Interrupt -> Interrupt -> Bool
>= :: Interrupt -> Interrupt -> Bool
$cmax :: Interrupt -> Interrupt -> Interrupt
max :: Interrupt -> Interrupt -> Interrupt
$cmin :: Interrupt -> Interrupt -> Interrupt
min :: Interrupt -> Interrupt -> Interrupt
Ord, Int -> Interrupt -> ShowS
[Interrupt] -> ShowS
Interrupt -> String
(Int -> Interrupt -> ShowS)
-> (Interrupt -> String)
-> ([Interrupt] -> ShowS)
-> Show Interrupt
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Interrupt -> ShowS
showsPrec :: Int -> Interrupt -> ShowS
$cshow :: Interrupt -> String
show :: Interrupt -> String
$cshowList :: [Interrupt] -> ShowS
showList :: [Interrupt] -> ShowS
Show)