xturtle 0.1.5 → 0.1.6
raw patch · 7 files changed
+189/−138 lines, 7 files
Files
- src/Graphics/X11/Turtle.hs +14/−5
- src/Graphics/X11/Turtle/Data.hs +12/−15
- src/Graphics/X11/Turtle/Field.hs +58/−22
- src/Graphics/X11/Turtle/Input.hs +17/−0
- src/Graphics/X11/Turtle/Move.hs +5/−2
- src/Graphics/X11/Turtle/XTools.hs +82/−93
- xturtle.cabal +1/−1
src/Graphics/X11/Turtle.hs view
@@ -28,6 +28,8 @@ setheading, circle, write,+ stamp,+ dot, image, bgcolor, home,@@ -75,6 +77,7 @@ ondrag, onmotion, onkeypress,+ ontimer, -- * save and load getInputs,@@ -82,7 +85,7 @@ getSVG ) where -import Graphics.X11.Turtle.Data(nameToShape, nameToSpeed)+import Graphics.X11.Turtle.Data(shapeTable, speedTable) import Graphics.X11.Turtle.Input( TurtleState, TurtleInput(..), turtleSeries, direction, visible, undonum, drawed, polyPoints)@@ -91,7 +94,7 @@ Field, Layer, Character, openField, closeField, forkField, waitField, fieldSize, flushField, moveTurtle, addLayer, clearLayer, addCharacter, clearCharacter,- onclick, onrelease, ondrag, onmotion, onkeypress)+ onclick, onrelease, ondrag, onmotion, onkeypress, ontimer) import Text.XML.YJSVG(SVG(..), Color(..)) import Control.Concurrent(Chan, writeChan, ThreadId, killThread)@@ -104,7 +107,7 @@ -------------------------------------------------------------------------------- xturtleVersion :: (Int, String)-xturtleVersion = (53, "0.1.5")+xturtleVersion = (56, "0.1.6") -------------------------------------------------------------------------------- @@ -137,7 +140,7 @@ (ic, tis, sts) <- turtleSeries si <- newIORef 1 tid <- forkField f $ zipWithM_ (moveTurtle f ch l) sts $ tail sts- shps <- newIORef $ map (\n -> (n, nameToShape n)) ["classic", "turtle"]+ shps <- newIORef shapeTable let t = Turtle { field = f, layer = l,@@ -195,6 +198,12 @@ write :: Turtle -> String -> Double -> String -> IO () write t fnt sz = input t . Write fnt sz +stamp :: Turtle -> IO ()+stamp = (`input` Stamp)++dot :: Turtle -> Double -> IO ()+dot t = input t . Dot+ image :: Turtle -> FilePath -> Double -> Double -> IO () image t fp w h = input t $ PutImage fp w h @@ -236,7 +245,7 @@ shapesize t sx sy = input t $ Shapesize sx sy speed :: Turtle -> String -> IO ()-speed t str = case nameToSpeed str of+speed t str = case lookup str speedTable of Just (ps, ds) -> input t (PositionStep ps) >> input t (DirectionStep ds) Nothing -> putStrLn "no such speed"
src/Graphics/X11/Turtle/Data.hs view
@@ -1,19 +1,17 @@-module Graphics.X11.Turtle.Data(nameToShape, nameToSpeed) where+module Graphics.X11.Turtle.Data(+ -- * tables+ shapeTable, speedTable+) where import Control.Arrow(second, (&&&)) -nameToShape :: String -> [(Double, Double)]-nameToShape "classic" = unfold [(- 10, 0), (- 16, 6), (0, 0)]-nameToShape "turtle" = unfold [- (- 10, 0), (- 8, 3), (- 10, 5), (- 7, 9), (- 5, 6), (0, 8), (4, 7),- (6, 10), (8, 7), (7, 5), (10, 2), (13, 3), (16, 0)]-nameToShape name = error $ "There is no shape named " ++ name--unfold :: [(Double, Double)] -> [(Double, Double)]-unfold = uncurry (++) . (id &&& (reverse . map (second negate)))--nameToSpeed :: String -> Maybe (Maybe Double, Maybe Double)-nameToSpeed str = lookup str speedTable+shapeTable :: [(String, [(Double, Double)])]+shapeTable = [+ ("classic", unfold [(- 10, 0), (- 16, 6), (0, 0)]),+ ("turtle", unfold [+ (- 10, 0), (- 8, 3), (- 10, 5), (- 7, 9), (- 5, 6), (0, 8),+ (4, 7), (6, 10), (8, 7), (7, 5), (10, 2), (13, 3), (16, 0)])]+ where unfold = uncurry (++) . (id &&& (reverse . map (second negate))) speedTable :: [(String, (Maybe Double, Maybe Double))] speedTable = [@@ -21,5 +19,4 @@ ("fast", (Just 60, Just $ pi / 3)), ("normal", (Just 20, Just $ pi / 9)), ("slow", (Just 10, Just $ pi / 18)),- ("slowest", (Just 3, Just $ pi / 60))- ]+ ("slowest", (Just 3, Just $ pi / 60))]
src/Graphics/X11/Turtle/Field.hs view
@@ -19,6 +19,7 @@ addLayer, drawLine, fillPolygon,+ fillRectangle, writeString, drawImage, undoLayer,@@ -35,7 +36,8 @@ onrelease, ondrag, onmotion,- onkeypress+ onkeypress,+ ontimer ) where import Graphics.X11.Turtle.XTools(@@ -43,22 +45,23 @@ XEventPtr, XIC, Bufs, undoBuf, bgBuf, topBuf, GCs, gcForeground, gcBackground, Event(..), forkIOX, openWindow, destroyWindow, closeDisplay, windowSize,- flush, getColorPixel, setForeground, copyArea, fillRectangle,+ flush, colorPixel, setForeground, copyArea, drawLineXT, writeStringXT, allocaXEvent, waitEvent, pending, nextEvent, getEvent, filterEvent, utf8LookupString, buttonPress, buttonRelease, xK_VoidSymbol)-import qualified Graphics.X11.Turtle.XTools as X(fillPolygon, drawImage)+import qualified Graphics.X11.Turtle.XTools as X(fillPolygonXT, drawImageXT,+ fillRectangle) import Graphics.X11.Turtle.Layers( Layers, Layer, Character, newLayers, redrawLayers, makeLayer, addDraw, setBackground, undoLayer, clearLayer, makeCharacter, setCharacter) import Text.XML.YJSVG(Color(..)) -import Control.Monad(forever, replicateM, when)+import Control.Monad(forever, replicateM, when, join, unless) import Control.Monad.Tools(doWhile_, doWhile, whenM) import Control.Arrow((***)) import Control.Concurrent(- forkIO, ThreadId, killThread, Chan, newChan, readChan, writeChan)+ forkIO, ThreadId, killThread, Chan, newChan, readChan, writeChan, threadDelay) import Data.IORef(IORef, newIORef, readIORef, writeIORef, modifyIORef) import Data.Maybe(fromMaybe)@@ -74,9 +77,11 @@ fDrag :: IORef (Double -> Double -> IO ()), fMotion :: IORef (Double -> Double -> IO ()), fKeypress :: IORef (Char -> IO Bool), fPressed :: IORef Bool,+ fTimerEvent :: IORef (IO Bool), fLayers :: IORef Layers, fRunning :: IORef [ThreadId],- fLock, fClose, fEnd :: Chan ()+ fLock, fClose, fEnd :: Chan (),+ fInputChan :: Chan InputType } makeField :: Display -> Window -> Bufs -> GCs -> XIC -> Atom ->@@ -87,19 +92,21 @@ motion <- newIORef $ \_ _ -> return () keypress <- newIORef $ \_ -> return True pressed <- newIORef False+ timer <- newIORef $ return True running <- newIORef [] [lock, close, end] <- replicateM 3 newChan+ inputChan <- newChan writeChan lock () return Field{ fDisplay = dpy, fWindow = win, fBufs = bufs, fGCs = gcs, fIC = ic, fDel = del, fSize = sizeRef, fClick = click, fRelease = release, fDrag = drag, fMotion = motion,- fKeypress = keypress, fPressed = pressed,+ fKeypress = keypress, fPressed = pressed, fTimerEvent = timer, fLayers = ls, fRunning = running,- fLock = lock, fClose = close, fEnd = end+ fLock = lock, fClose = close, fEnd = end, fInputChan = inputChan } --------------------------------------------------------------------------------@@ -112,7 +119,7 @@ sizeRef <- newIORef size let getSize = readIORef sizeRef ls <- newLayers 50 - (getSize >>= uncurry (fillRectangle dpy ub gcb 0 0))+ (getSize >>= uncurry (X.fillRectangle dpy ub gcb 0 0)) (getSize >>= \(w, h) -> copyArea dpy ub bb gcf 0 0 w h 0 0) (getSize >>= \(w, h) -> copyArea dpy bb tb gcf 0 0 w h 0 0) f <- makeField dpy win bufs gcs ic del sizeRef ls@@ -120,25 +127,38 @@ flush dpy return f -waitInput :: Field -> IO (Chan Bool, Chan ())+data InputType = XInput | End | Timer++waitInput :: Field -> IO (Chan InputType, Chan ()) waitInput f = do- go <- newChan+-- go <- newChan+ let go = fInputChan f empty <- newChan tid <- forkIOX $ forever $ do waitEvent $ fDisplay f- writeChan go True+ writeChan go XInput readChan empty+ modifyIORef (fRunning f) (tid :) _ <- forkIO $ do readChan $ fClose f killThread tid- writeChan go False+ writeChan go End return (go, empty) runLoop :: Field -> IO () runLoop f = allocaXEvent $ \e -> do (go, empty) <- waitInput f doWhile_ $ do- notEnd <- readChan go+ iType <- readChan go+ cont' <- case iType of+ Timer -> do+ c <- join $ readIORef $ fTimerEvent f+ unless c $ readIORef (fRunning f) >>= mapM_ killThread+ return c -- readIORef (fTimerEvent f) >>= k+ _ -> return True+ let notEnd = case iType of+ End -> False+ _ -> True cont <- doWhile True $ const $ do evN <- pending $ fDisplay f if evN > 0 then do@@ -149,7 +169,7 @@ c <- processEvent f e ev return (c, c) else return (True, False)- if notEnd && cont then writeChan empty () >> return True+ if notEnd && cont && cont' then writeChan empty () >> return True else return False readIORef (fRunning f) >>= mapM_ killThread destroyWindow (fDisplay f) (fWindow f)@@ -224,10 +244,10 @@ fieldColor :: Field -> Layer -> Color -> IO () fieldColor f l c = setBackground l $ do- getColorPixel (fDisplay f) c >>=+ colorPixel (fDisplay f) c >>= maybe (return ()) (setForeground (fDisplay f) (gcBackground $ fGCs f))- readIORef (fSize f) >>= uncurry (fillRectangle+ readIORef (fSize f) >>= uncurry (X.fillRectangle (fDisplay f) (undoBuf $ fBufs f) (gcBackground $ fGCs f) 0 0) --------------------------------------------------------------------------------@@ -252,17 +272,27 @@ drawImage f l fp xc yc w h = addDraw l (di undoBuf, di bgBuf) where di bf = do (x, y) <- topLeft f xc yc- X.drawImage (fDisplay f) (bf $ fBufs f) (gcForeground $ fGCs f)+ X.drawImageXT (fDisplay f) (bf $ fBufs f) (gcForeground $ fGCs f) fp x y (round w) (round h) fillPolygon :: Field -> Layer -> [(Double, Double)] -> Color -> IO () fillPolygon f l psc clr = addDraw l (fp undoBuf, fp bgBuf) where fp bf = do ps <- mapM (fmap (uncurry Point) . uncurry (topLeft f)) psc- getColorPixel (fDisplay f) clr >>= maybe (return ())+ colorPixel (fDisplay f) clr >>= maybe (return ()) (setForeground (fDisplay f) (gcForeground $ fGCs f))- X.fillPolygon (fDisplay f) (bf $ fBufs f) (gcForeground $ fGCs f) ps+ X.fillPolygonXT (fDisplay f) (bf $ fBufs f) (gcForeground $ fGCs f) ps +fillRectangle ::+ Field -> Layer -> Double -> Double -> Double -> Double -> Color -> IO ()+fillRectangle f l xc0 yc0 w h clr = addDraw l (fr undoBuf, fr bgBuf)+ where fr bf = do+ (x0, y0) <- topLeft f xc0 yc0+ colorPixel (fDisplay f) clr >>= maybe (return ())+ (setForeground (fDisplay f) (gcForeground $ fGCs f))+ X.fillRectangle (fDisplay f) (bf $ fBufs f) (gcForeground $ fGCs f)+ x0 y0 (round w) (round h)+ drawLineBuf :: Field -> (Bufs -> Pixmap) -> Int -> Color -> Double -> Double -> Double -> Double -> IO () drawLineBuf f bf lw c x1_ y1_ x2_ y2_ = do@@ -292,9 +322,9 @@ drawShape :: Field -> Color -> [(Double, Double)] -> IO () drawShape f clr psc = do ps <- mapM (fmap (uncurry Point) . uncurry (topLeft f)) psc- getColorPixel (fDisplay f) clr >>= maybe (return ())+ colorPixel (fDisplay f) clr >>= maybe (return ()) (setForeground (fDisplay f) (gcForeground $ fGCs f))- X.fillPolygon (fDisplay f) (topBuf $ fBufs f) (gcForeground $ fGCs f) ps+ X.fillPolygonXT (fDisplay f) (topBuf $ fBufs f) (gcForeground $ fGCs f) ps clearCharacter :: Character -> IO () clearCharacter c = setCharacter c $ return ()@@ -310,3 +340,9 @@ onkeypress :: Field -> (Char -> IO Bool) -> IO () onkeypress = writeIORef . fKeypress++ontimer :: Field -> Int -> IO Bool -> IO ()+ontimer f t fun = do+ writeIORef (fTimerEvent f) fun+ threadDelay $ t * 1000+ writeChan (fInputChan f) Timer
src/Graphics/X11/Turtle/Input.hs view
@@ -21,6 +21,7 @@ import Text.XML.YJSVG(SVG(..), Color(..), Position(..)) import Control.Concurrent.Chan(Chan, newChan, getChanContents)+import Control.Arrow -------------------------------------------------------------------------------- @@ -41,6 +42,8 @@ | Rotate Double | Write String Double String | PutImage FilePath Double Double+ | Stamp+ | Dot Double | Bgcolor Color | Undo | Clear@@ -112,6 +115,20 @@ nextTurtle t (PutImage fp w h) = (clearState t){ draw = Just img, drawed = img : drawed t} where img = Image (uncurry Center $ position t) w h fp+nextTurtle t Stamp = (clearState t){+ draw = Just stamp, drawed = stamp : drawed t}+ where+ (x0, y0) = position t+ sp = let (sx, sy) = shapesize t in+ map (((+ x0) *** (+ y0)) . rotate . ((* sx) *** (* sy))) $ shape t+ rotate (x, y) = let rad = direction t in+ (x * cos rad - y * sin rad, x * sin rad + y * cos rad)+ points = map (uncurry Center) sp+ stamp = Polyline points (pencolor t) (pencolor t) 0+nextTurtle t (Dot sz) = (clearState t){+ draw = Just dot, drawed = dot : drawed t}+ where+ dot = Rect (uncurry Center $ position t) sz sz 0 (pencolor t) (pencolor t) nextTurtle t (Bgcolor c) = (clearState t){ bgcolor = c, drawed = init (drawed t) ++ [Fill c]} nextTurtle t Clear = (clearState t){clear = True, drawed = [last $ drawed t]}
src/Graphics/X11/Turtle/Move.hs view
@@ -24,7 +24,8 @@ onrelease, ondrag, onmotion,- onkeypress+ onkeypress,+ ontimer ) where import Graphics.X11.Turtle.State(TurtleState(..))@@ -33,8 +34,9 @@ openField, closeField, waitField, fieldSize, forkField, flushField, fieldColor, addLayer, drawLine, writeString, undoLayer, clearLayer, fillPolygon,+ fillRectangle, addCharacter, drawCharacter, drawCharacterAndLine, clearCharacter,- onclick, onrelease, ondrag, onmotion, onkeypress, drawImage)+ onclick, onrelease, ondrag, onmotion, onkeypress, drawImage, ontimer) import Text.XML.YJSVG(SVG(..), Position(..)) import Control.Concurrent(threadDelay)@@ -83,6 +85,7 @@ where posToTup (Center x y) = (x, y) posToTup _ = error "not implemented"+drawSVG f l (Rect (Center x y) w h 0 fc _) = fillRectangle f l x y w h fc drawSVG f l (Image (Center x0 y0) w h fp) = drawImage f l fp x0 y0 w h drawSVG _ _ (Fill _) = return () drawSVG _ _ _ = error "not implemented"
src/Graphics/X11/Turtle/XTools.hs view
@@ -3,12 +3,11 @@ Display, Window, Pixmap,+ XIC, Atom, Point(..), Position, Dimension,- XEventPtr,- XIC, Bufs, undoBuf, bgBuf,@@ -16,27 +15,30 @@ GCs, gcForeground, gcBackground,++ -- ** event types+ XEventPtr, Event(..), - -- * open window+ -- * basic functions forkIOX, openWindow, destroyWindow, closeDisplay, windowSize, - -- * draws+ -- * draw functions flush,- getColorPixel,+ colorPixel, setForeground, copyArea, fillRectangle,- fillPolygon,+ fillPolygonXT, drawLineXT, writeStringXT,- drawImage,+ drawImageXT, - -- * event+ -- * event functions allocaXEvent, waitEvent, pending,@@ -52,57 +54,51 @@ import Text.XML.YJSVG(Color(..)) import Graphics.X11(- Display, Drawable, Window, Pixmap, Visual, Colormap, GC, Pixel, Atom,- Point(..), Position, Dimension, XEventPtr,+ Display, Drawable, Window, Pixmap, GC, Pixel, Atom, Point(..), Position,+ Dimension, XEventPtr, initThreads, flush, supportsLocale, setLocaleModifiers, connectionNumber, openDisplay, closeDisplay, internAtom,- createSimpleWindow, destroyWindow, mapWindow, createGC, createPixmap,- rootWindow, defaultScreen, defaultScreenOfDisplay, defaultVisual,- defaultColormap, defaultDepth, whitePixel, blackPixel,- copyArea, fillRectangle, drawLine, nonconvex, coordModeOrigin,+ createSimpleWindow, destroyWindow, mapWindow, getGeometry,+ createGC, createPixmap, rootWindow, defaultScreen,+ defaultScreenOfDisplay, defaultVisual, defaultColormap, defaultDepth,+ whitePixel, blackPixel,+ copyArea, fillRectangle, fillPolygon, drawLine, drawPoint,+ nonconvex, coordModeOrigin, setLineAttributes, lineSolid, capRound, joinRound, setForeground, allocNamedColor, color_pixel,- allocaXEvent, pending, nextEvent,- setWMProtocols, selectInput, button1MotionMask, buttonReleaseMask,- buttonPressMask, keyPressMask, exposureMask,- pointerMotionMask,- buttonPress, buttonRelease, xK_VoidSymbol, getGeometry, drawPoint)-import qualified Graphics.X11 as X(fillPolygon)+ setWMProtocols, selectInput, allocaXEvent, pending, nextEvent,+ exposureMask, keyPressMask, buttonPressMask, buttonReleaseMask,+ pointerMotionMask, buttonPress, buttonRelease, xK_VoidSymbol) import Graphics.X11.Xlib.Extras(Event(..), getEvent) import Graphics.X11.Xft(- XftColor, xftDrawCreate, xftFontOpen, withXftColorValue,- withXftColorName, xftDrawString)+ xftDrawCreate, xftFontOpen, withXftColorValue, withXftColorName,+ xftDrawString) import Graphics.X11.Xrender(XRenderColor(..)) import Graphics.X11.Xim( XIC, XNInputStyle(..), openIM, createIC, getICValue, filterEvent, utf8LookupString)+import Graphics.Imlib(+ ImlibLoadError(..), loadImageWithErrorReturn, contextSetImage,+ imageGetWidth, imageGetHeight, imageGetData, createCroppedScaledImage) +import Numeric(showFFloat) import Control.Monad(forM_, replicateM) import Control.Monad.Tools(unlessM) import Control.Concurrent(ThreadId, forkIO, threadWaitRead)-import Data.Bits((.|.), shift)-import System.Locale.SetLocale(setLocale, Category(..))+import System.Locale.SetLocale(Category(..), setLocale) import System.Posix.Types(Fd(..))-import Numeric(showFFloat)--import Data.IORef+import Data.Word(Word32)+import Data.Bits((.|.), shift)+import Data.IORef(newIORef, readIORef) import Data.IORef.Tools(atomicModifyIORef_)-import Foreign.Ptr-import Foreign.Storable-import Foreign.Marshal.Array-import Data.Word-import Graphics.Imlib+import Foreign.Ptr(Ptr)+import Foreign.Storable(peek)+import Foreign.Marshal.Array(advancePtr) -------------------------------------------------------------------------------- -data Bufs = Bufs{- undoBuf :: Pixmap,- bgBuf :: Pixmap,- topBuf :: Pixmap}--data GCs = GCs{- gcForeground :: GC,- gcBackground :: GC}+data Bufs = Bufs{undoBuf :: Pixmap, bgBuf :: Pixmap, topBuf :: Pixmap}+data GCs = GCs{gcForeground :: GC, gcBackground :: GC} -------------------------------------------------------------------------------- @@ -129,11 +125,10 @@ fevent <- getICValue ic "filterEvents" [gc, gcBG] <- replicateM 2 $ createGC dpy win setForeground dpy gcBG 0xffffff- forM_ bufs $ \bf -> fillRectangle dpy bf gcBG 0 0 rWidth rHeight+ forM_ bufs $ \buf -> fillRectangle dpy buf gcBG 0 0 rWidth rHeight setWMProtocols dpy win [del] selectInput dpy win $ fevent .|. exposureMask .|. keyPressMask .|.- buttonPressMask .|. buttonReleaseMask .|. button1MotionMask .|.- pointerMotionMask+ buttonPressMask .|. buttonReleaseMask .|. pointerMotionMask size <- mapWindow dpy win >> windowSize dpy win return (dpy, win, Bufs ub bb tb, GCs gc gcBG, ic, del, size) @@ -144,76 +139,65 @@ -------------------------------------------------------------------------------- -getColorPixel :: Display -> Color -> IO (Maybe Pixel)-getColorPixel _ (RGB r g b) = return $ Just $ shift (fromIntegral r) 16 .|.+colorPixel :: Display -> Color -> IO (Maybe Pixel)+colorPixel _ (RGB r g b) = return $ Just $ shift (fromIntegral r) 16 .|. shift (fromIntegral g) 8 .|. fromIntegral b-getColorPixel dpy (ColorName cn) = fmap (Just . color_pixel . fst)- (allocNamedColor dpy (defaultColormap dpy $ defaultScreen dpy) cn) `catch`- const (putStrLn "no such color" >> return Nothing)+colorPixel dpy (ColorName cn) = fmap (Just . color_pixel . fst)+ (allocNamedColor dpy (defaultColormap dpy $ defaultScreen dpy) cn)+ `catch` const (putStrLn "no such color" >> return Nothing) -fillPolygon :: Display -> Drawable -> GC -> [Point] -> IO ()-fillPolygon d w gc ps = X.fillPolygon d w gc ps nonconvex coordModeOrigin+fillPolygonXT :: Display -> Drawable -> GC -> [Point] -> IO ()+fillPolygonXT d w gc ps = fillPolygon d w gc ps nonconvex coordModeOrigin drawLineXT :: Display -> GC -> Drawable -> Int -> Color -> Position -> Position -> Position -> Position -> IO ()-drawLineXT dpy gc bf lw c x1 y1 x2 y2 = do- getColorPixel dpy c >>= maybe (return ()) (setForeground dpy gc)+drawLineXT dpy gc buf lw c x1 y1 x2 y2 = do+ colorPixel dpy c >>= maybe (return ()) (setForeground dpy gc) setLineAttributes dpy gc (fromIntegral lw) lineSolid capRound joinRound- drawLine dpy bf gc x1 y1 x2 y2+ drawLine dpy buf gc x1 y1 x2 y2 writeStringXT :: Display -> Drawable -> String -> Double -> Color -> Position -> Position -> String -> IO () writeStringXT dpy buf fname size clr x y str = do- let scrN = defaultScreenOfDisplay dpy- visual = defaultVisual dpy $ defaultScreen dpy+ let visual = defaultVisual dpy $ defaultScreen dpy colormap = defaultColormap dpy $ defaultScreen dpy+ font = fname ++ "-" ++ showFFloat (Just 0) size "" xftDraw <- xftDrawCreate dpy buf visual colormap- xftFont <- xftFontOpen dpy scrN $- fname ++ "-" ++ showFFloat (Just 0) size ""- withXftColor dpy visual colormap clr $ \c ->- xftDrawString xftDraw c xftFont x y str--withXftColor ::- Display -> Visual -> Colormap -> Color -> (XftColor -> IO a) -> IO a-withXftColor dpy visual colormap (RGB r g b) action =- withXftColorValue dpy visual colormap color action- where- color = XRenderColor {- xrendercolor_red = fromIntegral r * 0x100,- xrendercolor_green = fromIntegral b * 0x100,- xrendercolor_blue = fromIntegral g * 0x100,- xrendercolor_alpha = 0xffff}-withXftColor dpy visual colormap (ColorName cn) action =- withXftColorName dpy visual colormap cn action------------------------------------------------------------------------------------waitEvent :: Display -> IO ()-waitEvent = threadWaitRead . Fd . connectionNumber--drawImage :: Display -> Drawable -> GC -> FilePath -> Position -> Position ->+ xftFont <- xftFontOpen dpy (defaultScreenOfDisplay dpy) font+ case clr of+ RGB r g b -> withXftColorValue dpy visual colormap color $ \c ->+ xftDrawString xftDraw c xftFont x y str+ where+ color = XRenderColor {+ xrendercolor_red = fromIntegral r * 0x100,+ xrendercolor_green = fromIntegral b * 0x100,+ xrendercolor_blue = fromIntegral g * 0x100,+ xrendercolor_alpha = 0xffff}+ ColorName cn -> withXftColorName dpy visual colormap cn $ \c ->+ xftDrawString xftDraw c xftFont x y str+ +drawImageXT :: Display -> Drawable -> GC -> FilePath -> Position -> Position -> Dimension -> Dimension -> IO ()-drawImage dpy win gc fp x y w h = getPicture fp w h >>=- maybe (return ()) (drawPicture dpy win gc x y)+drawImageXT dpy win gc fp x y w h =+ getImage fp w h >>= maybe (return ()) (drawBitmap dpy win gc x y w h) -getPicture :: FilePath -> Dimension -> Dimension ->- IO (Maybe (Dimension, Dimension, Ptr Word32))-getPicture fp nw nh = do+getImage :: FilePath -> Dimension -> Dimension -> IO (Maybe (Ptr Word32))+getImage fp nw nh = do (img, err) <- loadImageWithErrorReturn fp case err of ImlibLoadErrorNone -> do contextSetImage img- w <- fmap fromIntegral imageGetWidth- h <- fmap fromIntegral imageGetHeight- nimg <- createCroppedScaledImage (0 :: Int) (0 :: Int) (w :: Int) (h :: Int) nw nh- contextSetImage nimg- dat <- imageGetData- return $ Just (nw, nh, dat)+ let zero = 0 :: Int+ w <- fmap fromIntegral imageGetWidth :: IO Int+ h <- fmap fromIntegral imageGetHeight :: IO Int+ img' <- createCroppedScaledImage zero zero w h nw nh+ contextSetImage img'+ fmap Just imageGetData _ -> print err >> return Nothing -drawPicture :: Display -> Drawable -> GC -> Position -> Position ->- (Dimension, Dimension, Ptr Word32) -> IO ()-drawPicture dpy win gc x0 y0 (w, h, dat) = do+drawBitmap :: Display -> Drawable -> GC -> Position -> Position -> Dimension ->+ Dimension -> Ptr Word32 -> IO ()+drawBitmap dpy win gc x0 y0 w h dat = do ptr <- newIORef dat forM_ [0 .. w * h - 1] $ \i -> do readIORef ptr >>= peek >>= setForeground dpy gc@@ -221,3 +205,8 @@ y = fromIntegral i `div` w drawPoint dpy win gc (x0 + fromIntegral x) (y0 + fromIntegral y) atomicModifyIORef_ ptr $ flip advancePtr 1++--------------------------------------------------------------------------------++waitEvent :: Display -> IO ()+waitEvent = threadWaitRead . Fd . connectionNumber
xturtle.cabal view
@@ -2,7 +2,7 @@ cabal-version: >= 1.6 name: xturtle-version: 0.1.5+version: 0.1.6 stability: experimental author: Yoshikuni Jujo <PAF01143@nifty.ne.jp> maintainer: Yoshikuni Jujo <PAF01143@nifty.ne.jp>