diff --git a/Chitra.cabal b/Chitra.cabal
new file mode 100644
--- /dev/null
+++ b/Chitra.cabal
@@ -0,0 +1,41 @@
+Name:                Chitra
+Version:             0.1
+Synopsis:            Haskell library for platform independent graphics using VNC.
+Homepage:            http://github.com/ckkashyap/Chitra
+License:             BSD3
+License-file:        LICENSE
+Author:              C K Kashyap
+Maintainer:          ckkashyap@gmail.com
+synopsis:		Simple, VNC based graphics rendering system
+description: Chitra in most Indian languages means "Image". This aim of this project is to build an VNC library that can be used to develop interactive graphical application. What I think will be the strength of Chitra would be its "platform independence". So, the idea is, the library would have a "putpixel" function which when called would render a pixel on an image buffer that would be rendered via the vnc server. For viewing and interactive with the aplication, one would use a standard VNC client. Eventually, I might chose to do this using the RDP protocol that even has support for sound.  
+
+	To try out -
+
+	Just do a make and you should have the executable *Main* created. 
+
+	Run ./Main <width> <height> <port> 
+
+	Now try connecting a vnc client to localhost:5900
+
+Category:            Graphics
+
+Build-type:          Simple
+
+Cabal-version:       >=1.2
+
+Library
+  Exposed-modules:     Chitra.Canvas,
+                       RFB.ClientToServer,
+                       RFB.Handshake,
+                       RFB.CommandLoop,
+                       RFB.Server
+  Hs-source-dirs:      ./
+  Build-depends:       base >= 4.2 && < 4.3,
+                       binary >= 0.5 && < 0.6,
+                       bytestring >= 0.9 && < 1.0,
+                       network >= 2.2 && < 2.3,
+                       mtl >= 1.1 && < 1.2
+
+Executable Chitra
+  Main-is:             Main.hs
+  Build-depends:       base >= 4.2 && < 4.3
diff --git a/Chitra/Canvas.hs b/Chitra/Canvas.hs
new file mode 100644
--- /dev/null
+++ b/Chitra/Canvas.hs
@@ -0,0 +1,27 @@
+module Chitra.Canvas where
+
+import Control.Monad
+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 qualified RFB.Constants as RFB
+import qualified RFB.Server as SERVER
+import qualified RFB.Handshake as Handshake
+import qualified RFB.CommandLoop as CommandLoop
+
+
+
+start w h p= do
+	SERVER.serve w h p doit
+
+doit w h hnd = do
+	Handshake.handshake w h hnd
+	CommandLoop.commandLoop hnd w h
+	
+
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,29 @@
+Copyright 2002, C.K.Kashyap
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the copyright holder(s) nor the names of
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Main.hs b/Main.hs
new file mode 100644
--- /dev/null
+++ b/Main.hs
@@ -0,0 +1,11 @@
+import qualified Chitra.Canvas as C
+import System.Environment
+
+main = do
+	args <- getArgs
+	case args of
+		[w,h,port] -> C.start width height port
+			where
+				width = read w :: Int
+				height = read h :: Int
+		_ -> putStrLn "Usage: ./Main width height port"
diff --git a/RFB/ClientToServer.hs b/RFB/ClientToServer.hs
new file mode 100644
--- /dev/null
+++ b/RFB/ClientToServer.hs
@@ -0,0 +1,109 @@
+module RFB.ClientToServer (
+	Command
+	(
+		SetPixelFormat ,
+		SetEncodings ,
+		FramebufferUpdate ,
+		KeyEvent ,
+		PointerEvent ,
+		ClientCutText ,
+		BadCommand
+	),
+	CommandData
+	(
+		SetPixelFormatData ,
+		SetEncodingsData ,
+		FramebufferUpdateData ,
+		KeyEventData ,
+		PointerEventData ,
+		ClientCutTextData
+	),
+	bytesToRead,
+	parseCommandByteString,
+	getCommandData,
+	word8ToCommand,
+) where
+
+import Data.Word
+
+import qualified Utilities.ParseByteString as PBS
+import qualified Data.ByteString.Lazy as BS
+
+
+data Command = SetPixelFormat | SetEncodings | FramebufferUpdate | KeyEvent | PointerEvent | ClientCutText | BadCommand deriving (Show)
+
+data CommandData = SetPixelFormatData {
+	bitsPerPixel	:: Int,
+	depth		:: Int,
+	bigEndian	:: Int,
+	trueColor	:: Int,
+	redMax		:: Int,
+	greenMax	:: Int,
+	blueMax		:: Int,
+	redShift	:: Int,
+	greenShift	:: Int,
+	blueShift	:: Int
+} | ClientCutTextData {
+	length		:: Int
+} | SetEncodingsData {
+	count		:: Int
+} | FramebufferUpdateData {
+	incremental	:: Int,
+	x		:: Int,
+	y		:: Int,
+	width		:: Int,
+	height		:: Int
+} | KeyEventData {
+	downFlag	:: Int,
+	key		:: Int
+} | PointerEventData {
+	buttonMask	:: Int,
+	x		:: Int,
+	y		:: Int
+} | BadCommandData deriving (Show)
+
+
+
+bytesToRead :: Command -> Int
+bytesToRead c = foldr (+) 0 (map (\x -> if x == 0 then 1 else x) (commandFormat c))
+
+commandFormat :: Command -> [Int] -- 0 for padding bytes
+commandFormat c = case c of
+		SetPixelFormat		-> [0,0,0,1,1,1,1,2,2,2,1,1,1,0,0,0]
+		SetEncodings		-> [0,2]
+		FramebufferUpdate	-> [1,2,2,2,2]
+		KeyEvent		-> [1,0,0,4]
+		PointerEvent		-> [1,2,2]
+		ClientCutText		-> [0,0,0,4]
+		BadCommand		-> []
+
+
+parseCommandByteString :: BS.ByteString -> Command -> [Int]
+parseCommandByteString byteString command =
+	PBS.parseByteString list byteString
+		where 
+			list = (commandFormat command)
+
+getCommandData	:: BS.ByteString -> Command -> CommandData
+getCommandData byteString command = commandDataFromList list
+	where
+		list = PBS.parseByteString (commandFormat command) byteString
+		commandDataFromList xs = case command of
+			SetPixelFormat		-> SetPixelFormatData (xs!!0) (xs!!1) (xs!!2) (xs!!3) (xs!!4) (xs!!5) (xs!!6) (xs!!7) (xs!!8) (xs!!9)
+			SetEncodings		-> SetEncodingsData (xs!!0)
+			FramebufferUpdate	-> FramebufferUpdateData (xs!!0) (xs!!1) (xs!!2) (xs!!3) (xs!!4)
+			KeyEvent		-> KeyEventData (xs!!0) (xs!!1)
+			PointerEvent		-> PointerEventData (xs!!0) (xs!!1) (xs!!2)
+			ClientCutText		-> ClientCutTextData (xs!!0)
+			BadCommand		-> BadCommandData
+
+
+word8ToCommand :: Word8 -> Command
+word8ToCommand w = case w of
+	0 -> SetPixelFormat
+	2 -> SetEncodings
+	3 -> FramebufferUpdate
+	4 -> KeyEvent
+	5 -> PointerEvent
+	6 -> ClientCutText
+	_ -> BadCommand
diff --git a/RFB/CommandLoop.hs b/RFB/CommandLoop.hs
new file mode 100644
--- /dev/null
+++ b/RFB/CommandLoop.hs
@@ -0,0 +1,129 @@
+{-# LANGUAGE NamedFieldPuns #-}
+module RFB.CommandLoop (commandLoop) where
+
+import System.IO
+import qualified Data.ByteString.Lazy as BS
+
+import Data.Char
+import Data.Binary.Get
+import Data.Binary.Put
+import Data.Word
+
+import qualified RFB.ClientToServer as RFBClient
+import qualified RFB.Encoding as Encoding
+import qualified RFB.State as RFBState
+
+import Control.Monad.State
+
+
+type MyState a = StateT RFBState.RFBState  IO a
+
+commandLoop :: Handle -> Int -> Int -> IO ()
+commandLoop h width height= do
+	runStateT (commandLoop1 h) (RFBState.initialState width height)
+	return ()
+
+
+commandLoop1 :: Handle -> MyState ()
+commandLoop1 handle = do
+	commandByte <- liftIO$ BS.hGet handle 1
+	let command = RFBClient.word8ToCommand $ runGet (do {x<-getWord8;return(x);}) commandByte
+	byteStream <- liftIO $ BS.hGet handle (RFBClient.bytesToRead command)
+	let commandData = RFBClient.getCommandData byteStream command
+	--let commandData = RFBClient.parseCommandByteString byteStream command
+	liftIO $ putStrLn $ "Client said -> " ++ (show command)
+	liftIO $ putStrLn (show commandData)
+	case command of
+		RFBClient.SetPixelFormat -> processSetPixelFormat commandData
+		RFBClient.SetEncodings -> liftIO $ processSetEncodings handle commandData 
+		RFBClient.FramebufferUpdate -> processFrameBufferUpdateRequest handle commandData
+		RFBClient.PointerEvent -> processPointerEvent handle commandData
+		RFBClient.ClientCutText -> processClientCutTextEvent handle commandData
+		RFBClient.KeyEvent -> processKeyEvent handle commandData
+		RFBClient.BadCommand -> liftIO $ putStrLn (show command)
+	commandLoop1 handle
+
+
+
+processClientCutTextEvent handle (RFBClient.ClientCutTextData length) = do
+	x <- liftIO $ BS.hGet handle length
+	liftIO $ putStrLn (show x)
+
+	
+
+processKeyEvent handle commandData = do
+	return ()
+
+processPointerEvent handle (RFBClient.PointerEventData buttonMask x y)= do
+	state@(RFBState.RFBState d i p pend u) <- get
+	let newState=if buttonMask == 1 then Encoding.putPixel state (x,y) else state
+	put newState
+	if pend && ((length u) > 0) then do
+			liftIO $ putStrLn $ "Updating -> " ++ (show u)
+			liftIO $ BS.hPutStr handle (updateRectangles state)
+			liftIO $ hFlush handle
+			put (RFBState.RFBState d i p False [])
+			return ()
+		else 
+			return ()
+
+
+
+processSetPixelFormat (RFBClient.SetPixelFormatData bitsPerPixel depth bigEndian trueColor redMax greenMax blueMax redShift greenShift blueShift)
+	= do
+		state <- get
+		let newState=RFBState.setPixelFormat state bitsPerPixel bigEndian redMax greenMax blueMax redShift greenShift blueShift
+		put newState
+		return ()
+
+
+
+processSetEncodings handle (RFBClient.SetEncodingsData count) = do
+	x <- BS.hGet handle (4*count)
+	let e = runGet (do {x<-getWord32le; return x}) x
+	putStrLn (show e)
+	return ()
+
+
+fullScreen :: Int -> Int -> Int -> Int -> RFBState.RFBState -> BS.ByteString
+fullScreen x y width height state = runPut $ do
+	putWord8 0
+	putWord8 0
+	putWord16be 1
+	putWord16be (fromIntegral x)
+	putWord16be (fromIntegral y)
+	putWord16be (fromIntegral width)
+	putWord16be (fromIntegral height)
+	putWord32be 0
+	Encoding.getImageByteString state x y width height
+	return ()
+
+
+
+updateRectangles state@(RFBState.RFBState _ _ (RFBState.PixelFormat bpp _ _ _ _ _ _ _) pend updateList) = runPut $ do
+	putWord8 0
+	putWord8 0
+	putWord16be (fromIntegral (length updateList))
+	Encoding.encodeRectagles bpp updateList
+	return ()
+
+empty = runPut $ return ()
+
+
+	
+
+processFrameBufferUpdateRequest handle (RFBClient.FramebufferUpdateData incremental x y width height) = do -- this produces black
+	state@(RFBState.RFBState d i p pend u) <- get
+	let byteString=if incremental == 0 then fullScreen x y width height state else (if (length u > 0) then updateRectangles state else empty)
+	--let newState = if incremental == 0 then state else RFBState.RFBState d i p pend []
+	let newState = if incremental == 0 then RFBState.RFBState d i p False [] else RFBState.RFBState d i p (if (length u > 0) then False else True) [] 
+	put newState
+ 	(RFBState.RFBState _ _ _ newPend _) <- get
+	liftIO $ putStrLn (show pend)
+	liftIO $ putStrLn (show newPend)
+	--liftIO $ putStrLn (show state)
+	--liftIO $ putStrLn (show newState)
+	liftIO $ BS.hPutStr handle byteString
+	liftIO $ hFlush handle
+
+
diff --git a/RFB/Handshake.hs b/RFB/Handshake.hs
new file mode 100644
--- /dev/null
+++ b/RFB/Handshake.hs
@@ -0,0 +1,77 @@
+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
diff --git a/RFB/Server.hs b/RFB/Server.hs
new file mode 100644
--- /dev/null
+++ b/RFB/Server.hs
@@ -0,0 +1,56 @@
+module RFB.Server (serve) where
+
+import Data.Bits
+import Network.Socket
+import Network.BSD
+import Data.List
+import Control.Concurrent
+import Control.Concurrent.MVar
+import System.IO
+
+
+-- HandlerFunc Width Height
+type HandlerFunc = Int -> Int -> Handle -> IO ()
+
+serve :: Int -> Int -> String -> HandlerFunc -> IO ()
+serve width height port handlerFunc = withSocketsDo $
+	do 	-- Look up the port.  Either raises an exception or returns
+		-- a nonempty list.  
+		addrinfos <- getAddrInfo 
+			(Just (defaultHints {addrFlags = [AI_PASSIVE]}))
+			Nothing (Just port)
+		let serveraddr = head addrinfos
+
+		-- Create a socket
+		sock <- socket (addrFamily serveraddr) Stream defaultProtocol
+
+		-- Bind it to the address we're listening to
+		bindSocket sock (addrAddress serveraddr)
+
+		-- Start listening for connection requests.  Maximum queue size
+		-- of 5 connection requests waiting to be accepted.
+		listen sock 5
+
+		-- Create a lock to use for synchronizing access to the handler
+		lock <- newMVar ()
+
+		-- Loop forever waiting for connections.  Ctrl-C to abort.
+		procRequests lock sock
+		where
+		  -- | Process incoming connection requests
+		  procRequests :: MVar () -> Socket -> IO ()
+		  procRequests lock mastersock = 
+		      do (connsock, clientaddr) <- accept mastersock
+			 forkIO $ procMessages lock connsock clientaddr
+			 procRequests lock mastersock
+
+		  -- | Process incoming messages
+		  procMessages :: MVar () -> Socket -> SockAddr -> IO ()
+		  procMessages lock connsock clientaddr =
+		      do connhdl <- socketToHandle connsock ReadWriteMode
+			 --hSetBuffering connhdl LineBuffering
+			 --messages <- hGetContents connhdl
+			 --mapM_ (handle lock clientaddr) (lines messages)
+			 handlerFunc width height connhdl
+			 hClose connhdl
+
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
