The basic primitives exported by any frantk toolkit.
These are used in the abstract definitions of the GUI monad, Prim Widgets,
and Conf configure information.

data GUIInfo -- state for the toolkit

data WindowPrim -- a window
rootWinPrim :: GUIInfo -> IO WindowPrim -- the root window

data CanvasPrim -- a canvas

runLoop :: IO () -> (GUIInfo -> IO ()) -> IO ()
 -- run the event loop with a close down action

quitW :: GUIInfo -> IO () -- close everything down

data Config -- config information, such as setting the background 

debugW :: Bool -> GUIInfo -> IO () -- turn on debugging

getWTime :: GUIInfo -> IO Double 
 -- get the time in seconds since the program started

afterW :: Int -> IO () -> GUIInfo -> IO (IO ())
 -- perform an action once after x seconds

everyW :: Int -> IO () -> GUIInfo -> IO (IO ()) 
 -- perform an action every x seconds

updateW :: GUIInfo -> IO ()
 -- update the display

primCallback :: IO () -> GUIInfo -> IO (IO (),Remover)
 -- set up a callback action. It can be called with the first action
 -- in result pair and removed with second. It should be a primitive
 -- action that goes through the event loop

primRunW :: [String] -> GUIInfo -> IO String
primRunW_ :: [String] -> GUIInfo -> IO ()

\begin{code}
module WidgetExports (rootWinPrim,debugW,WindowPrim,Config,GUIInfo,getWTime,
                      runLoop,CanvasPrim,quitW,everyW,afterW,updateW,
		      primCallback,primRunW,primRunW_,
		      T.getRootPointerLoc,T.getPointerLoc,
		      validPanelConfigs) where
import qualified TclPrimImpl as T
import TclPrimImpl (Config,GUIInfo)
import FranPrim (Time)
import Remover
import IOExts
import Identify

instance Identifiable Config  where
 identify = identify . T.identifyConfig 

primRunW = flip T.tcl
primRunW_ = flip T.tcl_

quitW = T.quit
type CanvasPrim = T.Canvas
type WindowPrim = T.Window
getWTime = T.getTime
debugW = T.tcl_debug
rootWinPrim = T.rootWin
updateW g = T.tcl_ g ["update idletasks"]


runLoop :: IO () -> (GUIInfo -> IO ()) -> IO ()
runLoop finish act = T.runLoop $ \g -> do
 w <- T.rootWin g
 T.addFinaliserW w finish
 act g

afterW :: Time -> IO () -> GUIInfo -> IO (IO ())
afterW x act gui = 
  T.after (round (x * 1000)) act gui

everyW :: Time -> IO () -> GUIInfo -> IO (IO ())
everyW x act gui = do 
  ref <- newIORef (Just (return ()))
  every' (round (x * 1000)) ref 
  return $ callRemoverRef ref
 where
  callRemoverRef ref = do
    mb <- readIORef ref
    writeIORef ref Nothing
    case mb of
      Nothing -> return ()
      Just rm -> do writeIORef ref Nothing
		    rm

  every' :: Int -> IORef (Maybe (IO ())) -> IO ()
  every' x ref = do
    mb <- readIORef ref
    case mb of
     Nothing -> return ()
     Just _ -> do
      T.after x (do act;every' x ref;return ()) gui >>= writeIORef ref . Just

primCallback :: IO () -> GUIInfo -> IO (IO (),Remover)
primCallback io g = do
 (s,rm) <- T.tcl_callback g "." (const $ io)
 return (T.tcl_ g [tail $ init $ s],rm)

validPanelConfigs :: [Ident]
validPanelConfigs = 
 [identify "background", 
  identify "borderwidth", 
  identify "highlightbackground", identify "highlightcolor", 
  identify "highlightthickness", 
  identify "foreground"]

  
  
\end{code}
