220 lines
5.0 KiB
Haskell
220 lines
5.0 KiB
Haskell
{-# LANGUAGE CApiFFI #-}
|
|
{-# LANGUAGE ForeignFunctionInterface #-}
|
|
|
|
module WM.XKutu where
|
|
|
|
import Data.Int (Int16, Int32, Int8)
|
|
import Data.Word (Word16, Word32)
|
|
import Foreign (Ptr, Storable, alignment, alloca, peek, peekByteOff, poke, pokeByteOff, sizeOf)
|
|
import Foreign.C.Types (CInt (CInt))
|
|
|
|
newtype XcbWindow = XcbWindow Word32
|
|
deriving (Show, Storable)
|
|
|
|
data Geometry = Geometry
|
|
{ geom_x :: Int16,
|
|
geom_y :: Int16,
|
|
geom_w :: Word16,
|
|
geom_h :: Word16
|
|
}
|
|
deriving (Show)
|
|
|
|
instance Storable Geometry where
|
|
sizeOf _ = 8
|
|
alignment _ = alignment (undefined :: Word32)
|
|
|
|
peek ptr = do
|
|
x <- peekByteOff ptr 0
|
|
y <- peekByteOff ptr 2
|
|
w <- peekByteOff ptr 4
|
|
h <- peekByteOff ptr 6
|
|
pure $ Geometry x y w h
|
|
|
|
poke ptr (Geometry x y w h) = do
|
|
pokeByteOff ptr 0 x
|
|
pokeByteOff ptr 2 y
|
|
pokeByteOff ptr 4 w
|
|
pokeByteOff ptr 6 h
|
|
|
|
data PointerInfo = PointerInfo
|
|
{ pointer_info_x :: Int16,
|
|
pointer_info_y :: Int16,
|
|
pointer_info_w :: XcbWindow
|
|
}
|
|
deriving (Show)
|
|
|
|
instance Storable PointerInfo where
|
|
sizeOf _ = 8
|
|
alignment _ = alignment (undefined :: Word32)
|
|
|
|
peek ptr = do
|
|
x <- peekByteOff ptr 0
|
|
y <- peekByteOff ptr 2
|
|
w <- peekByteOff ptr 4
|
|
pure $ PointerInfo x y w
|
|
|
|
poke ptr (PointerInfo x y w) = do
|
|
pokeByteOff ptr 0 x
|
|
pokeByteOff ptr 2 y
|
|
pokeByteOff ptr 4 w
|
|
|
|
data Event = Event
|
|
{ event_type :: Int32,
|
|
event_window :: XcbWindow,
|
|
event_override_redirect :: Int8,
|
|
event_btn :: Word32,
|
|
event_x :: Int32,
|
|
event_y :: Int32,
|
|
event_height :: Word32,
|
|
event_width :: Word32,
|
|
event_state :: Word32,
|
|
event_is_root :: Int8
|
|
}
|
|
deriving (Show)
|
|
|
|
instance Storable Event where
|
|
sizeOf _ = 40
|
|
alignment _ = alignment (undefined :: Word32)
|
|
|
|
peek ptr = do
|
|
eventType <- peekByteOff ptr 0
|
|
window <- peekByteOff ptr 4
|
|
overrideRedirect <- peekByteOff ptr 8
|
|
btn <- peekByteOff ptr 12
|
|
x <- peekByteOff ptr 16
|
|
y <- peekByteOff ptr 20
|
|
height <- peekByteOff ptr 24
|
|
width <- peekByteOff ptr 28
|
|
state <- peekByteOff ptr 32
|
|
isRoot <- peekByteOff ptr 36
|
|
|
|
pure $
|
|
Event
|
|
eventType
|
|
(XcbWindow window)
|
|
overrideRedirect
|
|
btn
|
|
x
|
|
y
|
|
height
|
|
width
|
|
state
|
|
isRoot
|
|
|
|
poke ptr (Event eventType (XcbWindow window) overrideRedirect btn x y height width state isRoot) = do
|
|
pokeByteOff ptr 0 eventType
|
|
pokeByteOff ptr 4 window
|
|
pokeByteOff ptr 8 overrideRedirect
|
|
pokeByteOff ptr 12 btn
|
|
pokeByteOff ptr 16 x
|
|
pokeByteOff ptr 20 y
|
|
pokeByteOff ptr 24 height
|
|
pokeByteOff ptr 28 width
|
|
pokeByteOff ptr 32 state
|
|
pokeByteOff ptr 36 isRoot
|
|
|
|
foreign import capi "x_kutu.h value MOD"
|
|
mOD_MASK :: CInt
|
|
|
|
foreign import capi "x_kutu.h value XCB_MOD_MASK_LOCK"
|
|
cLK_MASK :: CInt
|
|
|
|
foreign import capi "x_kutu.h value XCB_MOD_MASK_2"
|
|
nUM_MASK :: CInt
|
|
|
|
foreign import capi "x_kutu.h deploy"
|
|
c_deploy :: IO CInt
|
|
|
|
deploy :: IO Bool
|
|
deploy = (== 0) <$> c_deploy
|
|
|
|
foreign import capi "x_kutu.h flush"
|
|
flush :: IO ()
|
|
|
|
foreign import capi "x_kutu.h cleanup"
|
|
cleanup :: IO ()
|
|
|
|
foreign import capi "x_kutu.h add_keybind"
|
|
add_keybind :: CInt -> CInt -> IO ()
|
|
|
|
foreign import capi "x_kutu.h add_mousebind"
|
|
add_mousebind :: CInt -> CInt -> IO ()
|
|
|
|
foreign import capi "x_kutu.h get_focus"
|
|
c_get_focus :: IO Word32
|
|
|
|
get_focus :: IO XcbWindow
|
|
get_focus = XcbWindow <$> c_get_focus
|
|
|
|
foreign import capi "x_kutu.h get_root"
|
|
c_get_root :: IO Word32
|
|
|
|
get_root :: IO XcbWindow
|
|
get_root = XcbWindow <$> c_get_root
|
|
|
|
foreign import capi "x_kutu.h focus"
|
|
focus :: XcbWindow -> IO ()
|
|
|
|
foreign import capi "x_kutu.h subscribe"
|
|
subscribe :: XcbWindow -> IO ()
|
|
|
|
foreign import capi "x_kutu.h kill"
|
|
kill :: XcbWindow -> IO ()
|
|
|
|
foreign import capi "x_kutu.h destroy"
|
|
destroy :: XcbWindow -> IO ()
|
|
|
|
foreign import capi "x_kutu.h show"
|
|
show :: XcbWindow -> IO ()
|
|
|
|
foreign import capi "x_kutu.h hide"
|
|
hide :: XcbWindow -> IO ()
|
|
|
|
foreign import capi "x_kutu.h send_to_top"
|
|
send_to_top :: XcbWindow -> IO ()
|
|
|
|
foreign import capi "x_kutu.h draw_rectangle"
|
|
c_draw_rectangle :: CInt -> CInt -> CInt -> CInt -> Word32 -> IO Word32
|
|
|
|
draw_rectangle :: CInt -> CInt -> CInt -> CInt -> Word32 -> IO XcbWindow
|
|
draw_rectangle x y w h c =
|
|
XcbWindow <$> c_draw_rectangle x y w h c
|
|
|
|
foreign import capi "x_kutu.h get_geometry"
|
|
c_get_geometry :: XcbWindow -> Ptr Geometry -> IO ()
|
|
|
|
get_geometry :: XcbWindow -> IO Geometry
|
|
get_geometry win =
|
|
alloca $ \ptr -> do
|
|
c_get_geometry win ptr
|
|
peek ptr
|
|
|
|
foreign import capi "x_kutu.h get_screen"
|
|
c_get_screen :: Ptr Geometry -> IO ()
|
|
|
|
get_screen :: IO Geometry
|
|
get_screen =
|
|
alloca $ \ptr -> do
|
|
c_get_screen ptr
|
|
peek ptr
|
|
|
|
foreign import capi "x_kutu.h get_pointer"
|
|
c_get_pointer :: Ptr PointerInfo -> IO ()
|
|
|
|
get_pointer :: IO PointerInfo
|
|
get_pointer =
|
|
alloca $ \ptr -> do
|
|
c_get_pointer ptr
|
|
peek ptr
|
|
|
|
foreign import capi "x_kutu.h next_event"
|
|
c_next_event :: Ptr Event -> IO CInt
|
|
|
|
next_event :: IO (Maybe Event)
|
|
next_event =
|
|
alloca $ \ptr -> do
|
|
ok <- c_next_event ptr
|
|
if ok == 0
|
|
then pure Nothing
|
|
else Just <$> peek ptr
|