diff options
| author | Josh Rahm <joshuarahm@gmail.com> | 2026-01-06 15:09:52 -0700 |
|---|---|---|
| committer | Josh Rahm <joshuarahm@gmail.com> | 2026-01-06 15:09:52 -0700 |
| commit | 68dd63f6b3de774863051b66e609a0ca4f4ac2a1 (patch) | |
| tree | a908ebced56be6fc14307b1a1dc304c47905f8e2 /plug/src | |
| parent | 12f8ef6dbf8618aaa304d239fbfd3c1b7b4494d3 (diff) | |
| download | montis-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.hs | 33 | ||||
| -rw-r--r-- | plug/src/Link.hs | 18 | ||||
| -rw-r--r-- | plug/src/Montis/Base/Foreign/Runtime.hs | 37 | ||||
| -rw-r--r-- | plug/src/Montis/Base/Foreign/WlRoots.hs | 44 | ||||
| -rw-r--r-- | plug/src/Montis/Base/Foreign/WlRoots/Types.hs | 99 | ||||
| -rw-r--r-- | plug/src/Montis/Core.hs | 10 | ||||
| -rw-r--r-- | plug/src/Montis/Core/Events.hs | 46 | ||||
| -rw-r--r-- | plug/src/Montis/Core/Extensions.hs | 30 | ||||
| -rw-r--r-- | plug/src/Montis/Core/Internal/Foreign/Export.hs | 226 | ||||
| -rw-r--r-- | plug/src/Montis/Core/Monad.hs | 125 | ||||
| -rw-r--r-- | plug/src/Montis/Core/Plugin/Interface.hs | 20 | ||||
| -rw-r--r-- | plug/src/Montis/Core/Runtime.hs | 82 | ||||
| -rw-r--r-- | plug/src/Montis/Core/Start.hs | 38 | ||||
| -rw-r--r-- | plug/src/Montis/Core/State.hs | 116 | ||||
| -rw-r--r-- | plug/src/Montis/Core/State/Marshal.hs | 44 | ||||
| -rw-r--r-- | plug/src/Montis/Foreign/Marshal.hs | 20 | ||||
| -rw-r--r-- | plug/src/Montis/Standard/Drag.hs | 123 | ||||
| -rw-r--r-- | plug/src/Montis/Standard/Keys.hs | 110 | ||||
| -rw-r--r-- | plug/src/Montis/Standard/Mouse.hs | 50 | ||||
| -rw-r--r-- | plug/src/harness_adapter.c | 73 |
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 - |