pvd-1.1.1: PvdSocket.hs
module PvdSocket (
initSocket,
handleClient
) where
import Control.Concurrent (forkIO)
import Control.Concurrent.STM
import Control.Monad (liftM, liftM2, liftM3, when)
import Network.Socket
import qualified System.IO as IO
import qualified XUtils as X
import PvdMonad
handleClient conf = do
(socket,dpy,win) <- runPvd conf (liftM3 (,,) getSocket getDpy getWin)
accept socket >>= forkIO . uncurry (processMessages dpy win)
where processMessages dpy win connsock clientaddr = do
connhdl <- socketToHandle connsock IO.ReadMode
IO.hSetBuffering connhdl IO.LineBuffering
messages <- IO.hGetContents connhdl
redraw <- fmap or $ mapM (runPvd conf . handleCmd) (lines messages)
IO.hClose connhdl
when redraw $ X.sendExposeEvent dpy win
initSocket port = withSocketsDo $ do
addrinfos <- getAddrInfo
(Just (defaultHints {addrFlags = [AI_PASSIVE]}))
Nothing (Just port)
let serveraddr = head addrinfos
sock <- socket (addrFamily serveraddr) Stream defaultProtocol
bindSocket sock (addrAddress serveraddr)
listen sock 5
return sock
handleCmd :: String -> Pvd Bool
handleCmd cmd = case words cmd of
["next"] -> modIdx $ (1 +) . snd
["prev"] -> modIdx $ (-1 +) . snd
["last"] -> modIdx $ (-1 +) . fst
["first"] -> modIdx $ \_ -> 0
"playlist":"add":imgs -> modPlaylist (++ imgs)
"playlist":"replace":imgs -> liftM2 (||) (setIdx 0) (setPlaylist imgs)
"playlist":"insert":"0":imgs ->
liftM2 (||) (modPlaylist (imgs ++)) (modIdx $ (length imgs +) . snd)
_ -> return False