Added message interface

This commit is contained in:
Matthias Schiffer 2010-04-07 10:31:27 +02:00
parent 050f1283eb
commit 1b4d7204a8
2 changed files with 128 additions and 57 deletions

View file

@ -11,7 +11,7 @@ build-type: Simple
Cabal-Version: >=1.2 Cabal-Version: >=1.2
library library
build-depends: base >= 4 build-depends: base >= 4, clock
exposed-modules: HWiid exposed-modules: HWiid
hs-source-dirs: src hs-source-dirs: src
extra-libraries: cwiid extra-libraries: cwiid

View file

@ -3,20 +3,17 @@
module HWiid ( BDAddr(..) module HWiid ( BDAddr(..)
, Wiimote , Wiimote
, WiimoteState(..) , WiimoteState(..)
, WiimoteMesg(..)
, nullWiimote , nullWiimote
, bdAddrAny , bdAddrAny
, hwiidFlagMesgInterface
, hwiidFlagNonblock
, hwiidReportStatus
, hwiidReportButtons
, hwiidLed1 , hwiidLed1
, hwiidLed2 , hwiidLed2
, hwiidLed3 , hwiidLed3
, hwiidLed4 , hwiidLed4
, hwiidReportStatus
, hwiidReportButtons
, hwiidOpen
, hwiidOpenTimeout
, hwiidClose
, hwiidGetState
, hwiidSetReportMode
, hwiidSetLed
, hwiidButton2 , hwiidButton2
, hwiidButton1 , hwiidButton1
, hwiidButtonB , hwiidButtonB
@ -30,19 +27,105 @@ module HWiid ( BDAddr(..)
, hwiidButtonPlus , hwiidButtonPlus
, hwiidNunchukButtonZ , hwiidNunchukButtonZ
, hwiidNunchukButtonC , hwiidNunchukButtonC
, hwiidOpen
, hwiidOpenTimeout
, hwiidClose
, hwiidGetState
, hwiidSetReportMode
, hwiidSetLed
, hwiidGetMesg
) where ) where
import Data.Bits
import Data.Typeable
import Data.Word import Data.Word
import Foreign.C.Types import Foreign.C.Types
import Foreign.Marshal.Alloc (alloca) import Foreign.Marshal.Alloc (alloca, free)
import Foreign.Marshal.Array (peekArray)
import Foreign.Marshal.Utils (with) import Foreign.Marshal.Utils (with)
import Foreign.Ptr import Foreign.Ptr
import Foreign.Storable import Foreign.Storable
import System.Posix.Clock (TimeSpec)
#include <cwiid.h> #include <cwiid.h>
hwiidFlagMesgInterface :: CInt
hwiidFlagMesgInterface = (#const CWIID_FLAG_MESG_IFC)
hwiidFlagNonblock :: CInt
hwiidFlagNonblock = (#const CWIID_FLAG_NONBLOCK)
hwiidReportStatus :: Word8
hwiidReportStatus = (#const CWIID_RPT_STATUS)
hwiidReportButtons :: Word8
hwiidReportButtons = (#const CWIID_RPT_BTN)
hwiidLed1 :: Word8
hwiidLed1 = (#const CWIID_LED1_ON)
hwiidLed2 :: Word8
hwiidLed2 = (#const CWIID_LED2_ON)
hwiidLed3 :: Word8
hwiidLed3 = (#const CWIID_LED3_ON)
hwiidLed4 :: Word8
hwiidLed4 = (#const CWIID_LED4_ON)
hwiidButton2 :: Word16
hwiidButton2 = (#const CWIID_BTN_2)
hwiidButton1 :: Word16
hwiidButton1 = (#const CWIID_BTN_1)
hwiidButtonB :: Word16
hwiidButtonB = (#const CWIID_BTN_B)
hwiidButtonA :: Word16
hwiidButtonA = (#const CWIID_BTN_A)
hwiidButtonMinus :: Word16
hwiidButtonMinus = (#const CWIID_BTN_MINUS)
hwiidButtonHome :: Word16
hwiidButtonHome = (#const CWIID_BTN_HOME)
hwiidButtonLeft :: Word16
hwiidButtonLeft = (#const CWIID_BTN_LEFT)
hwiidButtonRight :: Word16
hwiidButtonRight = (#const CWIID_BTN_RIGHT)
hwiidButtonDown :: Word16
hwiidButtonDown = (#const CWIID_BTN_DOWN)
hwiidButtonUp :: Word16
hwiidButtonUp = (#const CWIID_BTN_UP)
hwiidButtonPlus :: Word16
hwiidButtonPlus = (#const CWIID_BTN_PLUS)
hwiidNunchukButtonZ :: Word16
hwiidNunchukButtonZ = (#const CWIID_NUNCHUK_BTN_Z)
hwiidNunchukButtonC :: Word16
hwiidNunchukButtonC = (#const CWIID_NUNCHUK_BTN_C)
hwiidMesgTypeStatus :: (#type enum cwiid_mesg_type)
hwiidMesgTypeStatus = (#const CWIID_MESG_STATUS)
hwiidMesgTypeButton :: (#type enum cwiid_mesg_type)
hwiidMesgTypeButton = (#const CWIID_MESG_BTN)
data BDAddr = BDAddr (Word8, Word8, Word8, Word8, Word8, Word8) data BDAddr = BDAddr (Word8, Word8, Word8, Word8, Word8, Word8)
deriving (Eq, Ord, Show) deriving (Eq, Ord, Show)
@ -88,67 +171,41 @@ instance Storable WiimoteState where
(#poke struct cwiid_state, buttons) state buttons (#poke struct cwiid_state, buttons) state buttons
data WiimoteMesg = WiimoteStatusMesg
{ mesgType :: (#type enum cwiid_mesg_type)
, mesgBattery :: Word8
, mesgExtensionType :: (#type enum cwiid_ext_type)
}
| WiimoteButtonMesg
{ mesgType :: (#type enum cwiid_mesg_type)
, mesgButtons :: Word16
}
| WiimoteMesgUnknown
deriving (Eq, Show)
instance Storable WiimoteMesg where
sizeOf _ = (#size union cwiid_mesg)
alignment _ = alignment (undefined :: CInt)
peek mesg = do
mesgtype <- (#peek union cwiid_mesg, type) mesg
case () of
_ | mesgtype == hwiidMesgTypeStatus -> do
battery <- (#peek struct cwiid_status_mesg, battery) mesg
exttype <- (#peek struct cwiid_status_mesg, ext_type) mesg
return $ WiimoteStatusMesg mesgtype battery exttype
| mesgtype == hwiidMesgTypeButton -> do
buttons <- (#peek struct cwiid_btn_mesg, buttons) mesg
return $ WiimoteButtonMesg mesgtype buttons
| otherwise -> return WiimoteMesgUnknown
poke _ _ = error "Can't write WiimoteMesg"
newtype Wiimote = Wiimote (Ptr Wiimote) deriving (Eq, Ord, Show, Storable) newtype Wiimote = Wiimote (Ptr Wiimote) deriving (Eq, Ord, Show, Storable)
hwiidLed1 :: Word8
hwiidLed1 = (#const CWIID_LED1_ON)
hwiidLed2 :: Word8
hwiidLed2 = (#const CWIID_LED2_ON)
hwiidLed3 :: Word8
hwiidLed3 = (#const CWIID_LED3_ON)
hwiidLed4 :: Word8
hwiidLed4 = (#const CWIID_LED4_ON)
hwiidReportStatus :: Word8
hwiidReportStatus = (#const CWIID_RPT_STATUS)
hwiidReportButtons :: Word8
hwiidReportButtons = (#const CWIID_RPT_BTN)
hwiidButton2 :: Word16
hwiidButton2 = (#const CWIID_BTN_2)
hwiidButton1 :: Word16
hwiidButton1 = (#const CWIID_BTN_1)
hwiidButtonB :: Word16
hwiidButtonB = (#const CWIID_BTN_B)
hwiidButtonA :: Word16
hwiidButtonA = (#const CWIID_BTN_A)
hwiidButtonMinus :: Word16
hwiidButtonMinus = (#const CWIID_BTN_MINUS)
hwiidButtonHome :: Word16
hwiidButtonHome = (#const CWIID_BTN_HOME)
hwiidButtonLeft :: Word16
hwiidButtonLeft = (#const CWIID_BTN_LEFT)
hwiidButtonRight :: Word16
hwiidButtonRight = (#const CWIID_BTN_RIGHT)
hwiidButtonDown :: Word16
hwiidButtonDown = (#const CWIID_BTN_DOWN)
hwiidButtonUp :: Word16
hwiidButtonUp = (#const CWIID_BTN_UP)
hwiidButtonPlus :: Word16
hwiidButtonPlus = (#const CWIID_BTN_PLUS)
hwiidNunchukButtonZ :: Word16
hwiidNunchukButtonZ = (#const CWIID_NUNCHUK_BTN_Z)
hwiidNunchukButtonC :: Word16
hwiidNunchukButtonC = (#const CWIID_NUNCHUK_BTN_C)
nullWiimote :: Wiimote nullWiimote :: Wiimote
nullWiimote = Wiimote nullPtr nullWiimote = Wiimote nullPtr
@ -181,3 +238,17 @@ foreign import ccall unsafe "cwiid.h cwiid_set_rpt_mode"
foreign import ccall unsafe "cwiid.h cwiid_set_led" foreign import ccall unsafe "cwiid.h cwiid_set_led"
hwiidSetLed :: Wiimote -> Word8 -> IO CInt hwiidSetLed :: Wiimote -> Word8 -> IO CInt
foreign import ccall unsafe "cwiid.h cwiid_get_mesg"
cwiid_get_mesg :: Wiimote -> Ptr CInt -> Ptr (Ptr WiimoteMesg) -> Ptr TimeSpec -> IO CInt
hwiidGetMesg :: Wiimote -> IO [WiimoteMesg]
hwiidGetMesg wiimote = alloca $ \countptr -> alloca $ \arrayptr -> alloca $ \timestamp -> do
cwiid_get_mesg wiimote countptr arrayptr timestamp
count <- peek countptr
array <- peek arrayptr
ret <- peekArray (fromIntegral count) array
free array
return ret