diff --git a/src/Graphics/X11/Turtle.hs b/src/Graphics/X11/Turtle.hs
--- a/src/Graphics/X11/Turtle.hs
+++ b/src/Graphics/X11/Turtle.hs
@@ -49,16 +49,18 @@
 	windowWidth,
 	windowHeight,
 	onclick,
+	onkeypress,
 	waitField,
 
-	xturtleVersion
+	xturtleVersion,
+	write
 ) where
 
 import Graphics.X11.TurtleMove(
 	Field, Layer, Character,
 	forkIOX, openField, closeField,
 	addCharacter, addLayer, fieldSize, clearLayer, clearCharacter,
-	addThread, fieldColor, onclick, waitField,
+	addThread, fieldColor, onclick, onkeypress, waitField, Color(..),
 	moveTurtle
  )
 import Graphics.X11.TurtleInput(
@@ -72,11 +74,10 @@
 import Prelude hiding(Left)
 import Data.IORef(IORef, newIORef, readIORef, modifyIORef)
 import Data.Bits(shift, (.|.))
-import Data.Word(Word8)
 import Data.Fixed(mod')
 
 xturtleVersion :: (Int, String)
-xturtleVersion = (21, "0.0.12")
+xturtleVersion = (24, "0.0.13")
 
 data Turtle = Turtle {
 	field :: Field,
@@ -172,17 +173,14 @@
 penup = flip sendCommand Penup
 pendown = flip sendCommand Pendown
 
-pencolor :: Turtle -> Word8 -> Word8 -> Word8 -> IO ()
-pencolor t r_ g_ b_ = sendCommand t $ Pencolor c
-	where
-	c = shift r 16 .|. shift g 8 .|. b
-	[r, g, b] = map fromIntegral [r_, g_, b_]
+pencolor :: Turtle -> Double -> Double -> Double -> IO ()
+pencolor t r_ g_ b_ = sendCommand t $ Pencolor r_ g_ b_ -- c
 
-bgcolor :: Field -> Word8 -> Word8 -> Word8 -> IO ()
-bgcolor f r_ g_ b_ = fieldColor f c
+bgcolor :: Field -> Double -> Double -> Double -> IO ()
+bgcolor f r_ g_ b_ = fieldColor f $ Color c
 	where
 	c = shift r 16 .|. shift g 8 .|. b
-	[r, g, b] = map fromIntegral [r_, g_, b_]
+	[r, g, b] = map (round . (* 255)) [r_, g_, b_]
 
 pensize :: Turtle -> Double -> IO ()
 pensize t = sendCommand t . Pensize
@@ -192,6 +190,9 @@
 
 radians :: Turtle -> IO ()
 radians = flip degrees $ 2 * pi
+
+write :: Turtle -> String -> Double -> String -> IO ()
+write t fnt sz = sendCommand t . Write fnt sz
 
 undo :: Turtle -> IO ()
 undo t = readIORef (stateIndex t)
diff --git a/src/Graphics/X11/TurtleField.hs b/src/Graphics/X11/TurtleField.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/X11/TurtleField.hs
@@ -0,0 +1,470 @@
+module Graphics.X11.TurtleField(
+	Field,
+	Layer,
+	Character,
+
+	openField,
+	closeField,
+	waitField,
+	fieldColor,
+	fieldSize,
+
+	addLayer,
+	addCharacter,
+
+	drawLine,
+	drawLineNotFlush,
+	writeString,
+	drawCharacter,
+	drawCharacterAndLine,
+	clearCharacter,
+
+	undoLayer,
+	clearLayer,
+	flushLayer,
+
+	onclick,
+	onkeypress,
+
+	forkIOX,
+	addThread,
+
+	Color(..)
+) where
+
+import Graphics.X11(
+	Display, Window, Pixmap, Atom, GC, Point(..), Dimension, Position, Pixel,
+
+	setLineAttributes, lineSolid, capRound, joinRound,
+
+	openDisplay, closeDisplay, flush, defaultScreen, rootWindow,
+	whitePixel, blackPixel,	defaultDepth,
+	createSimpleWindow, mapWindow, createPixmap, internAtom, createGC,
+
+	setForeground, copyArea,
+	fillRectangle, fillPolygon, nonconvex, coordModeOrigin,
+
+	setWMProtocols, selectInput, allocaXEvent, nextEvent, XEventPtr,
+	keyPressMask, exposureMask, buttonPressMask,
+
+	getGeometry, initThreads, connectionNumber, pending, destroyWindow,
+
+	defaultVisual, defaultColormap, defaultScreenOfDisplay,
+
+	supportsLocale, setLocaleModifiers,
+	xK_VoidSymbol
+ )
+import qualified Graphics.X11 as X (drawLine)
+import Graphics.X11.Xlib.Extras(Event(..), getEvent)
+import Graphics.X11.Xft
+import Graphics.X11.Xrender
+import Graphics.X11.Xim
+
+import Data.IORef(IORef, newIORef, readIORef, writeIORef, modifyIORef)
+import Data.Bits((.|.))
+import Data.Convertible(convert)
+import Data.List.Tools(modifyAt, setAt)
+import Data.Bool.Tools(whether)
+import Data.Maybe
+
+import Control.Monad(replicateM, forM_, forever, replicateM_, when, unless)
+import Control.Monad.Tools(doWhile_, whenM, unlessM)
+import Control.Arrow((***))
+import Control.Concurrent(
+	forkIO, ThreadId, Chan, newChan, writeChan, readChan, threadWaitRead,
+	killThread)
+
+import System.Posix.Types
+import System.Locale.SetLocale
+import Foreign.C.Types
+
+data Color = Color {pixel :: Pixel}
+
+colorToPixel :: Color -> Pixel
+colorToPixel = pixel
+
+data Field = Field{
+	fDisplay :: Display,
+	fWindow :: Window,
+	fGC :: GC,
+	fGCBG :: GC,
+	fDel :: Atom,
+	fUndoBuf :: Pixmap,
+	fBG :: Pixmap,
+	fBuf :: Pixmap,
+	fWidth :: IORef Dimension,
+	fHeight :: IORef Dimension,
+	fBuffed :: IORef [IO ()],
+	fLayers :: IORef [[Bool -> IO ()]],
+	fCharacters :: IORef [IO ()],
+	fWait :: Chan (),
+	fEvent :: Chan (Maybe Event),
+	fClose :: Chan (),
+	fClosed :: IORef Bool,
+	fRunning :: IORef [ThreadId],
+	fOnclick :: IORef (Double -> Double -> IO Bool),
+	fKeypress :: IORef (Char -> IO Bool),
+	fEnd :: Chan ()
+ }
+
+data Layer = Layer{
+	layerField :: Field,
+	layerId :: Int
+ }
+
+data Character = Character{
+	characterField :: Field,
+	characterId :: Int
+ }
+
+openField :: IO Field
+openField = do
+	setLocale LC_CTYPE Nothing >>= maybe (error "Can't set locale.") print
+	_ <- initThreads
+	unlessM supportsLocale $ error "Current locale is notSupported."
+	_ <- setLocaleModifiers ""
+	dpy <- openDisplay ""
+	del <- internAtom dpy "WM_DELETE_WINDOW" True
+	let	scr = defaultScreen dpy
+	root <- rootWindow dpy scr
+	(_, _, _, rWidth, rHeight, _, _) <- getGeometry dpy root
+	let	black = blackPixel dpy scr
+		white = whitePixel dpy scr
+		depth = defaultDepth dpy scr
+	bufs <- replicateM 3 $ createPixmap dpy root rWidth rHeight depth
+	win <- createSimpleWindow dpy root 0 0 rWidth rHeight 1 black white
+	im <- openIM dpy Nothing Nothing Nothing
+	ic <- createIC im [XIMPreeditNothing, XIMStatusNothing] win
+	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
+	setWMProtocols dpy win [del]
+	selectInput dpy win $ exposureMask .|. keyPressMask .|. buttonPressMask .|. fevent
+	mapWindow dpy win
+	[widthRef, heightRef] <- mapM newIORef [rWidth, rHeight]
+	buffActions <- newIORef []
+	layerActions <- newIORef []
+	characterActions <- newIORef []
+	wait <- newChan
+	event <- newChan
+	close <- newChan
+	closed <- newIORef False
+	running <- newIORef []
+	onclickRef <- newIORef $ const $ const $ return True
+	keypressRef <- newIORef $ const $ return True
+	endRef <- newChan
+	writeChan wait ()
+	let f = Field{
+		fDisplay = dpy,
+		fWindow = win,
+		fGC = gc,
+		fGCBG = gcBG,
+		fDel = del,
+		fUndoBuf = head bufs,
+		fBG = bufs !! 1,
+		fBuf = bufs !! 2,
+		fWidth = widthRef,
+		fHeight = heightRef,
+		fBuffed = buffActions,
+		fLayers = layerActions,
+		fCharacters = characterActions,
+		fWait = wait,
+		fEvent = event,
+		fClose = close,
+		fClosed = closed,
+		fRunning = running,
+		fOnclick = onclickRef,
+		fKeypress = keypressRef,
+		fEnd = endRef
+	 }
+	_ <- forkIOX $ runLoop ic f
+	flushWindow f
+	return f
+
+runLoop :: XIC -> Field -> IO ()
+runLoop ic f = allocaXEvent $ \e -> do
+	endc <- waitInput f
+	th1 <- forkIOX $ forever $ do
+		evN <- pending $ fDisplay f
+		replicateM_ (fromIntegral evN) $ do
+			nextNotFilteredEvent (fDisplay f) e
+			ev <- getEvent e
+			writeChan (fEvent f) $ Just ev
+		end <- readChan endc
+		when end $ writeChan (fEvent f) Nothing
+	(>> (closeDisplay (fDisplay f) >> writeChan (fEnd f) ())) $
+		(>> destroyWindow (fDisplay f) (fWindow f)) $ doWhile_ $ do
+		mev <- readChan $ fEvent f
+		case mev of
+			Just (ExposeEvent{}) -> do
+				(_, _, _, width, height, _, _) <-
+					getGeometry (fDisplay f) (fWindow f)
+				writeIORef (fWidth f) width
+				writeIORef (fHeight f) height
+				redrawAll f
+				return True
+			Just (KeyEvent{}) -> do
+				(mstr, mks) <- utf8LookupString ic e
+				let	str = fromMaybe " " mstr
+					_ks = fromMaybe xK_VoidSymbol mks
+				readIORef (fKeypress f) >>= fmap and . ($ str) . mapM
+			Just ev@ButtonEvent{} -> do
+				pos <- convertPosRev f (ev_x ev) (ev_y ev)
+				readIORef (fOnclick f) >>= ($ pos) . uncurry
+			Just ev@ClientMessageEvent{} ->
+				return $ convert (head $ ev_data ev) /= fDel f
+			Nothing -> killThread th1 >> return False
+			_ -> return True
+
+onclick :: Field -> (Double -> Double -> IO Bool) -> IO ()
+onclick f = writeIORef $ fOnclick f
+
+onkeypress :: Field -> (Char -> IO Bool) -> IO ()
+onkeypress f = writeIORef $ fKeypress f
+
+fieldColor :: Field -> Color -> IO ()
+fieldColor f clr = do
+	setForeground (fDisplay f) (fGCBG f) $ colorToPixel clr
+	let bufs = [fUndoBuf f, fBG f, fBuf f]
+	width <- readIORef $ fWidth f
+	height <- readIORef $ fHeight f
+	forM_ bufs $ \bf -> fillRectangle (fDisplay f) bf (fGCBG f) 0 0 width height
+	redrawAll f
+
+getConnection :: Field -> Fd
+getConnection = Fd . connectionNumber . fDisplay
+
+waitInput :: Field -> IO (Chan Bool)
+waitInput f = do
+	c <- newChan
+	_ <- forkIOX $ forever $ do
+		threadWaitRead $ getConnection f
+		writeChan c False
+	_ <- forkIO $ do
+		readChan $ fClose f
+		writeChan c True
+	return c
+
+closeField :: Field -> IO ()
+closeField f = do
+	readIORef (fRunning f) >>= mapM_ killThread
+	writeChan (fClose f) ()
+	writeIORef (fClosed f) True
+
+addThread :: Field -> ThreadId -> IO ()
+addThread f tid = modifyIORef (fRunning f) (tid :)
+
+flushLayer :: Layer -> IO ()
+flushLayer = flushWindow . layerField
+
+addLayer :: Field -> IO Layer
+addLayer f = do
+	ls <- readIORef $ fLayers f
+	writeIORef (fLayers f) (ls ++ [[]])
+	modifyIORef (fBuffed f) (++ [return ()])
+	return Layer{layerField = f, layerId = length ls}
+
+addCharacter :: Field -> IO Character
+addCharacter f = do
+	cs <- readIORef $ fCharacters f
+	writeIORef (fCharacters f) (cs ++ [return ()])
+	return Character{characterField = f, characterId = length cs}
+
+runIfOpened :: Field -> IO a -> IO ()
+runIfOpened f act = do
+	cl <- readIORef $ fClosed f
+	unless cl $ act >> return ()
+
+drawLineNotFlush ::
+	Layer -> Double -> Color -> Double -> Double -> Double -> Double -> IO ()
+drawLineNotFlush l@Layer{layerField = f} lw_ clr x1 y1 x2 y2 = runIfOpened f $ do
+	drawLineBuf f lw clr fBG x1 y1 x2 y2
+	addLayerAction l $ whether
+		(drawLineBuf f lw clr fUndoBuf x1 y1 x2 y2)
+		(drawLineBuf f lw clr fBG x1 y1 x2 y2)
+	where
+	lw = round lw_
+
+drawLine :: Layer -> Double -> Color -> Double -> Double -> Double -> Double -> IO ()
+drawLine l@Layer{layerField = f} lw_ clr x1 y1 x2 y2 = runIfOpened f $ do
+	drawLineBuf f lw clr fBG x1 y1 x2 y2 >> redrawCharacters f
+	addLayerAction l $ whether
+		(drawLineBuf f lw clr fUndoBuf x1 y1 x2 y2)
+		(drawLineBuf f lw clr fBG x1 y1 x2 y2)
+	where
+	lw = round lw_
+
+writeString :: Layer -> String -> Double -> Double -> Double -> Double ->
+	Double -> Double -> String -> IO ()
+writeString l@Layer{layerField = f} fname size r g b x y str = do
+	writeStringBuf f fBG fname size r g b x y str
+	redrawCharacters f
+	addLayerAction l $ whether
+		(writeStringBuf f fUndoBuf fname size r g b x y str)
+		(writeStringBuf f fBG fname size r g b x y str)
+
+writeStringBuf :: Field -> (Field -> Pixmap) -> String -> Double -> Double -> Double -> Double ->
+	Double -> Double -> String -> IO ()
+writeStringBuf f buf fname size r g b x_ y_ str = do
+	let	dpy = fDisplay f
+		scr = defaultScreen dpy
+		scrN = defaultScreenOfDisplay dpy
+		visual = defaultVisual dpy scr
+		colormap = defaultColormap dpy scr
+	xftDraw <- xftDrawCreate dpy (buf f) visual colormap
+	xftFont <- xftFontOpen dpy scrN $ fname ++ "-" ++ show (round size :: Int) -- "KochiGothic-20"
+	[(x, y)] <- convertPos f [(x_, y_)]
+	withXftColorValue dpy visual colormap color $ \c ->
+		xftDrawString xftDraw c xftFont x y str
+	where
+	color = XRenderColor {
+		xrendercolor_red = round $ r * 0xffff,
+		xrendercolor_green = round $ b * 0xffff,
+		xrendercolor_blue = round $ g * 0xffff,
+		xrendercolor_alpha = 0xffff
+	 }
+
+clearCharacter :: Character -> IO ()
+clearCharacter c = runIfOpened (characterField c) $
+	setCharacter c $ return ()
+
+drawCharacter :: Character -> Color -> [(Double, Double)] -> IO ()
+drawCharacter c@Character{characterField = f} clr sh =
+	runIfOpened (characterField c) $ setCharacter c $ do
+		setForeground (fDisplay f) (fGC f) $ colorToPixel clr
+		fillPolygonBuf (characterField c) sh
+
+drawCharacterAndLine ::	Character -> Color -> [(Double, Double)] -> Double ->
+	Double -> Double -> Double -> Double -> IO ()
+drawCharacterAndLine c@Character{characterField = f} clr ps lw_ x1 y1 x2 y2 =
+	runIfOpened f $ setCharacter c $ do
+		setForeground (fDisplay f) (fGC f) $ colorToPixel clr
+		fillPolygonBuf f ps >> drawLineBuf f lw clr fBuf x1 y1 x2 y2
+	where
+	lw = round lw_
+
+undoLayer :: Layer -> IO Bool
+undoLayer Layer{layerField = f, layerId = lid} = do
+	ls <- readIORef $ fLayers f
+	if null $ ls !! lid then return False else do
+		writeIORef (fLayers f) $ modifyAt ls lid init
+		redraw f
+		return True
+
+clearLayer :: Layer -> IO ()
+clearLayer Layer{layerField = f, layerId = lid} = do
+	ls <- readIORef $ fLayers f
+	writeIORef (fLayers f) $ setAt ls lid []
+	buffed <- readIORef $ fBuffed f
+	writeIORef (fBuffed f) $ setAt buffed lid $ return ()
+	redrawBuf f
+	redraw f
+
+forkIOX :: IO () -> IO ThreadId
+forkIOX = (initThreads >>) . forkIO
+
+--------------------------------------------------------------------------------
+
+undoN :: Int
+undoN = 100
+
+addLayerAction :: Layer -> (Bool -> IO ()) -> IO ()
+addLayerAction Layer{layerField = f, layerId = lid} act = do
+	ls <- readIORef $ fLayers f
+	if length (ls !! lid) > undoN
+		then do	head (ls !! lid) True
+			buffed <- readIORef $ fBuffed f
+			writeIORef (fBuffed f) $ 
+				modifyAt buffed lid (>> head (ls !! lid) True)
+			writeIORef (fLayers f) $
+				modifyAt ls lid $ (++ [act]) . tail
+		else writeIORef (fLayers f) $ modifyAt ls lid (++ [act])
+
+setCharacter :: Character -> IO () -> IO ()
+setCharacter Character{characterField = f, characterId = cid} act = do
+	cs <- readIORef $ fCharacters f
+	writeIORef (fCharacters f) $ setAt cs cid act
+	redrawCharacters f
+	flushWindow f
+
+fillPolygonBuf :: Field -> [(Double, Double)] -> IO ()
+fillPolygonBuf f ps_ = do
+	ps <- convertPos f ps_
+	fillPolygon (fDisplay f) (fBuf f) (fGC f) (map (uncurry Point) ps)
+		nonconvex coordModeOrigin
+
+drawLineBuf :: Field -> Int -> Color -> (Field -> Pixmap) ->
+	Double -> Double -> Double -> Double -> IO ()
+drawLineBuf f@Field{fDisplay = dpy, fGC = gc} lw clr bf x1_ y1_ x2_ y2_ = do
+	setForeground (fDisplay f) (fGC f) $ colorToPixel clr
+	setLineAttributes (fDisplay f) (fGC f) (fromIntegral lw) lineSolid capRound joinRound
+	[(x1, y1), (x2, y2)] <- convertPos f [(x1_, y1_), (x2_, y2_)]
+	X.drawLine dpy (bf f) gc x1 y1 x2 y2
+
+convertPos :: Field -> [(Double, Double)] -> IO [(Position, Position)]
+convertPos f ps = do
+	(width, height) <- fieldSize f
+	return $ (round . (+ width / 2) *** round . (+ height / 2) . negate)
+		`map` ps
+
+convertPosRev :: Field -> CInt -> CInt -> IO (Double, Double)
+convertPosRev f x y = do
+	(width, height) <- fieldSize f
+	return (fromIntegral x - width / 2, fromIntegral (- y) + height / 2)
+
+fieldSize :: Field -> IO (Double, Double)
+fieldSize w = fmap (fromIntegral *** fromIntegral) $ winSize w
+
+winSize :: Field -> IO (Dimension, Dimension)
+winSize f = do
+	width <- readIORef $ fWidth f
+	height <- readIORef $ fHeight f
+	return (width, height)
+
+redrawAll :: Field -> IO ()
+redrawAll f = do
+	redrawBuf f
+	redraw f
+	flushWindow f
+
+redrawBuf :: Field -> IO ()
+redrawBuf f = do
+	winSize f >>=
+		uncurry (fillRectangle (fDisplay f) (fUndoBuf f) (fGCBG f) 0 0)
+	readIORef (fBuffed f) >>= sequence_
+
+redraw :: Field -> IO ()
+redraw = withLock $ \f -> do
+	(width, height) <- winSize f
+	copyArea (fDisplay f) (fUndoBuf f) (fBG f) (fGC f) 0 0 width height 0 0
+	readIORef (fLayers f) >>= mapM_ ($ False) . concat
+	copyArea (fDisplay f) (fBG f) (fBuf f) (fGC f) 0 0 width height 0 0
+	readIORef (fCharacters f) >>= sequence_
+
+redrawCharacters :: Field -> IO ()
+redrawCharacters = withLock $ \f -> do
+	(width, height) <- winSize f
+	copyArea (fDisplay f) (fBG f) (fBuf f) (fGC f) 0 0 width height 0 0
+	readIORef (fCharacters f) >>= sequence_
+
+flushWindow :: Field -> IO ()
+flushWindow = withLock $ \f -> do
+	(width, height) <- winSize f
+	copyArea (fDisplay f) (fBuf f) (fWindow f) (fGC f) 0 0 width height 0 0
+	flush $ fDisplay f
+
+withLock :: (Field -> IO a) -> Field -> IO a
+withLock act f = do
+	readChan $ fWait f
+	ret <- act f
+	writeChan (fWait f) ()
+	return ret
+
+waitField :: Field -> IO ()
+waitField = readChan . fEnd
+
+nextNotFilteredEvent :: Display -> XEventPtr -> IO ()
+nextNotFilteredEvent dpy e = do
+	nextEvent dpy e
+	whenM (filterEvent e 0) $ nextNotFilteredEvent dpy e
diff --git a/src/Graphics/X11/TurtleInput.hs b/src/Graphics/X11/TurtleInput.hs
--- a/src/Graphics/X11/TurtleInput.hs
+++ b/src/Graphics/X11/TurtleInput.hs
@@ -11,7 +11,8 @@
 	degrees
 ) where
 
-import Graphics.X11.TurtleState(TurtleState(..), initialTurtleState, Color)
+import Graphics.X11.TurtleState(TurtleState(..), initialTurtleState, pencolor,
+	Draw(..))
 import Control.Concurrent.Chan(Chan, newChan, getChanContents)
 import Prelude hiding(Left)
 
@@ -34,9 +35,10 @@
 	| Forward Double
 	| Left Double
 	| Undonum Int
-	| Pencolor Color
+	| Pencolor Double Double Double
 	| Pensize Double
 	| Degrees Double
+	| Write String Double String
 	deriving Show
 
 getTurtleStates :: [(Double, Double)] -> IO (Chan TurtleInput, [TurtleState])
@@ -50,24 +52,28 @@
 nextTurtle t (Shape sh) = (clearState t){shape = sh}
 nextTurtle t (ShapeSize ss) = (clearState t){shapesize = ss}
 nextTurtle t (Goto x y) = (clearState t){position = (x, y), line = pendown t,
-	drawed = if pendown t then (pencolor t, pensize t, position t, (x, y))
-		: drawed t else drawed t} 
+	drawed = if pendown t
+		then Line (pencolor t) (pensize t) (position t) (x, y) : drawed t else drawed t} 
 nextTurtle t (Rotate d) = (clearState t){direction = d}
 nextTurtle t Pendown = (clearState t){pendown = True}
 nextTurtle t Penup = (clearState t){pendown = False}
 nextTurtle t (SetVisible v) = (clearState t){visible = v}
 nextTurtle t (Undonum un) = (clearState t){undonum = un}
 nextTurtle t (Clear) = (clearState t){clear = True, drawed = []}
-nextTurtle t (Pencolor c) = (clearState t){pencolor = c}
+nextTurtle t (Pencolor r g b) = (clearState t){red = r, green = g, blue = b}-- setPencolor (clearState t) c
 nextTurtle t (Pensize ps) = (clearState t){pensize = ps}
 nextTurtle t (Degrees ds) = (clearState t){
 	degrees = ds,
 	direction = direction t * ds / degrees t
  }
+nextTurtle t (Write fnt sz str) = (clearState t){
+	draw = Str (red t, green t, blue t) fnt sz (position t) str,
+	drawed = Str (red t, green t, blue t) fnt sz (position t) str : drawed t
+ }
 nextTurtle _ _ = error "not defined"
 
 clearState :: TurtleState -> TurtleState
-clearState t = t{line = False, undo = False, undonum = 1, clear = False}
+clearState t = t{line = False, undo = False, undonum = 1, clear = False, draw = NoDraw}
 
 inputToTurtle :: [TurtleState] -> TurtleState -> [TurtleInput] -> [TurtleState]
 inputToTurtle [] ts0 (Undo : tis) = ts0 : inputToTurtle [] ts0 tis
diff --git a/src/Graphics/X11/TurtleMove.hs b/src/Graphics/X11/TurtleMove.hs
--- a/src/Graphics/X11/TurtleMove.hs
+++ b/src/Graphics/X11/TurtleMove.hs
@@ -14,20 +14,23 @@
 	addThread,
 	fieldColor,
 	onclick,
+	onkeypress,
 	waitField,
+	writeString,
+	Color(..),
 
 	moveTurtle
 ) where
 
-import Graphics.X11.TurtleState(TurtleState(..), Color)
-import Graphics.X11.WindowLayers(
+import Graphics.X11.TurtleState(TurtleState(..), pencolor, Draw(..))
+import Graphics.X11.TurtleField(
 	Field, Layer, Character,
 	forkIOX, openField, closeField, flushLayer,
 	addLayer, addCharacter, fieldSize, clearLayer,
 	drawLine, drawCharacter, drawCharacterAndLine, undoLayer,
 	drawLineNotFlush,
 	clearCharacter, addThread,
-	fieldColor, onclick, waitField
+	fieldColor, onkeypress, onclick, waitField, writeString, Color(..)
  )
 
 import Control.Concurrent(threadDelay)
@@ -53,34 +56,39 @@
 
 moveTurtle :: Character -> Layer -> TurtleState -> TurtleState -> IO ()
 moveTurtle c l t0 t1 = do
-	when (undo t1 && line t0) $ do
+	when (undo t1 && (line t0 || draw t0 /= NoDraw)) $ do
 		done <- undoLayer l
 		unless done $ clearLayer l >> drawLines l (drawed t1)
 	when (undo t1 && clear t0) $ drawLines l $ drawed t1
 	when (visible t1) $ do
 		forM_ (getDirections (dir t0) (dir t1)) $ \d -> do
-			drawTurtle c (pencolor t1) (shape t1) (shapesize t1) d
+			drawTurtle c (Color $ pencolor t1) (shape t1) (shapesize t1) d
 				(pensize t1) p0 Nothing
 			threadDelay rotateSpeed
 		forM_ (getPositions x0 y0 x1 y1) $ \p -> do
-			drawTurtle c (pencolor t1) (shape t1) (shapesize t1)
+			drawTurtle c (Color $ pencolor t1) (shape t1) (shapesize t1)
 				(dir t1) (pensize t1) p lineOrigin
 			threadDelay moveSpeed
-		drawTurtle c (pencolor t1) (shape t1) (shapesize t1) (dir t1)
+		drawTurtle c (Color $ pencolor t1) (shape t1) (shapesize t1) (dir t1)
 			(pensize t1) p1 lineOrigin
 	unless (visible t1) $ clearCharacter c
 	when (not (undo t1) && line t1) $
-		drawLine l (pensize t1) (pencolor t1) x0 y0 x1 y1 >> flushLayer l
+		drawLine l (pensize t1) (Color $ pencolor t1) x0 y0 x1 y1 >> flushLayer l
 	when (clear t1) $ clearLayer l >> flushLayer l
+	unless (undo t1) $ drawDraw l (draw t1) >> flushLayer l
 	where
 	(tl, to) = if undo t1 then (t0, t1) else (t1, t0)
 	lineOrigin = if line tl then Just $ position to else Nothing
 	p0@(x0, y0) = position t0
 	p1@(x1, y1) = position t1
 
-drawLines :: Layer -> [(Color, Double, (Double, Double), (Double, Double))] -> IO ()
-drawLines l ls =
-	mapM_ (\(clr, lw, (x0, y0), (x1, y1)) -> drawLineNotFlush l lw clr x0 y0 x1 y1) $ reverse ls
+drawLines :: Layer -> [Draw] -> IO ()
+drawLines l = mapM_ (drawDraw l) . reverse
+
+drawDraw :: Layer -> Draw -> IO ()
+drawDraw _ NoDraw = return ()
+drawDraw l (Line clr lw (x0, y0) (x1, y1)) = drawLineNotFlush l lw (Color clr) x0 y0 x1 y1
+drawDraw l (Str (r, g, b) fnt sz (x, y) str) = writeString l fnt sz r g b x y str
 
 getPositions :: Double -> Double -> Double -> Double -> [Pos]
 getPositions x0 y0 x1 y1 = take num $ zip [x0, x0 + dx .. ] [y0, y0 + dy .. ]
diff --git a/src/Graphics/X11/TurtleState.hs b/src/Graphics/X11/TurtleState.hs
--- a/src/Graphics/X11/TurtleState.hs
+++ b/src/Graphics/X11/TurtleState.hs
@@ -1,20 +1,57 @@
 module Graphics.X11.TurtleState (
 	TurtleState(..),
 	initialTurtleState,
-	Color
+	Color,
+	pencolor,
+	setPencolor,
+	Draw(..)
 ) where
 
 import Data.Word(Word32)
+import Data.Bits
 
 type Color = Word32
 
+data Draw
+	= NoDraw
+	| Line{
+		color :: Color,
+		width :: Double,
+		begin :: (Double, Double),
+		end :: (Double, Double)
+	 }
+	| Str{
+		scolor :: (Double, Double, Double),
+		font :: String,
+		size :: Double,
+		pos :: (Double, Double),
+		contents :: String
+	 }
+	deriving (Show, Eq)
+
+pencolor :: TurtleState -> Word32
+pencolor t = c
+	where
+	c = shift (round $ red t * 0xff) 16 .|.
+		shift (round $ green t * 0xff) 8 .|. round (blue t * 0xff)
+
+setPencolor :: TurtleState -> Word32 -> TurtleState
+setPencolor t c = t{red = r, green = g, blue = b}
+	where
+	r_ = shiftR c 16 .&. 0xff
+	g_ = shiftR c 8 .&. 0xff
+	b_ = c .&. 0xff
+	[r, g, b] = map ((/ 0xff) . fromIntegral) [r_, g_, b_]
+
 data TurtleState = TurtleState {
 	position :: (Double, Double),
 	direction :: Double,
 	degrees :: Double,
 	pendown :: Bool,
 	pensize :: Double,
-	pencolor :: Color,
+	red :: Double,
+	green :: Double,
+	blue :: Double,
 	shape :: [(Double, Double)],
 	shapesize :: Double,
 	visible :: Bool,
@@ -22,7 +59,8 @@
 	undo :: Bool,
 	line :: Bool,
 	undonum :: Int,
-	drawed :: [(Color, Double, (Double, Double), (Double, Double))]
+	draw :: Draw,
+	drawed :: [Draw]
  } deriving Show
 
 initialTurtleState :: [(Double, Double)] -> TurtleState
@@ -32,7 +70,9 @@
 	degrees = 360,
 	pendown = True,
 	pensize = 0,
-	pencolor = 0x000000,
+	red = 0,
+	green = 0,
+	blue = 0,
 	shape = sh,
 	shapesize = 1,
 	visible = True,
@@ -40,5 +80,6 @@
 	undo = False,
 	line = False,
 	undonum = 1,
+	draw = NoDraw,
 	drawed = []
  }
diff --git a/src/Graphics/X11/WindowLayers.hs b/src/Graphics/X11/WindowLayers.hs
deleted file mode 100644
--- a/src/Graphics/X11/WindowLayers.hs
+++ /dev/null
@@ -1,401 +0,0 @@
-module Graphics.X11.WindowLayers(
-	Field,
-	Layer,
-	Character,
-
-	openField,
-	closeField,
-	waitField,
-	fieldColor,
-	fieldSize,
-
-	addLayer,
-	addCharacter,
-
-	drawLine,
-	drawLineNotFlush,
-	drawCharacter,
-	drawCharacterAndLine,
-	clearCharacter,
-
-	undoLayer,
-	clearLayer,
-	flushLayer,
-
-	onclick,
-
-	forkIOX,
-	addThread
-) where
-
-import Graphics.X11(
-	Display, Window, Pixmap, Atom, GC, Point(..), Dimension, Position, Pixel,
-
-	setLineAttributes, lineSolid, capRound, joinRound,
-
-	openDisplay, closeDisplay, flush, defaultScreen, rootWindow,
-	whitePixel, blackPixel,	defaultDepth,
-	createSimpleWindow, mapWindow, createPixmap, internAtom, createGC,
-
-	setForeground, copyArea,
-	fillRectangle, fillPolygon, nonconvex, coordModeOrigin,
-
-	setWMProtocols, selectInput, allocaXEvent, nextEvent,
-	keyPressMask, exposureMask, buttonPressMask,
-
-	getGeometry, initThreads, connectionNumber, pending, destroyWindow
- )
-import qualified Graphics.X11 as X (drawLine)
-import Graphics.X11.Xlib.Extras(Event(..), getEvent)
-
-import Data.IORef(IORef, newIORef, readIORef, writeIORef, modifyIORef)
-import Data.Bits((.|.))
-import Data.Convertible(convert)
-import Data.List.Tools(modifyAt, setAt)
-import Data.Bool.Tools(whether)
-
-import Control.Monad(replicateM, forM_, forever, replicateM_, when)
-import Control.Monad.Tools(doWhile_)
-import Control.Arrow((***))
-import Control.Concurrent(
-	forkIO, ThreadId, Chan, newChan, writeChan, readChan, threadWaitRead,
-	killThread, threadDelay)
-
-import System.Posix.Types
-import Foreign.C.Types
-
-data Field = Field{
-	fDisplay :: Display,
-	fWindow :: Window,
-	fGC :: GC,
-	fGCBG :: GC,
-	fDel :: Atom,
-	fUndoBuf :: Pixmap,
-	fBG :: Pixmap,
-	fBuf :: Pixmap,
-	fWidth :: IORef Dimension,
-	fHeight :: IORef Dimension,
-	fBuffed :: IORef [IO ()],
-	fLayers :: IORef [[Bool -> IO ()]],
-	fCharacters :: IORef [IO ()],
-	fWait :: Chan (),
-	fEvent :: Chan (Maybe Event),
-	fClose :: Chan (),
-	fClosed :: IORef Bool,
-	fRunning :: IORef [ThreadId],
-	fOnclick :: IORef (Double -> Double -> IO Bool),
-	fEnd :: Chan ()
- }
-
-data Layer = Layer{
-	layerField :: Field,
-	layerId :: Int
- }
-
-data Character = Character{
-	characterField :: Field,
-	characterId :: Int
- }
-
-openField :: IO Field
-openField = do
-	_ <- initThreads
-	dpy <- openDisplay ""
-	del <- internAtom dpy "WM_DELETE_WINDOW" True
-	let	scr = defaultScreen dpy
-	root <- rootWindow dpy scr
-	(_, _, _, rWidth, rHeight, _, _) <- getGeometry dpy root
-	let	black = blackPixel dpy scr
-		white = whitePixel dpy scr
-		depth = defaultDepth dpy scr
-	bufs <- replicateM 3 $ createPixmap dpy root rWidth rHeight depth
-	win <- createSimpleWindow dpy root 0 0 rWidth rHeight 1 black white
-	[gc, gcBG] <- replicateM 2 $ createGC dpy win
-	setForeground dpy gcBG 0xffffff
-	forM_ bufs $ \bf -> fillRectangle dpy bf gcBG 0 0 rWidth rHeight
-	setWMProtocols dpy win [del]
-	selectInput dpy win $ exposureMask .|. keyPressMask .|. buttonPressMask
-	mapWindow dpy win
-	[widthRef, heightRef] <- mapM newIORef [rWidth, rHeight]
-	buffActions <- newIORef []
-	layerActions <- newIORef []
-	characterActions <- newIORef []
-	wait <- newChan
-	event <- newChan
-	close <- newChan
-	closed <- newIORef False
-	running <- newIORef []
-	onclickRef <- newIORef $ const $ const $ return True
-	endRef <- newChan
-	writeChan wait ()
-	let f = Field{
-		fDisplay = dpy,
-		fWindow = win,
-		fGC = gc,
-		fGCBG = gcBG,
-		fDel = del,
-		fUndoBuf = head bufs,
-		fBG = bufs !! 1,
-		fBuf = bufs !! 2,
-		fWidth = widthRef,
-		fHeight = heightRef,
-		fBuffed = buffActions,
-		fLayers = layerActions,
-		fCharacters = characterActions,
-		fWait = wait,
-		fEvent = event,
-		fClose = close,
-		fClosed = closed,
-		fRunning = running,
-		fOnclick = onclickRef,
-		fEnd = endRef
-	 }
-	_ <- forkIOX $ runLoop f
-	flushWindow f
-	return f
-
-runLoop :: Field -> IO ()
-runLoop f = allocaXEvent $ \e -> do
-	endc <- waitInput f
-	th1 <- forkIOX $ forever $ do
-		evN <- pending $ fDisplay f
-		replicateM_ (fromIntegral evN) $ do
-			nextEvent (fDisplay f) e
-			ev <- getEvent e
-			writeChan (fEvent f) $ Just ev
-		end <- readChan endc
-		when end $ writeChan (fEvent f) Nothing
-	(>> (closeDisplay (fDisplay f) >> writeChan (fEnd f) ())) $
-		(>> destroyWindow (fDisplay f) (fWindow f)) $ doWhile_ $ do
-		mev <- readChan $ fEvent f
-		case mev of
-			Just (ExposeEvent{}) -> do
-				(_, _, _, width, height, _, _) <-
-					getGeometry (fDisplay f) (fWindow f)
-				writeIORef (fWidth f) width
-				writeIORef (fHeight f) height
-				redrawAll f
-				return True
-			Just (KeyEvent{}) -> return True
-			Just ev@ButtonEvent{} -> do
-				pos <- convertPosRev f (ev_x ev) (ev_y ev)
-				readIORef (fOnclick f) >>= ($ pos) . uncurry
-			Just ev@ClientMessageEvent{} ->
-				return $ convert (head $ ev_data ev) /= fDel f
-			Nothing -> killThread th1 >> return False
-			_ -> return True
-
-onclick :: Field -> (Double -> Double -> IO Bool) -> IO ()
-onclick f act = writeIORef (fOnclick f) act
-
-fieldColor :: Field -> Pixel -> IO ()
-fieldColor f clr = do
-	setForeground (fDisplay f) (fGCBG f) clr
-	let bufs = [fUndoBuf f, fBG f, fBuf f]
-	width <- readIORef $ fWidth f
-	height <- readIORef $ fHeight f
-	forM_ bufs $ \bf -> fillRectangle (fDisplay f) bf (fGCBG f) 0 0 width height
-	redrawAll f
-
-getConnection :: Field -> Fd
-getConnection = Fd . connectionNumber . fDisplay
-
-waitInput :: Field -> IO (Chan Bool)
-waitInput f = do
-	c <- newChan
-	_ <- forkIOX $ forever $ do
-		threadWaitRead $ getConnection f
-		writeChan c False
-	_ <- forkIO $ do
-		readChan $ fClose f
-		writeChan c True
-	return c
-
-closeField :: Field -> IO ()
-closeField f = do
-	readIORef (fRunning f) >>= mapM_ killThread
-	threadDelay 100000
-	writeChan (fClose f) ()
-	writeIORef (fClosed f) True
-
-addThread :: Field -> ThreadId -> IO ()
-addThread f tid = modifyIORef (fRunning f) (tid :)
-
-flushLayer :: Layer -> IO ()
-flushLayer = flushWindow . layerField
-
-addLayer :: Field -> IO Layer
-addLayer f = do
-	ls <- readIORef $ fLayers f
-	writeIORef (fLayers f) (ls ++ [[]])
-	modifyIORef (fBuffed f) (++ [return ()])
-	return Layer{layerField = f, layerId = length ls}
-
-addCharacter :: Field -> IO Character
-addCharacter f = do
-	cs <- readIORef $ fCharacters f
-	writeIORef (fCharacters f) (cs ++ [return ()])
-	return Character{characterField = f, characterId = length cs}
-
-runIfOpened :: Field -> IO a -> IO ()
-runIfOpened f act = do
-	cl <- readIORef $ fClosed f
-	if cl then return () else act >> return ()
-
-drawLineNotFlush ::
-	Layer -> Double -> Pixel -> Double -> Double -> Double -> Double -> IO ()
-drawLineNotFlush l@Layer{layerField = f} lw_ clr x1 y1 x2 y2 = runIfOpened f $ do
-	drawLineBuf f lw clr fBG x1 y1 x2 y2
-	addLayerAction l $ whether
-		(drawLineBuf f lw clr fUndoBuf x1 y1 x2 y2)
-		(drawLineBuf f lw clr fBG x1 y1 x2 y2)
-	where
-	lw = round lw_
-
-drawLine :: Layer -> Double -> Pixel -> Double -> Double -> Double -> Double -> IO ()
-drawLine l@Layer{layerField = f} lw_ clr x1 y1 x2 y2 = runIfOpened f $ do
-	drawLineBuf f lw clr fBG x1 y1 x2 y2 >> redrawCharacters f
-	addLayerAction l $ whether
-		(drawLineBuf f lw clr fUndoBuf x1 y1 x2 y2)
-		(drawLineBuf f lw clr fBG x1 y1 x2 y2)
-	where
-	lw = round lw_
-
-clearCharacter :: Character -> IO ()
-clearCharacter c = runIfOpened (characterField c) $
-	setCharacter c $ return ()
-
-drawCharacter :: Character -> Pixel -> [(Double, Double)] -> IO ()
-drawCharacter c@Character{characterField = f} clr sh = do
-	runIfOpened (characterField c) $ setCharacter c $ do
-		setForeground (fDisplay f) (fGC f) clr
-		fillPolygonBuf (characterField c) sh
-
-drawCharacterAndLine ::	Character -> Pixel -> [(Double, Double)] -> Double ->
-	Double -> Double -> Double -> Double -> IO ()
-drawCharacterAndLine c@Character{characterField = f} clr ps lw_ x1 y1 x2 y2 = do
-	runIfOpened f $ setCharacter c $ do
-		setForeground (fDisplay f) (fGC f) clr
-		fillPolygonBuf f ps >> drawLineBuf f lw clr fBuf x1 y1 x2 y2
-	where
-	lw = round lw_
-
-undoLayer :: Layer -> IO Bool
-undoLayer Layer{layerField = f, layerId = lid} = do
-	ls <- readIORef $ fLayers f
-	if null $ ls !! lid then return False else do
-		writeIORef (fLayers f) $ modifyAt ls lid init
-		redraw f
-		return True
-
-clearLayer :: Layer -> IO ()
-clearLayer Layer{layerField = f, layerId = lid} = do
-	ls <- readIORef $ fLayers f
-	writeIORef (fLayers f) $ setAt ls lid []
-	buffed <- readIORef $ fBuffed f
-	writeIORef (fBuffed f) $ setAt buffed lid $ return ()
-	redrawBuf f
-	redraw f
-
-forkIOX :: IO () -> IO ThreadId
-forkIOX = (initThreads >>) . forkIO
-
---------------------------------------------------------------------------------
-
-undoN :: Int
-undoN = 100
-
-addLayerAction :: Layer -> (Bool -> IO ()) -> IO ()
-addLayerAction Layer{layerField = f, layerId = lid} act = do
-	ls <- readIORef $ fLayers f
-	if length (ls !! lid) > undoN
-		then do	head (ls !! lid) True
-			buffed <- readIORef $ fBuffed f
-			writeIORef (fBuffed f) $ 
-				modifyAt buffed lid (>> head (ls !! lid) True)
-			writeIORef (fLayers f) $
-				modifyAt ls lid $ (++ [act]) . tail
-		else writeIORef (fLayers f) $ modifyAt ls lid (++ [act])
-
-setCharacter :: Character -> IO () -> IO ()
-setCharacter Character{characterField = f, characterId = cid} act = do
-	cs <- readIORef $ fCharacters f
-	writeIORef (fCharacters f) $ setAt cs cid act
-	redrawCharacters f
-	flushWindow f
-
-fillPolygonBuf :: Field -> [(Double, Double)] -> IO ()
-fillPolygonBuf f ps_ = do
-	ps <- convertPos f ps_
-	fillPolygon (fDisplay f) (fBuf f) (fGC f) (map (uncurry Point) ps)
-		nonconvex coordModeOrigin
-
-drawLineBuf :: Field -> Int -> Pixel -> (Field -> Pixmap) ->
-	Double -> Double -> Double -> Double -> IO ()
-drawLineBuf f@Field{fDisplay = dpy, fGC = gc} lw clr bf x1_ y1_ x2_ y2_ = do
-	setForeground (fDisplay f) (fGC f) clr
-	setLineAttributes (fDisplay f) (fGC f) (fromIntegral lw) lineSolid capRound joinRound
-	[(x1, y1), (x2, y2)] <- convertPos f [(x1_, y1_), (x2_, y2_)]
-	X.drawLine dpy (bf f) gc x1 y1 x2 y2
-
-convertPos :: Field -> [(Double, Double)] -> IO [(Position, Position)]
-convertPos f ps = do
-	(width, height) <- fieldSize f
-	return $ (round . (+ width / 2) *** round . (+ height / 2) . negate)
-		`map` ps
-
-convertPosRev :: Field -> CInt -> CInt -> IO (Double, Double)
-convertPosRev f x y = do
-	(width, height) <- fieldSize f
-	return $ (fromIntegral x - width / 2, fromIntegral (- y) + height / 2)
-
-fieldSize :: Field -> IO (Double, Double)
-fieldSize w = fmap (fromIntegral *** fromIntegral) $ winSize w
-
-winSize :: Field -> IO (Dimension, Dimension)
-winSize f = do
-	width <- readIORef $ fWidth f
-	height <- readIORef $ fHeight f
-	return (width, height)
-
-redrawAll :: Field -> IO ()
-redrawAll f = do
-	redrawBuf f
-	redraw f
-	flushWindow f
-
-redrawBuf :: Field -> IO ()
-redrawBuf f = do
-	winSize f >>=
-		uncurry (fillRectangle (fDisplay f) (fUndoBuf f) (fGCBG f) 0 0)
-	readIORef (fBuffed f) >>= sequence_
-
-redraw :: Field -> IO ()
-redraw = withLock $ \f -> do
-	(width, height) <- winSize f
-	copyArea (fDisplay f) (fUndoBuf f) (fBG f) (fGC f) 0 0 width height 0 0
-	readIORef (fLayers f) >>= mapM_ ($ False) . concat
-	copyArea (fDisplay f) (fBG f) (fBuf f) (fGC f) 0 0 width height 0 0
-	readIORef (fCharacters f) >>= sequence_
-
-redrawCharacters :: Field -> IO ()
-redrawCharacters = withLock $ \f -> do
-	(width, height) <- winSize f
-	copyArea (fDisplay f) (fBG f) (fBuf f) (fGC f) 0 0 width height 0 0
-	readIORef (fCharacters f) >>= sequence_
-
-flushWindow :: Field -> IO ()
-flushWindow = withLock $ \f -> do
-	(width, height) <- winSize f
-	copyArea (fDisplay f) (fBuf f) (fWindow f) (fGC f) 0 0 width height 0 0
-	flush $ fDisplay f
-
-withLock :: (Field -> IO a) -> Field -> IO a
-withLock act f = do
-	readChan $ fWait f
-	ret <- act f
-	writeChan (fWait f) ()
-	return ret
-
-waitField :: Field -> IO ()
-waitField = readChan . fEnd
diff --git a/xturtle.cabal b/xturtle.cabal
--- a/xturtle.cabal
+++ b/xturtle.cabal
@@ -2,7 +2,7 @@
 cabal-version:	>= 1.6
 
 name:		xturtle
-version:	0.0.12
+version:	0.0.13
 stability:	experimental
 author:		Yoshikuni Jujo <PAF01143@nifty.ne.jp>
 maintainer:	Yoshikuni Jujo <PAF01143@nifty.ne.jp>
@@ -30,7 +30,8 @@
 library
   Hs-source-dirs:	src
   Exposed-modules:	Graphics.X11.Turtle
-  Build-depends:	base > 3 && < 5, yjtools >= 0.9.13, convertible, X11
+  Build-depends:	base > 3 && < 5, yjtools >= 0.9.13, convertible, X11,
+    X11-xft <= 3.1, x11-xim, setlocale
   Ghc-options:		-Wall
-  Other-modules:	Graphics.X11.WindowLayers, Graphics.X11.TurtleInput,
+  Other-modules:	Graphics.X11.TurtleField, Graphics.X11.TurtleInput,
     Graphics.X11.TurtleMove, Graphics.X11.TurtleState, Graphics.X11.TurtleShape
