packages feed

Chitra-0.1: RFB/Handshake.hs

module RFB.Handshake (handshake) where

import System.IO
import qualified Data.ByteString.Lazy as BS
import qualified Data.ByteString.Lazy.Char8 as B
import Data.Char
import Data.Binary.Get
import Data.Binary.Put
import Data.Word

import Control.Monad.State

type MyState a = StateT Int IO a



handshake :: Int -> Int -> Handle -> IO ()
handshake w h hnd =  do
	runStateT (handshake1 w h hnd) 0
	return ()
			

handshake1 :: Int -> Int -> Handle -> MyState ()
handshake1 width height handle = do
	liftIO $ hPutStrLn handle "RFB 003.003"
	liftIO $ hFlush handle

	byteStream <- liftIO $ hGetLine handle
	liftIO $ putStrLn ("Client Said :: " ++ (show byteStream))
	let majorVersion = read $ (take 3).(drop 4) $ byteStream :: Int
	if majorVersion /= 3 then liftIO (fail ("Expected 3 but the Client sent " ++ (show majorVersion)))
		else liftIO $ return () -- contiue down the function

	-- Send 1 to the client, meaning, no auth required
	liftIO $ BS.hPutStr handle (BS.pack [0,0,0,1])
	liftIO $ hFlush handle

	clientInitMessage <- liftIO $ BS.hGet handle 1

	let sharedOrNot = runGet (do {x<-getWord8;return(x);}) clientInitMessage

	if sharedOrNot==1 then liftIO $ putStrLn "Sharing enabled"
		else liftIO $ putStrLn "Sharing disabled"

	liftIO $ BS.hPutStr handle (serverInitMessage width height)
	liftIO $ hFlush handle




serverInitMessage :: Int -> Int -> BS.ByteString
serverInitMessage width height = runPut $ do
				putWord16be (fromIntegral width::Word16) -- width
				putWord16be (fromIntegral height::Word16) -- height
				--pixel format
				putWord8 (32::Word8) -- bits per pixl
				putWord8 (24::Word8) -- depth
				putWord8 (1::Word8) -- big endian
				putWord8 (1::Word8) -- true color
				putWord16be (255::Word16) -- red max
				putWord16be (255::Word16) -- green max
				putWord16be (255::Word16) -- blue max
				putWord8 (16::Word8) -- red shift
				putWord8 (8::Word8)  -- green shift
				putWord8 (0::Word8)  -- blue shift

				--padding
				putWord8 (0::Word8)
				putWord8 (0::Word8)
				putWord8 (0::Word8)

				--name length
				let name = "Haskell Framebuffer"
				putWord32be (((fromIntegral.length) name)::Word32)
				--mapM_ (putWord8.fromIntegral.ord) name --this works
				putLazyByteString (B.pack name)
				--putLazyByteString (stringToByteString name) --this works