aboutsummaryrefslogtreecommitdiff
path: root/plug/src
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2026-01-06 15:09:52 -0700
committerJosh Rahm <joshuarahm@gmail.com>2026-01-06 15:09:52 -0700
commit68dd63f6b3de774863051b66e609a0ca4f4ac2a1 (patch)
treea908ebced56be6fc14307b1a1dc304c47905f8e2 /plug/src
parent12f8ef6dbf8618aaa304d239fbfd3c1b7b4494d3 (diff)
downloadmontis-68dd63f6b3de774863051b66e609a0ca4f4ac2a1.tar.gz
montis-68dd63f6b3de774863051b66e609a0ca4f4ac2a1.tar.bz2
montis-68dd63f6b3de774863051b66e609a0ca4f4ac2a1.zip
[rebrand] to arken = runtime, montis = plugin
Diffstat (limited to 'plug/src')
-rw-r--r--plug/src/Config.hs33
-rw-r--r--plug/src/Link.hs18
-rw-r--r--plug/src/Montis/Base/Foreign/Runtime.hs37
-rw-r--r--plug/src/Montis/Base/Foreign/WlRoots.hs44
-rw-r--r--plug/src/Montis/Base/Foreign/WlRoots/Types.hs99
-rw-r--r--plug/src/Montis/Core.hs10
-rw-r--r--plug/src/Montis/Core/Events.hs46
-rw-r--r--plug/src/Montis/Core/Extensions.hs30
-rw-r--r--plug/src/Montis/Core/Internal/Foreign/Export.hs226
-rw-r--r--plug/src/Montis/Core/Monad.hs125
-rw-r--r--plug/src/Montis/Core/Plugin/Interface.hs20
-rw-r--r--plug/src/Montis/Core/Runtime.hs82
-rw-r--r--plug/src/Montis/Core/Start.hs38
-rw-r--r--plug/src/Montis/Core/State.hs116
-rw-r--r--plug/src/Montis/Core/State/Marshal.hs44
-rw-r--r--plug/src/Montis/Foreign/Marshal.hs20
-rw-r--r--plug/src/Montis/Standard/Drag.hs123
-rw-r--r--plug/src/Montis/Standard/Keys.hs110
-rw-r--r--plug/src/Montis/Standard/Mouse.hs50
-rw-r--r--plug/src/harness_adapter.c73
20 files changed, 0 insertions, 1344 deletions
diff --git a/plug/src/Config.hs b/plug/src/Config.hs
deleted file mode 100644
index 8ec06dd..0000000
--- a/plug/src/Config.hs
+++ /dev/null
@@ -1,33 +0,0 @@
-module Config (config) where
-
-import Control.Monad.IO.Class (liftIO)
-import Data.Bits (shiftL, (.&.))
-import Data.Word (Word32)
-import Montis.Core
-import Montis.Core.Runtime (warpCursor)
-import Montis.Standard.Drag (DragConfig (DragConfig))
-import Montis.Standard.Keys (KeysConfig (KeysConfig), subkeys)
-import Montis.Standard.Mouse (MouseConfig (MouseConfig))
-
-keys :: KeyEvent -> Montis Bool
-keys ev
- | keyEvent_modifiers ev .&. mod1Mask == 0 = return False
- | otherwise = case keyEvent_codepoint ev of
- 'j' -> do
- liftIO (putStrLn "j was pressed!")
- subkeys $ \ev -> case keyEvent_codepoint ev of
- 'k' -> do
- liftIO (putStrLn "k was pressed after j!")
- warpCursor 0 0
- return True
- _ -> return False
- _ -> return False
-
-mod1Mask :: Word32
-mod1Mask = 1 `shiftL` 3 -- WLR_MODIFIER_ALT
-
-config :: MontisConfig
-config =
- install MouseConfig $
- install (DragConfig mod1Mask) $
- install (KeysConfig keys) defaultConfig
diff --git a/plug/src/Link.hs b/plug/src/Link.hs
deleted file mode 100644
index 4ac3f5c..0000000
--- a/plug/src/Link.hs
+++ /dev/null
@@ -1,18 +0,0 @@
--- | Module that provides the start hooks using the config required to link the
--- plugin's shared library.
-module Link () where
-
-import Config (config)
-import Montis.Core
-
-foreign export ccall "plugin_cold_start"
- coldStart :: MontisColdStart
-
-foreign export ccall "plugin_hot_start"
- hotStart :: MontisHotStart
-
-coldStart :: MontisColdStart
-coldStart = coldStartMontis config
-
-hotStart :: MontisHotStart
-hotStart = hotStartMontis config
diff --git a/plug/src/Montis/Base/Foreign/Runtime.hs b/plug/src/Montis/Base/Foreign/Runtime.hs
deleted file mode 100644
index 427545a..0000000
--- a/plug/src/Montis/Base/Foreign/Runtime.hs
+++ /dev/null
@@ -1,37 +0,0 @@
-module Montis.Base.Foreign.Runtime where
-
-import Data.Void
-import Foreign.C (CInt (..), CString, CDouble (..))
-import Foreign.Ptr
-
-data ForeignMontisToplevel
-
-foreign import ccall "montis_do_request_hot_reload" foreign_doRequestHotReload :: Ptr Void -> IO ()
-
-foreign import ccall "montis_do_request_log" foreign_doRequestLog :: Ptr Void -> CString -> IO ()
-
-foreign import ccall "montis_do_request_exit" foreign_doRequestExit :: Ptr Void -> CInt -> IO ()
-
-foreign import ccall "montis_plugin_get_seat" foreign_getSeat :: Ptr Void -> IO (Ptr Void)
-
-foreign import ccall "montis_plugin_toplevel_at"
- foreign_toplevelAt :: Ptr Void -> CDouble -> CDouble -> IO (Ptr ForeignMontisToplevel)
-
-foreign import ccall "montis_plugin_get_toplevel_position"
- foreign_getToplevelPosition :: Ptr ForeignMontisToplevel -> Ptr CDouble -> Ptr CDouble -> IO ()
-
-foreign import ccall "montis_plugin_set_toplevel_position"
- foreign_setToplevelPosition :: Ptr ForeignMontisToplevel -> CDouble -> CDouble -> IO ()
-
-foreign import ccall "montis_plugin_get_toplevel_geometry"
- foreign_getToplevelGeometry ::
- Ptr ForeignMontisToplevel -> Ptr CDouble -> Ptr CDouble -> Ptr CDouble -> Ptr CDouble -> IO ()
-
-foreign import ccall "montis_plugin_set_toplevel_geometry"
- foreign_setToplevelGeometry :: Ptr ForeignMontisToplevel -> CDouble -> CDouble -> CDouble -> CDouble -> IO ()
-
-foreign import ccall "montis_plugin_focus_toplevel"
- foreign_focusToplevel :: Ptr ForeignMontisToplevel -> IO ()
-
-foreign import ccall "montis_plugin_warp_cursor"
- foreign_warpCursor :: Ptr Void -> CDouble -> CDouble -> IO ()
diff --git a/plug/src/Montis/Base/Foreign/WlRoots.hs b/plug/src/Montis/Base/Foreign/WlRoots.hs
deleted file mode 100644
index 272567f..0000000
--- a/plug/src/Montis/Base/Foreign/WlRoots.hs
+++ /dev/null
@@ -1,44 +0,0 @@
--- | Contains functions and thin wrappers via ffi to the wlroots API.
-module Montis.Base.Foreign.WlRoots where
-
-import Foreign (Ptr, Word32, nullPtr)
-import Montis.Base.Foreign.WlRoots.Types
-
--- | Converts a null pointer into 'Nothing' to avoid dangling FFI handles.
-guardNull :: Ptr a -> Maybe (Ptr a)
-guardNull p | p == nullPtr = Nothing
-guardNull p = Just p
-
-foreign import ccall "wlr_seat_set_keyboard"
- foreign_wlrSetSeatKeyboard ::
- Ptr ForeignWlrSeat -> Ptr ForeignWlrInputDevice -> IO ()
-
--- | Binds the given input device as the active keyboard for a seat.
-setSeatKeyboard :: WlrSeat -> WlrInputDevice -> IO ()
-setSeatKeyboard (WlrSeat p1) (WlrInputDevice p2) =
- foreign_wlrSetSeatKeyboard p1 p2
-
-foreign import ccall "wlr_seat_get_keyboard"
- foreign_wlrSeatGetKeyboard ::
- Ptr ForeignWlrSeat -> IO (Ptr ForeignWlrKeyboard)
-
--- | Looks up the current keyboard for a seat, if one exists.
-getSeatKeyboard :: WlrSeat -> IO (Maybe WlrKeyboard)
-getSeatKeyboard (WlrSeat p) =
- fmap WlrKeyboard . guardNull <$> foreign_wlrSeatGetKeyboard p
-
-foreign import ccall "wlr_keyboard_get_modifiers"
- foreign_wlrKeyboardGetModifiers ::
- Ptr ForeignWlrKeyboard -> IO Word32
-
--- | Returns the current keyboard modifier mask for the keyboard.
-getKeyboardModifiers :: WlrKeyboard -> IO Word32
-getKeyboardModifiers (WlrKeyboard p) = foreign_wlrKeyboardGetModifiers p
-
-foreign import ccall "wlr_seat_keyboard_notify_key"
- foreign_wlrSeatKeyboardNotifyKey ::
- Ptr ForeignWlrSeat -> Word32 -> Word32 -> Word32 -> IO ()
-
--- | Forwards a key event to the seat with time, keycode, and state.
-seatKeyboardNotifyKey :: WlrSeat -> Word32 -> Word32 -> Word32 -> IO ()
-seatKeyboardNotifyKey (WlrSeat p) = foreign_wlrSeatKeyboardNotifyKey p
diff --git a/plug/src/Montis/Base/Foreign/WlRoots/Types.hs b/plug/src/Montis/Base/Foreign/WlRoots/Types.hs
deleted file mode 100644
index c109653..0000000
--- a/plug/src/Montis/Base/Foreign/WlRoots/Types.hs
+++ /dev/null
@@ -1,99 +0,0 @@
-module Montis.Base.Foreign.WlRoots.Types where
-
-import Foreign (IntPtr, Ptr, intPtrToPtr, ptrToIntPtr)
-import Text.Read
-
--- | Opaque foreign type for a wlroots keyboard.
-data ForeignWlrKeyboard
-
-newtype WlrKeyboard where
- WlrKeyboard :: Ptr ForeignWlrKeyboard -> WlrKeyboard
- deriving (Show, Ord, Eq)
-
--- | Opaque foreign type for a wlroots pointer.
-data ForeignWlrPointer
-
-newtype WlrPointer where
- WlrPointer :: Ptr ForeignWlrPointer -> WlrPointer
- deriving (Show, Ord, Eq)
-
--- | Opaque foreign type for wlroots pointer button events.
-data ForeignWlrPointerButtonEvent
-
-newtype WlrPointerButtonEvent where
- WlrPointerButtonEvent :: Ptr ForeignWlrPointerButtonEvent -> WlrPointerButtonEvent
- deriving (Show, Ord, Eq)
-
--- | Opaque foreign type for wlroots pointer motion events.
-data ForeignWlrPointerMotionEvent
-
-newtype WlrPointerMotionEvent where
- WlrPointerMotionEvent :: Ptr ForeignWlrPointerMotionEvent -> WlrPointerMotionEvent
- deriving (Show, Ord, Eq)
-
--- | Opaque foreign type for wlroots absolute pointer motion events.
-data ForeignWlrPointerMotionAbsoluteEvent
-
-newtype WlrPointerMotionAbsoluteEvent where
- WlrPointerMotionAbsoluteEvent :: Ptr ForeignWlrPointerMotionAbsoluteEvent -> WlrPointerMotionAbsoluteEvent
- deriving (Show, Ord, Eq)
-
--- | Opaque foreign type for a wlroots seat.
-data ForeignWlrSeat
-
-newtype WlrSeat where
- WlrSeat :: Ptr ForeignWlrSeat -> WlrSeat
- deriving (Show, Ord, Eq)
-
--- | Opaque foreign type for a wlroots input device.
-data ForeignWlrInputDevice
-
-newtype WlrInputDevice where
- WlrInputDevice :: Ptr ForeignWlrInputDevice -> WlrInputDevice
- deriving (Show, Ord, Eq)
-
--- | Opaque foreign type for wlroots keyboard key events.
-data ForeignWlrEventKeyboardKey
-
-newtype WlrEventKeyboardKey where
- WlrEventKeyboardKey :: Ptr ForeignWlrEventKeyboardKey -> WlrEventKeyboardKey
- deriving (Show, Ord, Eq)
-
--- | Opaque foreign type for xdg-shell surfaces.
-data ForeignWlrXdgSurface
-
--- | Opaque foreign type for XWayland surfaces.
-data ForeignWlrXWaylandSurface
-
--- | Tagged wrapper over surface pointer variants.
-data Surface where
- XdgSurface :: Ptr ForeignWlrXdgSurface -> Surface
- XWaylandSurface :: Ptr ForeignWlrXWaylandSurface -> Surface
- deriving (Ord, Eq)
-
-instance Show Surface where
- show (XdgSurface p) = show (XdgSerializeSurface (ptrToIntPtr p))
- show (XWaylandSurface p) = show (XWaylandSerializeSurface (ptrToIntPtr p))
-
-instance Read Surface where
- readPrec = fmap toSurf readPrec
- where
- -- Rebuild constructors from serialized pointers.
- toSurf (XdgSerializeSurface ip) = XdgSurface (intPtrToPtr ip)
- toSurf (XWaylandSerializeSurface ip) = XWaylandSurface (intPtrToPtr ip)
-
--- | Serializable version of 'Surface' to enable Read/Show.
-data SerializableSurface
- = XdgSerializeSurface IntPtr
- | XWaylandSerializeSurface IntPtr
- deriving (Read, Show)
-
-class ForeignSurface a where
- -- | Converts a foreign surface pointer into the tagged wrapper.
- toSurface :: Ptr a -> Surface
-
-instance ForeignSurface ForeignWlrXdgSurface where
- toSurface = XdgSurface
-
-instance ForeignSurface ForeignWlrXWaylandSurface where
- toSurface = XWaylandSurface
diff --git a/plug/src/Montis/Core.hs b/plug/src/Montis/Core.hs
deleted file mode 100644
index 5399f1e..0000000
--- a/plug/src/Montis/Core.hs
+++ /dev/null
@@ -1,10 +0,0 @@
-module Montis.Core
- ( module X,
- )
-where
-
-import Montis.Core.Events as X
-import Montis.Core.Monad as X
-import Montis.Core.Runtime as X
-import Montis.Core.Start as X
-import Montis.Core.State as X
diff --git a/plug/src/Montis/Core/Events.hs b/plug/src/Montis/Core/Events.hs
deleted file mode 100644
index 91b8618..0000000
--- a/plug/src/Montis/Core/Events.hs
+++ /dev/null
@@ -1,46 +0,0 @@
-module Montis.Core.Events where
-
-import Data.Word (Word32)
-import Montis.Base.Foreign.WlRoots.Types
-
-data KeyState = KeyPressed | KeyReleased deriving (Show, Read, Eq, Enum, Ord)
-
-data KeyEvent = KeyEvent
- { keyEvent_timeMs :: Word32,
- keyEvent_keycode :: Word32,
- keyEvent_state :: KeyState,
- keyEvent_modifiers :: Word32,
- keyEvent_keysym :: Word32,
- keyEvent_codepoint :: Char,
- keyEvent_device :: WlrInputDevice
- }
- deriving (Show, Ord, Eq)
-
-data ButtonState = ButtonReleased | ButtonPressed deriving (Show, Read, Eq, Enum, Ord)
-
-data ButtonEvent = ButtonEvent
- { buttonEvent_pointer :: WlrPointer,
- buttonEvent_timeMs :: Word32,
- buttonEvent_button :: Word32,
- buttonEvent_modifiers :: Word32,
- buttonEvent_state :: ButtonState
- }
- deriving (Eq, Show, Ord)
-
-data MotionEvent = MotionEvent
- { motionEvent_pointer :: WlrPointer,
- motionEvent_timeMs :: Word32,
- motionEvent_modifiers :: Word32,
- motionEvent_absolute :: (Double, Double),
- motionEvent_raw :: (Double, Double)
- }
- deriving (Eq, Show, Ord)
-
-data SurfaceState = Map | Unmap | Destroy
- deriving (Eq, Ord, Show, Read, Enum)
-
-data SurfaceEvent = SurfaceEvent
- { surfaceEvent_state :: SurfaceState,
- surfaceEvent_surface :: Surface
- }
- deriving (Eq, Ord, Show)
diff --git a/plug/src/Montis/Core/Extensions.hs b/plug/src/Montis/Core/Extensions.hs
deleted file mode 100644
index 0e8384f..0000000
--- a/plug/src/Montis/Core/Extensions.hs
+++ /dev/null
@@ -1,30 +0,0 @@
-module Montis.Core.Extensions where
-
-import Data.Data
- ( Typeable,
- tyConModule,
- tyConName,
- tyConPackage,
- )
-import Data.Kind (Constraint, Type)
-import Text.Printf (printf)
-import Type.Reflection (someTypeRep, someTypeRepTyCon)
-
--- | A key to key into the Extension maps.
-data ExtensionKey where
- ExtensionKey :: {extensionKeyValue :: String} -> ExtensionKey
- deriving (Eq, Ord, Show)
-
-data Extension (c :: Type -> Constraint) where
- Extension :: (Typeable a, c a) => a -> Extension c
-
-class Nil a
-instance Nil a
-
--- | Produces a string representation of a type used to key into the extensible
--- state map.
-typeRepr :: forall proxy a. (Typeable a) => proxy a -> ExtensionKey
-typeRepr proxy = ExtensionKey $ tyconToStr $ someTypeRepTyCon (someTypeRep proxy)
- where
- tyconToStr tc =
- printf "%s.%s.%s" (tyConPackage tc) (tyConModule tc) (tyConName tc)
diff --git a/plug/src/Montis/Core/Internal/Foreign/Export.hs b/plug/src/Montis/Core/Internal/Foreign/Export.hs
deleted file mode 100644
index faa1964..0000000
--- a/plug/src/Montis/Core/Internal/Foreign/Export.hs
+++ /dev/null
@@ -1,226 +0,0 @@
--- | This module has no public functions, but provides the surface interface
--- between the Montis runtime and the plugin.
-module Montis.Core.Internal.Foreign.Export () where
-
-import Control.Monad (forM_)
-import Control.Monad.State (MonadIO (liftIO), gets)
-import Data.ByteString qualified as BS
-import Data.ByteString.Char8 qualified as CH
-import Data.Singletons.Decide (Void)
-import Foreign
- ( Ptr,
- Storable (poke, pokeByteOff),
- Word32,
- Word8,
- deRefStablePtr,
- freeStablePtr,
- mallocBytes,
- newStablePtr,
- )
-import Foreign.C (CChar, CDouble (..), CInt (..))
-import Foreign.Ptr (castPtr)
-import Montis.Base.Foreign.WlRoots.Types
- ( ForeignSurface (toSurface),
- ForeignWlrInputDevice,
- ForeignWlrPointer,
- ForeignWlrXWaylandSurface,
- ForeignWlrXdgSurface,
- WlrEventKeyboardKey,
- WlrInputDevice (WlrInputDevice),
- WlrPointer (WlrPointer),
- WlrPointerButtonEvent,
- )
-import Montis.Core
-import Montis.Core.State
-import Montis.Core.State.Marshal (marshalState)
-import Montis.Foreign.Marshal (Demarshal (Demarshal), demarshal, runDemarshal)
-
--- | Helpers to unpack the opaque state, run a Montis action, and re-wrap it.
--- Each call consumes the old stable pointer and returns a fresh one.
-runForeign ::
- Montis () ->
- OpqStT ->
- IO OpqStT
-runForeign fn stableptr = do
- (ctx, st) <- deRefStablePtr stableptr
- freeStablePtr stableptr
- (_, state') <- runMontis ctx st fn
- newStablePtr (ctx, state')
-
-runForeignWithReturn ::
- (Storable a) =>
- Montis a ->
- Ptr a ->
- OpqStT ->
- IO OpqStT
-runForeignWithReturn fn outptr stableptr = do
- (ctx, st) <- deRefStablePtr stableptr
- freeStablePtr stableptr
- (val, state') <- runMontis ctx st fn
- poke outptr val
- newStablePtr (ctx, state')
-
--- ----------------------------------------------------------------------
--- State marshal/export
-
--- | Marshals the opaque state to a C-style byte array and size pointer.
-foreign export ccall "plugin_marshal_state"
- pluginMarshalState :: OpqStT -> Ptr Word32 -> IO (Ptr Word8)
-
-pluginMarshalState :: OpqStT -> Ptr Word32 -> IO (Ptr Word8)
-pluginMarshalState opqStT outlen = do
- (_, st) <- deRefStablePtr opqStT
- let bs = CH.pack (marshalState st)
- ret <- mallocBytes (BS.length bs)
- poke outlen (fromIntegral $ BS.length bs)
- forM_ (zip [0 ..] (BS.unpack bs)) $ \(off, w8) -> do
- pokeByteOff ret off w8
- return ret
-
--- ----------------------------------------------------------------------
--- Input handlers
-
-foreign export ccall "plugin_handle_button"
- pluginHandleButton :: Ptr WlrPointerButtonEvent -> Word32 -> OpqStT -> IO OpqStT
-
-pluginHandleButton :: Ptr WlrPointerButtonEvent -> Word32 -> OpqStT -> IO OpqStT
-pluginHandleButton eventPtr modifiers =
- runForeign $ do
- s <- gets currentHooks
- event <- liftIO $
- runDemarshal eventPtr $ do
- -- Follows struct wlr_pointer_button_event field order.
- pointerPtr <- demarshal :: Demarshal (Ptr ForeignWlrPointer)
- tMs <- demarshal
- button <- demarshal
- state <- demarshal :: Demarshal Word8
- return $
- ButtonEvent
- (WlrPointer pointerPtr)
- tMs
- button
- modifiers
- (if state == (0 :: Word8) then ButtonReleased else ButtonPressed)
-
- buttonHook s event
-
--- ----------------------------------------------------------------------
--- Keybinding handler
-
-foreign export ccall "plugin_handle_keybinding"
- pluginHandleKeybinding ::
- Ptr ForeignWlrInputDevice ->
- Ptr WlrEventKeyboardKey ->
- Word32 ->
- Word32 ->
- Word32 ->
- Ptr CInt ->
- OpqStT ->
- IO OpqStT
-
-pluginHandleKeybinding ::
- Ptr ForeignWlrInputDevice ->
- Ptr WlrEventKeyboardKey ->
- Word32 ->
- Word32 ->
- Word32 ->
- Ptr CInt ->
- OpqStT ->
- IO OpqStT
-pluginHandleKeybinding inputDevicePtr eventPtr mods sym cp =
- runForeignWithReturn $ do
- s <- gets currentHooks
- event <- liftIO $
- runDemarshal eventPtr $ do
- -- Matches struct wlr_keyboard_key_event in wlroots.
- tMs <- demarshal
- kc <- demarshal
- _ <- (demarshal :: Demarshal Word32)
- keyState <- demarshal
- return $
- KeyEvent
- tMs
- kc
- (if keyState == (0 :: Word8) then KeyReleased else KeyPressed)
- mods
- sym
- (toEnum $ fromIntegral cp)
- (WlrInputDevice inputDevicePtr)
-
- keyHook s event
- return 1
-
--- ----------------------------------------------------------------------
--- Motion handler
-
-foreign export ccall "plugin_handle_motion"
- pluginHandleMotion :: Ptr Void -> Word32 -> Word32 -> CDouble -> CDouble -> OpqStT -> IO OpqStT
-
-pluginHandleMotion :: Ptr Void -> Word32 -> Word32 -> CDouble -> CDouble -> OpqStT -> IO OpqStT
-pluginHandleMotion eventPtr modifiers isAbsolute lx ly =
- runForeign $ do
- s <- gets currentHooks
- event <- liftIO $
- if isAbsolute == 0
- then
- runDemarshal (castPtr eventPtr) $ do
- pointerPtr <- demarshal :: Demarshal (Ptr ForeignWlrPointer)
- tMs <- demarshal
- _ <- demarshal :: Demarshal Word32
- _ <- demarshal :: Demarshal Double
- _ <- demarshal :: Demarshal Double
- _ <- demarshal :: Demarshal Double
- _ <- demarshal :: Demarshal Double
- return $
- MotionEvent
- (WlrPointer pointerPtr)
- tMs
- modifiers
- (realToFrac lx, realToFrac ly)
- (0, 0)
- else
- runDemarshal (castPtr eventPtr) $ do
- -- After time_msec, wlroots pads to 8-byte alignment for doubles.
- pointerPtr <- demarshal :: Demarshal (Ptr ForeignWlrPointer)
- tMs <- demarshal
- _ <- demarshal :: Demarshal Word32
- rawX <- demarshal
- rawY <- demarshal
- return $
- MotionEvent
- (WlrPointer pointerPtr)
- tMs
- modifiers
- (realToFrac lx, realToFrac ly)
- (rawX, rawY)
-
- motionHook s event
-
--- ----------------------------------------------------------------------
--- Surface handlers
-
--- | Function exported to the harness to handle the mapping/unmapping/deletion
--- of an XDG surface.
-foreign export ccall "plugin_handle_surface"
- pluginHandleSurface ::
- Ptr ForeignWlrXdgSurface -> CInt -> OpqStT -> IO OpqStT
-
-pluginHandleSurface ::
- Ptr ForeignWlrXdgSurface -> CInt -> OpqStT -> IO OpqStT
-pluginHandleSurface p t =
- runForeign $ do
- s <- gets currentHooks
- surfaceHook s (SurfaceEvent (toEnum $ fromIntegral t) (toSurface p))
-
--- | Function exported to the harness to handle the mapping/unmapping/deletion
--- of an XWayland surface.
-foreign export ccall "plugin_handle_xwayland_surface"
- pluginHandleXWaylandSurface ::
- Ptr ForeignWlrXWaylandSurface -> CInt -> OpqStT -> IO OpqStT
-
-pluginHandleXWaylandSurface ::
- Ptr ForeignWlrXWaylandSurface -> CInt -> OpqStT -> IO OpqStT
-pluginHandleXWaylandSurface p t =
- runForeign $ do
- s <- gets currentHooks
- surfaceHook s (SurfaceEvent (toEnum $ fromIntegral t) (toSurface p))
diff --git a/plug/src/Montis/Core/Monad.hs b/plug/src/Montis/Core/Monad.hs
deleted file mode 100644
index b7d1633..0000000
--- a/plug/src/Montis/Core/Monad.hs
+++ /dev/null
@@ -1,125 +0,0 @@
-{-# LANGUAGE RankNTypes #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-
-module Montis.Core.Monad where
-
-import Control.Monad.Identity (Identity (Identity))
-import Control.Monad.Reader
-import Control.Monad.State (MonadState, StateT (runStateT), gets, modify')
-import Data.Default.Class (Default (def))
-import Data.Map qualified as Map
-import Data.Maybe (fromMaybe)
-import Data.Typeable
-import Foreign (StablePtr)
-import Montis.Core.Extensions (Extension (Extension), typeRepr)
-import Montis.Core.State
-
--- | A Config type for the Montis monad.
-type MontisConfig = Config Montis
-
--- | A Context type specific for the Montis monad.
-type MontisContext = Context Montis
-
--- | A State type for the Montis monad.
-type MontisState = State Montis
-
--- | The Opaque State Type passed between the plugin and the runtime. The
--- OpqStT *is* the opq_st_t from the runtime code.
-type OpqStT = StablePtr (MontisContext, MontisState)
-
--- | The Montis monad is a Reader over an immutable context plus a State over
--- mutable runtime state, all ultimately running in IO for host effects.
-newtype Montis a where
- Montis :: (ReaderT MontisContext (StateT MontisState IO) a) -> Montis a
- deriving (Functor, Applicative, Monad, MonadState MontisState, MonadIO)
-
--- | Reader access is scoped to the config portion of the full context; this
--- keeps plugin code from mutating the context while still allowing read-only
--- access to configuration.
-instance MonadReader MontisConfig Montis where
- ask :: Montis MontisConfig
- ask = Montis $ asks ctxConfig
-
- reader :: (MontisConfig -> a) -> Montis a
- reader fn = Montis $ asks (fn . ctxConfig)
-
- local :: (MontisConfig -> MontisConfig) -> Montis a -> Montis a
- local cfn (Montis fn) =
- Montis $ local (\ctx -> ctx {ctxConfig = cfn (ctxConfig ctx)}) fn
-
--- | Access the plugin self pointer stored in the context.
-getSelfPtr :: Montis SelfPtr
-getSelfPtr = Montis $ asks ctxSelfPtr
-
--- | Run a Montis action with a fixed context and initial state, returning the
--- result value and the updated state.
-runMontis :: MontisContext -> MontisState -> Montis a -> IO (a, MontisState)
-runMontis ctx initState (Montis m) = runStateT (runReaderT m ctx) initState
-
--- | The standard default config.
-defaultConfig :: MontisConfig
-defaultConfig =
- Config
- { startingHooks =
- Hooks
- { keyHook = const (return ()),
- surfaceHook = const (return ()),
- buttonHook = const (return ()),
- motionHook = const (return ())
- },
- -- Default hooks are no-ops except for basic printing, which makes the
- -- system usable without extra wiring during development.
- startupHook = return (),
- resetHook = return (),
- -- Extensions start empty; callers can register config extensions as needed.
- configExtensions = mempty
- }
-
--- | Store a typed extension in the extensible state map under its TypeRep.
--- The value is wrapped so the map remains heterogeneously typed.
-xStatePut :: forall a. (StateExtension a) => a -> Montis ()
-xStatePut xst = do
- modify'
- ( \st ->
- st
- { extensibleState =
- Map.insert
- (typeRepr (Identity xst))
- (Right (Extension xst))
- (extensibleState st)
- }
- )
-
--- | Retrieve a typed extension, demarshalling it if needed and caching it back.
--- When the extension is stored in marshalled form, it is decoded and then
--- reinserted so future lookups are fast.
-xStateGet :: forall a. (StateExtension a) => Montis a
-xStateGet = do
- mp <- gets extensibleState
- case lookupByType (Proxy :: Proxy a) mp of
- Nothing -> return initialValue
- Just (Right (Extension v)) -> return $ fromMaybe initialValue (cast v)
- Just (Left s) -> do
- let x = (demarshalExtension s :: Maybe a)
- in forM_ x xStatePut >> return (fromMaybe initialValue x)
-
--- | Modifies the typed extension bi the given function.
-xStateModify :: forall a. (StateExtension a) => (a -> a) -> Montis ()
-xStateModify fn = do
- s <- xStateGet
- (xStatePut . fn) s
-
-xStateModifyM :: forall a. (StateExtension a) => (a -> Montis a) -> Montis ()
-xStateModifyM fn = do
- s <- xStateGet
- xStatePut =<< fn s
-
--- | Retrieve a typed configuration extension or return the default
--- instance if the extension had not been configured.
-xConfigGet :: forall a. (Typeable a, Default a) => Montis a
-xConfigGet = do
- exts <- asks configExtensions
- return $
- fromMaybe def $
- Map.lookup (typeRepr (Proxy :: Proxy a)) exts
- >>= (\(Extension a) -> cast a)
diff --git a/plug/src/Montis/Core/Plugin/Interface.hs b/plug/src/Montis/Core/Plugin/Interface.hs
deleted file mode 100644
index 73c0371..0000000
--- a/plug/src/Montis/Core/Plugin/Interface.hs
+++ /dev/null
@@ -1,20 +0,0 @@
--- | Provides the plugin interface through foreign exports.
-module Montis.Core.Plugin.Interface where
-
-import Data.ByteString (ByteString)
-import Data.Data (Typeable)
-import Data.Singletons.Decide (Void)
-import Foreign (Ptr, StablePtr, Word32)
-import Foreign.C (CChar)
-import Montis.Core.State (SelfPtr)
-
--- type OpqStT l w = StablePtr (Context l w, State l w)
-
-class OpaqueState s where
- hotStart :: SelfPtr -> ByteString -> IO s
-
- coldStart :: SelfPtr -> IO s
-
- marshalState :: s -> ByteString
-
- teardown :: s -> IO ()
diff --git a/plug/src/Montis/Core/Runtime.hs b/plug/src/Montis/Core/Runtime.hs
deleted file mode 100644
index 0d4c905..0000000
--- a/plug/src/Montis/Core/Runtime.hs
+++ /dev/null
@@ -1,82 +0,0 @@
-module Montis.Core.Runtime
- ( ToplevelHandle,
- focusToplevel,
- getSeat,
- getToplevelGeometry,
- setToplevelGeometry,
- setToplevelPosition,
- toplevelAt,
- warpCursor,
- )
-where
-
-import Control.Monad.IO.Class (liftIO)
-import Data.Void (Void)
-import Foreign (Ptr)
-import Foreign.C (CDouble (..))
-import Foreign.Marshal.Alloc (alloca)
-import Foreign.Ptr (castPtr, nullPtr)
-import Foreign.Storable (peek)
-import Montis.Base.Foreign.Runtime
-import Montis.Base.Foreign.WlRoots.Types (ForeignWlrSeat, WlrSeat (WlrSeat))
-import Montis.Core.Monad (Montis, getSelfPtr)
-import Montis.Core.State (SelfPtr (..))
-
-type ToplevelHandle = Ptr ForeignMontisToplevel
-
-unwrapSelf :: SelfPtr -> Ptr Void
-unwrapSelf (SelfPtr p) = p
-
-getSeat :: Montis (Maybe WlrSeat)
-getSeat = do
- self <- getSelfPtr
- seatPtr <- liftIO $ foreign_getSeat (unwrapSelf self)
- if seatPtr == nullPtr
- then return Nothing
- else return $ Just (WlrSeat (castPtr seatPtr :: Ptr ForeignWlrSeat))
-
-toplevelAt :: Double -> Double -> Montis (Maybe ToplevelHandle)
-toplevelAt lx ly = do
- self <- getSelfPtr
- tl <- liftIO $ foreign_toplevelAt (unwrapSelf self) (realToFrac lx) (realToFrac ly)
- if tl == nullPtr
- then return Nothing
- else return (Just tl)
-
-getToplevelGeometry :: ToplevelHandle -> Montis (Double, Double, Double, Double)
-getToplevelGeometry tl =
- liftIO $
- alloca $ \xPtr -> alloca $ \yPtr -> alloca $ \wPtr -> alloca $ \hPtr -> do
- foreign_getToplevelGeometry tl xPtr yPtr wPtr hPtr
- x <- peek xPtr
- y <- peek yPtr
- w <- peek wPtr
- h <- peek hPtr
- return
- ( realToFrac (x :: CDouble),
- realToFrac (y :: CDouble),
- realToFrac (w :: CDouble),
- realToFrac (h :: CDouble)
- )
-
-setToplevelGeometry :: ToplevelHandle -> Double -> Double -> Double -> Double -> Montis ()
-setToplevelGeometry tl x y w h =
- liftIO $
- foreign_setToplevelGeometry
- tl
- (realToFrac x)
- (realToFrac y)
- (realToFrac w)
- (realToFrac h)
-
-setToplevelPosition :: ToplevelHandle -> Double -> Double -> Montis ()
-setToplevelPosition tl x y =
- liftIO $ foreign_setToplevelPosition tl (realToFrac x) (realToFrac y)
-
-focusToplevel :: ToplevelHandle -> Montis ()
-focusToplevel tl = liftIO $ foreign_focusToplevel tl
-
-warpCursor :: Double -> Double -> Montis ()
-warpCursor lx ly = do
- self <- getSelfPtr
- liftIO $ foreign_warpCursor (unwrapSelf self) (realToFrac lx) (realToFrac ly)
diff --git a/plug/src/Montis/Core/Start.hs b/plug/src/Montis/Core/Start.hs
deleted file mode 100644
index 54ec8c5..0000000
--- a/plug/src/Montis/Core/Start.hs
+++ /dev/null
@@ -1,38 +0,0 @@
-module Montis.Core.Start where
-
-import Data.ByteString qualified as BS
-import Data.ByteString.Char8 qualified as CH
-import Data.Void
-import Foreign (Word32, newStablePtr)
-import Foreign.C (CChar)
-import Foreign.Ptr
-import Montis.Core.Monad
-import Montis.Core.State
-import Montis.Core.State.Marshal (demarshalState)
-
-type MontisColdStart = Ptr Void -> IO OpqStT
-
-type MontisHotStart = Ptr Void -> Ptr CChar -> Word32 -> IO OpqStT
-
-hotStartMontis :: MontisConfig -> MontisHotStart
-hotStartMontis config self chars len = do
- bs <- BS.packCStringLen (chars, fromIntegral len)
-
- let ctx = Context config (SelfPtr self)
- st = demarshalState config (CH.unpack bs)
-
- ((), st') <- runMontis ctx st (resetHook config)
- newStablePtr (ctx, st')
-
--- Used to start montis given the provided config.
-coldStartMontis :: MontisConfig -> MontisColdStart
-coldStartMontis conf selfPtr =
- let ctx = Context conf (SelfPtr selfPtr)
- st =
- State
- { currentHooks = startingHooks conf,
- extensibleState = mempty
- }
- in do
- ((), st') <- runMontis ctx st (startupHook conf)
- newStablePtr (ctx, st')
diff --git a/plug/src/Montis/Core/State.hs b/plug/src/Montis/Core/State.hs
deleted file mode 100644
index ce8f903..0000000
--- a/plug/src/Montis/Core/State.hs
+++ /dev/null
@@ -1,116 +0,0 @@
--- | Definitions of montis core state.
-module Montis.Core.State where
-