From ea597e505a69974dfd35dd2728b1e9f3bb109fa9 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Mon, 24 Aug 2009 20:24:33 +0200 Subject: [PATCH] Add a backbuffer for the created window. This backbuffer is copied to the window on every expose event, but nothing is draw on it yet. --- FPPrac.hs | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/FPPrac.hs b/FPPrac.hs index 47b3cad..79a6a0a 100644 --- a/FPPrac.hs +++ b/FPPrac.hs @@ -99,6 +99,7 @@ testProg = Main data IState = forall s. IS { window :: Gtk.Window + , buffer :: IORef Cairo.Surface , postponed :: IORef [Request] , usrState :: IORef s , usrProg :: TinaStep s @@ -132,11 +133,11 @@ runTina :: TinaProgram -> IO () runTina Main {..} = do usrState <- newIORef initialState postponed <- newIORef (GfxText (rgb 0 0 0) (pt 50 50) "foo" : GfxClear :initialRequests) - let state = IS { window = undefined, usrProg = eventHandler, .. } + let state = IS { window = undefined, buffer = undefined, usrProg = eventHandler, .. } runGUI windowWidth windowHeight state runGUI :: Int -> Int -> IState -> IO () -runGUI w h s = do +runGUI w h (IS { .. }) = do -- Init GTK. Gtk.initGUI @@ -150,14 +151,36 @@ runGUI w h s = do , Gtk.windowDefaultHeight := h ] Gtk.onDestroy window Gtk.mainQuit - - -- Add the window to the state - let state = s { window = window } + -- Create a buffer to draw on (name the actual buffer buffer', so we + -- can use IS { .. } syntax below to pack the state. Using a record update + -- wouldn't work, probably because Cairo.Surface contains an existential + -- type... + -- We put the buffer in an IORef, so we can change it for a new one + -- later on (on window resizes). + buffer' <- Cairo.createImageSurface Cairo.FormatARGB32 w h + buffer <- newIORef buffer' + + -- Register the expose event + Gtk.on window Gtk.exposeEvent $ onExpose buffer + + -- Repack state + let state = IS { .. } + -- Show the window and start the Gtk mainloop. Gtk.widgetShowAll window Gtk.mainGUI +-- | Copy the given surface to the exposed window on an expose event. +onExpose :: IORef Cairo.Surface -> EventM.EventM EventM.EExpose Bool +onExpose buffer = do + current_buffer <- liftIO $ readIORef buffer + dw <- EventM.eventWindow + -- Copy the buffer to the window + liftIO $ Gtk.renderWithDrawable dw $ do + Cairo.setSourceSurface current_buffer 0 0 + Cairo.paint + return True -- No clue what this means {- runGUI s IS {..} = do -- 2.30.2