diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,8 @@
+2014-05-20 Ivan Perez <ivan.perez@keera.co.uk>
+
+        * API: adds infrared tracking support
+        * Tests: adapts test to report IR data
+
 2014-05-17 Ivan Perez <ivan.perez@keera.co.uk>
 
         * API: adds accelerometer sensing.
diff --git a/README b/README
--- a/README
+++ b/README
@@ -18,7 +18,6 @@
 
 TODO
 ========
-* Enable IR. Create an example that uses it.
 * Locate projects using this. (I am personally working on some games that will
 be published.)
 * Write a decent example that uses more than just testing a button thing.
diff --git a/System/CWiid.hsc b/System/CWiid.hsc
--- a/System/CWiid.hsc
+++ b/System/CWiid.hsc
@@ -23,8 +23,8 @@
 -- then exported properly.
 --
 -- * Not all functions/wiimote fields are accessible. In particular,
--- acceleromoter info is in testing stage and no IR information
--- is exported.
+-- acceleromoter and IR is in testing stage. Nunchuck, calibration,
+-- wiimote plus are not handled at all (but will be in the future).
 --
 -- All in all, the code works quite well and is currently being used
 -- to implement several real games.
@@ -57,7 +57,10 @@
         CWiidBtnFlag(..),
         -- * Accelerometers
         cwiidGetAcc,
-        CWiidAcc(..)
+        CWiidAcc(..),
+        -- * Infra-red
+        CWiidIRSrc(..),
+        cwiidGetIR
         ) where
 
 -- import Foreign.C.Error
@@ -148,13 +151,14 @@
 data CWiidState = CWiidState
   { rptMode :: Int, led :: Int, rumble :: Int, 
     battery :: Int, buttons :: Int, acc :: [Int]
+  , irSrc   :: [CWiidIRSrc]
   }
   deriving Show
 
 instance Storable CWiidState where
   sizeOf = const #size struct cwiid_state
   alignment = sizeOf
-  poke cwst (CWiidState rp l ru ba bu [ac0,ac1,ac2]) = do
+  poke cwst (CWiidState rp l ru ba bu [ac0,ac1,ac2] irs) = do
     (#poke struct cwiid_state, rpt_mode) cwst rp
     (#poke struct cwiid_state, led) cwst l
     (#poke struct cwiid_state, rumble) cwst ru
@@ -163,6 +167,7 @@
     (#poke struct cwiid_state, acc[0]) cwst (fromIntegral ac0 :: CUChar)
     (#poke struct cwiid_state, acc[1]) cwst (fromIntegral ac1 :: CUChar)
     (#poke struct cwiid_state, acc[2]) cwst (fromIntegral ac2 :: CUChar)
+    pokeArray ((#ptr struct cwiid_state, ir_src) cwst) irs 
   peek cwst = do
     rp <- (#peek struct cwiid_state, rpt_mode) cwst
     l <- (#peek struct cwiid_state, led) cwst
@@ -172,10 +177,66 @@
     ac0 <- (#peek struct cwiid_state, acc[0]) cwst
     ac1 <- (#peek struct cwiid_state, acc[1]) cwst
     ac2 <- (#peek struct cwiid_state, acc[2]) cwst
+    irs <- peekArray cwiidIrSrcCount ((#ptr struct cwiid_state, ir_src) cwst)
     return $ CWiidState rp l ru ba bu [ fromIntegral (ac0 :: CUChar)
                                       , fromIntegral (ac1 :: CUChar)
                                       , fromIntegral (ac2 :: CUChar)]
+                                      irs
 
+-- * Infrared
+
+-- | Maximum number of infrared points detected.
+--   By default (according to cwiid) it should be 4.
+cwiidIrSrcCount :: Int
+cwiidIrSrcCount = (#const CWIID_IR_SRC_COUNT)
+
+-- struct cwiid_ir_src {
+-- 	char valid;
+-- 	uint16_t pos[2];
+-- 	int8_t size;
+-- };
+--
+-- The following model is weaker than the counterpart in C (see above). We do
+-- so in order to provide something more "natural" in Haskell, but it might
+-- be better to use a more precise datatype.
+
+-- | Internal representation of an infrared point. You should no use it
+--   unless you know what you are doing; use 'CWiidIR' instead.
+data CWiidIRSrc = CWiidIRSrc
+  { cwiidIRSrcValid :: Bool
+  , cwiidIRSrcPosX  :: Int
+  , cwiidIRSrcPosY  :: Int
+  , cwiidIRSrcSize  :: Int
+  }
+ deriving Show
+
+instance Storable CWiidIRSrc where
+  sizeOf = const #size struct cwiid_ir_src
+  alignment = sizeOf
+  poke cwst (CWiidIRSrc valid posX posY sz) = do
+    (#poke struct cwiid_ir_src, valid)  cwst ((if valid then (-1) else 0) :: CChar)
+    (#poke struct cwiid_ir_src, pos[0]) cwst (fromIntegral posX :: CUShort)
+    (#poke struct cwiid_ir_src, pos[1]) cwst (fromIntegral posY :: CUShort)
+    (#poke struct cwiid_ir_src, size)   cwst (fromIntegral sz   :: CChar)
+  peek cwst = do
+    valid <- (#peek struct cwiid_ir_src, valid)  cwst
+    posX  <- (#peek struct cwiid_ir_src, pos[0]) cwst
+    posY  <- (#peek struct cwiid_ir_src, pos[1]) cwst
+    sz    <- (#peek struct cwiid_ir_src, size)   cwst
+    return $ CWiidIRSrc (not ((valid :: CChar) == 0))
+                        (fromIntegral (posX :: CUShort))
+                        (fromIntegral (posY :: CUShort))
+                        (fromIntegral (sz :: CChar))
+
+cwiidGetIR :: CWiidWiimote -> IO [CWiidIRSrc]
+cwiidGetIR wm = 
+  alloca $ \wiState -> do
+    _ <- c_cwiid_get_state handle wiState
+    ws <- peek wiState
+    return (irSrc ws)
+      where handle = unCWiidWiimote wm
+
+-- * Leds
 newtype CWiidLedFlag = CWiidLedFlag { unCWiidLedFlag :: Int }
                      deriving (Eq, Show)
 
@@ -298,6 +359,9 @@
  deriving (Eq, Show)
 
 -- | Obtain accelerometer information.
+--   FIXME: read wmgui/main.c:cwiid_acc(1119) to understand how to use
+--   this information, what else might need to be exported, and how
+--   to calibrate the accelerometers.
 cwiidGetAcc :: CWiidWiimote -> IO CWiidAcc
 cwiidGetAcc wm =
   alloca $ \wiState -> do
diff --git a/hcwiid.cabal b/hcwiid.cabal
--- a/hcwiid.cabal
+++ b/hcwiid.cabal
@@ -1,5 +1,5 @@
 Name:                   hcwiid
-Version:                0.0.4
+Version:                0.0.5
 Author:                 Kiwamu Okabe <kiwamu@debian.or.jp>, Ivan Perez <ivan.perez@keera.co.uk>
 Maintainer:             Ivan Perez <ivan.perez@keera.co.uk>
 License:                GPL-2
diff --git a/test/Test.hs b/test/Test.hs
--- a/test/Test.hs
+++ b/test/Test.hs
@@ -4,6 +4,8 @@
 import Control.Monad
 import System.CWiid
 import System.Posix.Unistd
+-- Uncomment if you want to move the mouse with the wiimote
+-- import System.Process
 
 main :: IO ()
 main = do
@@ -11,8 +13,33 @@
   (Just wm) <- cwiidOpen
   putStrLn "found!"
   _ <- cwiidSetLed wm (combineCwiidLedFlag [cwiidLed1, cwiidLed3])
-  _ <- cwiidSetRptMode wm 7
+  _ <- cwiidSetRptMode wm 15 -- Buttons + Acc + IR
   _ <- forever $ do _ <- usleep 300000
                     cwiidGetBtnState wm >>= print
                     cwiidGetAcc wm >>= print
+                    cwiidGetIR wm >>= print
+
+                    -- The following code shows how to use the IR camera
+                    -- to control the mouse. Adjust your monitor resolution
+                    -- and displacement using the constants below.
+                    --
+                    -- irs <- cwiidGetIR wm
+                    -- let numLeds = filter cwiidIRSrcValid rs
+                    -- let led1   = irs!!0
+                    --     led2   = irs!!1
+                    -- let posX = ((cwiidIRSrcPosX led1) + (cwiidIRSrcPosX led2)) `div` 2
+                    -- let posY = ((cwiidIRSrcPosY led1) + (cwiidIRSrcPosY led2)) `div` 2
+                    --     propX = (fromIntegral (1024 - posX)) / 1024.0
+                    --     propY = (fromIntegral (max 0 (posY - 384))) / 384.0 
+                    --     finX  = monitorDispX + round (monitorResX * propX)
+                    --     finY  = monitorDispY + round (monitorResY * propY)
+
+                    -- system $ "xdotool mousemove " ++ show finX ++ " " ++ show finY
+                    
   return () -- not reach
+
+-- monitorResX = 1280
+-- monitorResY = 1024
+-- 
+-- monitorDispX = 1920
+-- monitorDispY = 0
