2 -- A split-screen program:
3 -- User input is displayed in top half of screen;
4 -- Program output in the bottom half of the screen.
6 module TestCVar(talk) where
8 forkIO, CVar, newCVar, readCVar, writeCVar
11 -- from ansi.hs (modified for Xterm settings)
12 goto :: Int -> Int -> String
13 goto x y = "\ESC[" ++ show (y+1) ++ ";" ++ show (x+1) ++ "H"
16 cls = "\ESC[H\ESC[2J" -- for Xterm
18 -- Raw terminal handler:
19 -- Atomically writes characters to screen at specific coordinates.
21 type Terminal = CVar (Int,Int,Char)
23 terminal :: IO Terminal
25 = newCVar >>= \ buf ->
26 forkIO (server_loop buf) >>
29 -- possible optimisation:
30 -- remember current screen location to let us omit goto sometimes
32 = readCVar buf >>= \ (x,y,c) ->
38 -- Keeps track of cursor position so that user program doesn't have to.
39 -- Doesn't do redraw, scrolling, clipping, etc
41 type DemoWindow = CVar Char
43 window :: Terminal -> Int -> Int -> IO DemoWindow
45 = newCVar >>= \ buf ->
46 forkIO (server_loop buf left top) >>
50 = readCVar buf >>= \ c ->
52 server_loop buf left (y+1)
54 writeCVar t (x,y,c) >>
55 server_loop buf (x+1) y
57 put :: DemoWindow -> Char -> IO ()
58 put w c = writeCVar w c
60 -- copy input to top of screen, output to bottom of screen
61 talk :: (Char -> Char) -> IO ()
65 window t 0 0 >>= \ w1 ->
66 window t 0 12 >>= \ w2 ->
75 -- Non-blocking getchar
76 -- ToDo: find a way to replace the busy wait.
77 -- (Not easy in Unix!)
80 = primIOAvailable >>= \ avail ->