summaryrefslogtreecommitdiff
path: root/highway/Main.hs
blob: 58049dfcefa7662fdb386957eabe3fb70b98131c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
{-# LANGUAGE TemplateHaskell #-}

import Wayland.Server
import Lens.Micro.TH (makeLenses)
import Lens.Micro.Mtl ((%=), (<%=))
import Data.Data (Typeable)
import Control.Monad (void, when)
import Control.Monad.Trans (liftIO)
import qualified Wayland.Protocols.Core.WLOutput as WLOutput
import qualified Data.Map as M

geometry :: WLOutput.Geometry
geometry = WLOutput.Geometry { WLOutput.x              = 0
                             , WLOutput.y              = 0
                             , WLOutput.physicalWidth  = 5120
                             , WLOutput.physicalHeight = 2880
                             , WLOutput.subpixel       = WLOutput.SubpixelNone
                             , WLOutput.make           = "Apple"
                             , WLOutput.model          = "Studio Display"
                             , WLOutput.transform      = WLOutput.TransformNormal
                             }

data BindRequest
  = BindOutput WLOutput.Handle
  deriving (Typeable, Show)

data SignalRequest
  = ReqSIGINT
  deriving (Typeable, Show)

instance RequestClass SignalRequest
instance RequestClass BindRequest

data Output = Output
  deriving (Show)

data State = State { _outputs          :: M.Map WLOutput.Handle Output
                   , _interruptedCount :: Int
                   }
  deriving (Show)

makeLenses ''State

handleRequest :: Request -> DisplayM State ()
handleRequest r
  | Just (WLOutput.ReqRelease o) <- fromRequest r = do outputs %= M.delete o
                                                       destroyResource o
  | Just (BindOutput o)          <- fromRequest r = do outputs %= M.insert o Output
                                                       sendEvent o $ WLOutput.EvGeometry geometry
                                                       sendEvent o $ WLOutput.EvDone
                                                       flushEvents
  | Just ReqSIGINT               <- fromRequest r = do c <- interruptedCount <%= (+1)
                                                       liftIO $ putStrLn $ "Received SIGINT " ++ show c ++ "/3"
                                                       when (c >= 3) requestTermination
  | otherwise                                     = pure ()

main :: IO ()
main = void $ withDisplay (State M.empty 0) $ do
  socket <- bindSocket
  liftIO $ putStrLn $ "Listening on socket: " ++ socket
  registerSignalEvent ReqSIGINT 2
  output <- registerGlobal BindOutput
  processRequests handleRequest
  unregisterGlobal output