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 | |
| 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')
24 files changed, 0 insertions, 1501 deletions
diff --git a/plug/README.md b/plug/README.md deleted file mode 100644 index 5592f08..0000000 --- a/plug/README.md +++ /dev/null @@ -1 +0,0 @@ -The Plugin for the Montis Runtime. diff --git a/plug/package.yaml b/plug/package.yaml deleted file mode 100644 index bd42ced..0000000 --- a/plug/package.yaml +++ /dev/null @@ -1,87 +0,0 @@ -name: montis - -github: "jrahm/montis" -license: BSD-3-Clause -author: "Author name here" -maintainer: "example@example.com" -copyright: "2024 Author name here" - -extra-source-files: -- README.md - -# Metadata used when publishing your package -# synopsis: Short description of your package -# category: Web - -# To avoid duplicated efforts in documentation and dealing with the -# complications of embedding Haddock markup inside cabal files, it is -# common to point users to the README.md file. -description: Please see the README on GitHub at <https://github.com/githubuser/montis#readme> - - -dependencies: -- base >= 4.7 && < 5 -- mtl -- bytestring -- containers -- data-default-class -- transformers -- monad-loops -- singletons - - -ghc-options: -- -Wall -- -Wcompat -- -Widentities -- -Wincomplete-record-updates -- -Wincomplete-uni-patterns -- -Wmissing-export-lists -- -Wmissing-home-modules -- -Wpartial-fields -- -Wredundant-constraints -- -XGHC2021 -- -XTypeFamilies -- -XUndecidableInstances -- -XGADTs -- -XFunctionalDependencies -- -XUndecidableSuperClasses -- -XDefaultSignatures -- -XViewPatterns -- -XDerivingVia -- -XDisambiguateRecordFields -- -XLambdaCase -- -XDataKinds -- -fPIC - -executables: - montis.so: - main: Config.hs - source-dirs: src - c-sources: src/harness_adapter.c - ghc-options: - - -shared - - -dynamic - - -no-hs-main - - -lHSrts-1.0.2-ghc9.4.7 - - -O3 - cc-options: - - -g3 - - -O2 - - -shared - - -I../build/ - - -I../rt/include/ - - -I../build/wlroots/include - - -I../build/wlroots-src/include - - -DWLR_USE_UNSTABLE - -tests: - montis-test: - main: Spec.hs - source-dirs: test - ghc-options: - - -threaded - - -rtsopts - - -with-rtsopts=-N - dependencies: - - montis 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 - -import Data.Data (Proxy (Proxy), Typeable) -import Data.Default.Class (Default, def) -import Data.Map qualified as M -import Data.Void (Void) -import Foreign (Ptr) -import Montis.Core.Events -import Montis.Core.Extensions -import Text.Read (readMaybe) - --- | An opaque type used for the plugin's self-reference. -newtype SelfPtr where - SelfPtr :: Ptr Void -> SelfPtr - --- | This is the context the plugin operates under. The context contains data --- which must be provided by the runtime or the configuration. This data may not --- be cold-created. --- --- Parameters: --- `m` the monad for this Context. This is typically W. -data Context m where - Context :: - { ctxConfig :: Config m, - ctxSelfPtr :: SelfPtr - } -> - Context m - --- | Montis configuration. This is the structure that defines the user-written --- configuration, which is linked in. -data Config m where - Config :: - { startingHooks :: Hooks m, - startupHook :: m (), - resetHook :: m (), - configExtensions :: M.Map ExtensionKey (Extension Nil) - } -> - Config m - --- | Hooks the runtime can call. -data Hooks m where - Hooks :: - { keyHook :: KeyEvent -> m (), - surfaceHook :: SurfaceEvent -> m (), - buttonHook :: ButtonEvent -> m (), - motionHook :: MotionEvent -> m () - } -> - Hooks m - --- | Class for a configurable model. -class (Typeable a) => ConfigModule m a where - alterConfig :: a -> Config m -> Config m - --- | Configures a typed configuration extension. -install :: forall a m. (ConfigModule m a) => a -> Config m -> Config m -install a c = - alterConfig a $ - c - { configExtensions = - M.insert - (typeRepr (Proxy :: Proxy a)) - (Extension a) - (configExtensions c) - } - --- | Typeclass defining the set of types which can be used as state extensions --- to the W monad. These state extensions may be persistent or not. --- --- There are default implementations for all methods if the type implements --- Read, Show and Default, -class (Typeable a) => StateExtension a where - -- | The initial value used for the first time an extension is 'gotten' or - -- demarshalling fails. - initialValue :: a - - -- | Transforms a type into a string. If the type cannot be marshalled, this - -- function should return Nothing. - -- - -- If a type cannot be marshalled, it cannot persist across hot reloads. - marshalExtension :: a -> Maybe String - - -- | Reads an extension from a string. If this type is not marshallable or - -- reading fails, this function should return Nothing. - demarshalExtension :: String -> Maybe a - - -- | If the type implements Default, use the default implementation. - default initialValue :: (Default a) => a - initialValue = def - - -- | If the type implements Show, use show for the marshalling. - default marshalExtension :: (Show a) => a -> Maybe String - marshalExtension = Just . show - - -- | If the type implements Read, use read for the demarshalling. - default demarshalExtension :: (Read a) => String -> Maybe a - demarshalExtension = readMaybe - --- | State type. This type contains changeable data. -data State m where - State :: - { -- The datastructure containing the state of the windows. - - -- | Current set of hooks. The initial hooks are provided by the - -- configuration, but the hooks can change during operation. This is how - -- key sequences can be mapped. - currentHooks :: Hooks m, - -- | Map from the typerep string to the state extension. - extensibleState :: - M.Map ExtensionKey (Either String (Extension StateExtension)) - } -> - State m - --- | Lookup from an extension map by type. -lookupByType :: (Typeable a) => proxy a -> M.Map ExtensionKey b -> Maybe b -lookupByType pxy = M.lookup (typeRepr pxy) diff --git a/plug/src/Montis/Core/State/Marshal.hs b/plug/src/Montis/Core/State/Marshal.hs deleted file mode 100644 index 04a2a57..0000000 --- a/plug/src/Montis/Core/State/Marshal.hs +++ /dev/null @@ -1,44 +0,0 @@ -module Montis.Core.State.Marshal (marshalState, demarshalState) where - -import Data.Map qualified as M -import Data.Maybe (mapMaybe) -import Montis.Core.Extensions -import Montis.Core.State - -data MarshalledState where - MarshalledState :: - [(String, String)] -> - MarshalledState - deriving (Show, Read) - --- | Marshals the serializable parts of the state to a string. This happens --- during a hot-reload where some state must be saved to persist across hot --- reloads. --- Only the extensible state is persisted; hooks and other runtime data are --- reconstructed from the config on restart. -marshalState :: State m -> String -marshalState - ( State - { extensibleState = xs - } - ) = - show $ - MarshalledState - (mapMaybe (\(k, v) -> (extensionKeyValue k,) <$> doMarshalEx v) (M.toList xs)) - where - -- Left values are already marshalled; Right values are re-encoded here. - doMarshalEx :: Either String (Extension StateExtension) -> Maybe String - doMarshalEx (Left s) = Just s - doMarshalEx (Right (Extension a)) = marshalExtension a - --- | Demarshals the string from "marshalState" into a state. Uses the provided --- config to fill out non-persistent parts of the state. --- The extensible map is rehydrated as marshalled strings so decoding can be --- deferred until a specific extension is requested. -demarshalState :: Config m -> String -> State m -demarshalState Config {startingHooks = hooks} str = - State hooks xs - where - ( MarshalledState - (M.mapKeys ExtensionKey . fmap Left . M.fromList -> xs) - ) = read str diff --git a/plug/src/Montis/Foreign/Marshal.hs b/plug/src/Montis/Foreign/Marshal.hs deleted file mode 100644 index 157d928..0000000 --- a/plug/src/Montis/Foreign/Marshal.hs +++ /dev/null @@ -1,20 +0,0 @@ -module Montis.Foreign.Marshal where - -import Control.Monad.State -import Data.Word -import Foreign (Ptr, Storable (peek, sizeOf), castPtr, plusPtr) - -type Offset = Word32 - -newtype Demarshal a = Demarshal (StateT (Ptr ()) IO a) - deriving (Functor, Monad, Applicative, MonadState (Ptr ())) - -runDemarshal :: Ptr b -> Demarshal a -> IO a -runDemarshal p (Demarshal dm) = evalStateT dm (castPtr p) - -demarshal :: (Storable a) => Demarshal a -demarshal = do - ptr <- get - val <- Demarshal $ lift $ peek $ castPtr ptr - put (plusPtr ptr (sizeOf val)) - return val diff --git a/plug/src/Montis/Standard/Drag.hs b/plug/src/Montis/Standard/Drag.hs deleted file mode 100644 index a6ee878..0000000 --- a/plug/src/Montis/Standard/Drag.hs +++ /dev/null @@ -1,123 +0,0 @@ -module Montis.Standard.Drag where - -import Data.Bits ((.&.)) -import Data.Data (Typeable) -import Data.Word (Word32) -import Montis.Core -import Montis.Core.Runtime -import Montis.Core.State - ( Config (startingHooks), - ConfigModule (..), - Hooks (buttonHook, motionHook), - StateExtension (..), - ) -import Montis.Standard.Mouse (CursorPosition (CursorPosition)) - -data DragConfig where - DragConfig :: - { dragModifierMask :: Word32 - } -> - DragConfig - deriving (Typeable) - -instance ConfigModule Montis DragConfig where - alterConfig cfg c = - let ohb = buttonHook (startingHooks c) - ohm = motionHook (startingHooks c) - in c - { startingHooks = - (startingHooks c) - { buttonHook = \ev -> onButton (dragModifierMask cfg) ev >> ohb ev, - motionHook = \ev -> onMotion ev >> ohm ev - } - } - -data DragState = DragState - { dragToplevel :: ToplevelHandle, - dragOffsetX :: Double, - dragOffsetY :: Double - } - deriving (Typeable) - -data ResizeState = ResizeState - { resizeToplevel :: ToplevelHandle, - resizeStartX :: Double, - resizeStartY :: Double, - resizeStartW :: Double, - resizeStartH :: Double, - resizeStartCursorX :: Double, - resizeStartCursorY :: Double - } - deriving (Typeable) - -data DragAction - = DragMove DragState - | DragResize ResizeState - deriving (Typeable) - -newtype Dragging = Dragging (Maybe DragAction) - deriving (Typeable) - -instance StateExtension Dragging where - initialValue = Dragging Nothing - marshalExtension _ = Nothing - demarshalExtension _ = Nothing - -leftButton :: Word32 -leftButton = 272 -- BTN_LEFT - -rightButton :: Word32 -rightButton = 273 -- BTN_RIGHT - -onButton :: Word32 -> ButtonEvent -> Montis () -onButton modMask ev - | buttonEvent_button ev /= leftButton && buttonEvent_button ev /= rightButton = return () - | buttonEvent_state ev == ButtonPressed = do - if buttonEvent_modifiers ev .&. modMask == 0 - then return () - else do - CursorPosition (x, y) <- xStateGet - mtl <- toplevelAt x y - case mtl of - Nothing -> xStatePut (Dragging Nothing) - Just tl -> do - (tx, ty, tw, th) <- getToplevelGeometry tl - if buttonEvent_button ev == rightButton - then do - let warpX = tx + tw - warpY = ty + th - warpCursor warpX warpY - xStatePut (CursorPosition (warpX, warpY)) - xStatePut $ - Dragging - ( Just - ( DragResize - (ResizeState tl tx ty tw th warpX warpY) - ) - ) - else - xStatePut $ - Dragging - (Just (DragMove (DragState tl (x - tx) (y - ty)))) - | buttonEvent_state ev == ButtonReleased = - xStatePut (Dragging Nothing) - | otherwise = return () - -onMotion :: MotionEvent -> Montis () -onMotion ev = do - let (x, y) = motionEvent_absolute ev - xStatePut (CursorPosition (x, y)) - Dragging mdrag <- xStateGet - case mdrag of - Nothing -> return () - Just (DragMove (DragState tl dx dy)) -> - setToplevelPosition tl (x - dx) (y - dy) - Just (DragResize rs) -> do - let newW = max 1 (resizeStartW rs + (x - resizeStartCursorX rs)) - newH = max 1 (resizeStartH rs + (y - resizeStartCursorY rs)) - setToplevelGeometry - (resizeToplevel rs) - (resizeStartX rs) - (resizeStartY rs) - newW - newH diff --git a/plug/src/Montis/Standard/Keys.hs b/plug/src/Montis/Standard/Keys.hs deleted file mode 100644 index 0b670eb..0000000 --- a/plug/src/Montis/Standard/Keys.hs +++ /dev/null @@ -1,110 +0,0 @@ -module Montis.Standard.Keys where - -import Control.Monad (when) -import Control.Monad.IO.Class (liftIO) -import Data.Data (Typeable) -import Data.Default.Class (Default (..)) -import Data.Set qualified as Set -import Data.Word (Word32) -import Montis.Base.Foreign.WlRoots (seatKeyboardNotifyKey) -import Montis.Core.Events (KeyEvent (..), KeyState (..)) -import Montis.Core.Monad (Montis, xConfigGet, xStateGet, xStateModify) -import Montis.Core.Runtime (getSeat) -import Montis.Core.State - ( Config (startingHooks), - ConfigModule (..), - Hooks (keyHook), - StateExtension (..), - ) - --- | Configuration for the keybindings. -data KeysConfig where - KeysConfig :: - { startCont :: KeyEvent -> Montis Bool - } -> - KeysConfig - deriving (Typeable) - -instance Default KeysConfig where - def = KeysConfig $ \_ -> return False - -subkeys :: (KeyEvent -> Montis Bool) -> Montis Bool -subkeys fn = do - xStateModify $ \keyState -> - keyState - { awaiting = Just fn - } - return True - --- | State of the keys right now. -data KeysState where - KeysState :: - { awaiting :: Maybe (KeyEvent -> Montis Bool), - ignoredKeys :: Set.Set Word32 - } -> - KeysState - -instance StateExtension KeysState where - initialValue = KeysState Nothing Set.empty - marshalExtension = const Nothing - demarshalExtension = const Nothing - --- | Configurable module for keys. -instance ConfigModule Montis KeysConfig where - alterConfig _ c = - let oh = keyHook (startingHooks c) - in c - { startingHooks = - (startingHooks c) - { keyHook = \ev -> runEv ev >> oh ev - } - } - where - isKeyPress ev = keyEvent_state ev == KeyPressed - isKeyRelease ev = keyEvent_state ev == KeyReleased - shouldIgnoreEvent ev = do - KeysState {ignoredKeys} <- xStateGet - return $ Set.member (keyEvent_keycode ev) ignoredKeys - runEv ev = do - shouldIgnore <- shouldIgnoreEvent ev - if isKeyRelease ev && shouldIgnore - then xStateModify $ \ks -> - ks {ignoredKeys = Set.delete (keyEvent_keycode ev) (ignoredKeys ks)} - else do - handled <- - if isKeyPress ev - then do - handler' <- awaiting <$> xStateGet - handler <- maybe (startCont <$> xConfigGet) return handler' - -- Reset the hadler. - xStateModify $ \st -> - st {awaiting = Nothing} - handler ev - else return False - - if not handled - then forwardKeyToSeat ev - else when (isKeyPress ev) $ - xStateModify $ - \ks -> - ks - { ignoredKeys = - Set.insert (keyEvent_keycode ev) (ignoredKeys ks) - } - -forwardKeyToSeat :: KeyEvent -> Montis () -forwardKeyToSeat ev = do - mseat <- getSeat - case mseat of - Nothing -> return () - Just seat -> - liftIO $ - seatKeyboardNotifyKey - seat - (keyEvent_timeMs ev) - (keyEvent_keycode ev) - (keyStateToWord32 (keyEvent_state ev)) - -keyStateToWord32 :: KeyState -> Word32 -keyStateToWord32 KeyReleased = 0 -keyStateToWord32 KeyPressed = 1 diff --git a/plug/src/Montis/Standard/Mouse.hs b/plug/src/Montis/Standard/Mouse.hs deleted file mode 100644 index 933a2f4..0000000 --- a/plug/src/Montis/Standard/Mouse.hs +++ /dev/null @@ -1,50 +0,0 @@ -module Montis.Standard.Mouse where - -import Data.Data (Typeable) -import Montis.Core -import Montis.Core.Runtime (focusToplevel, toplevelAt) -import Montis.Core.State - ( Config (startingHooks), - ConfigModule (..), - Hooks (buttonHook, motionHook), - StateExtension (..), - ) - -data MouseConfig where - MouseConfig :: MouseConfig - deriving (Typeable) - -instance ConfigModule Montis MouseConfig where - alterConfig _ c = - let ohb = buttonHook (startingHooks c) - ohm = motionHook (startingHooks c) - in c - { startingHooks = - (startingHooks c) - { buttonHook = \ev -> onButton ev >> ohb ev, - motionHook = \ev -> onMotion ev >> ohm ev - } - } - -newtype CursorPosition = CursorPosition (Double, Double) - deriving (Typeable) - -instance StateExtension CursorPosition where - initialValue = CursorPosition (0, 0) - marshalExtension _ = Nothing - demarshalExtension _ = Nothing - -onMotion :: MotionEvent -> Montis () -onMotion ev = do - let (x, y) = motionEvent_absolute ev - xStatePut (CursorPosition (x, y)) - -onButton :: ButtonEvent -> Montis () -onButton ev - | buttonEvent_state ev /= ButtonPressed = return () - | otherwise = do - CursorPosition (x, y) <- xStateGet - mtl <- toplevelAt x y - case mtl of - Nothing -> return () - Just tl -> focusToplevel tl diff --git a/plug/src/harness_adapter.c b/plug/src/harness_adapter.c deleted file mode 100644 index db5e7ce..0000000 --- a/plug/src/harness_adapter.c +++ /dev/null @@ -1,73 +0,0 @@ -// This file provides functions for the wetterhorn harness that are not -// expressible directly in haskell. -// -// Currently these functions exclusively enable/disable the Haskell runtime. - -#include "HsFFI.h" -#include "plugin_interface.h" -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> - -const char *plugin_name = "Montis"; - -extern void performMajorGC(); - -void plugin_metaload(int argc, char** argv) -{ - // hs_init(&argc, &argv); -} - -void plugin_load(int argc, char **argv) { - hs_init(&argc, &argv); -} - -void plugin_teardown(opqst_t st) { - hs_exit(); -} - -void shell_exec(const char* cmd) { - if (fork() == 0) { - execl("/bin/sh", "/bin/sh", "-c", cmd, NULL); - exit(1); - } -} - -static const char msg[] = - "Montis Plugin v 0.01\n\n" - "Welcome, and thank you for your interest.\n\n" - "This is merely a plugin to the Montis Compositor and not meant to be\n" - "executed as a standalone binary. This plugin requires a harness to run\n" - "To use this file, please use './wtr_harness [full-path-to-wtr.so]'\n" - "That will allow you to see how this compositor works in all its glory!\n"; -static const int msg_sz = sizeof(msg); - -/* - * Implemens a basic _start that prints inforamtion and exits for users on an - * x86_64 system. - */ -__attribute__((naked)) void _start() -{ - - // Make system call to print the message - asm( - // Load the address of the string into rsi - "mov %0, %%rsi\n" - // Load the string length into edx - "mov %1, %%edx\n" - // Load the file descriptor for stdout into edi - "mov $1, %%edi\n" - // Load the syscall number for sys_write into eax - "mov $1, %%eax\n" - // Make the syscall - "syscall\n" - - // Exit the program. - "mov $0, %%rdi\n" - "mov $60, %%rax\n" - "syscall\n" - : - : "r"(msg), "r"(msg_sz) // Input: address of msg - : "%rsi", "%edx", "%edi" // Clobbered registers - ); -} diff --git a/plug/stack.yaml b/plug/stack.yaml deleted file mode 100644 index 0faf47c..0000000 --- a/plug/stack.yaml +++ /dev/null @@ -1,67 +0,0 @@ -# This file was automatically generated by 'stack init' -# -# Some commonly used options have been documented as comments in this file. -# For advanced use and comprehensive documentation of the format, please see: -# https://docs.haskellstack.org/en/stable/yaml_configuration/ - -# Resolver to choose a 'specific' stackage snapshot or a compiler version. -# A snapshot resolver dictates the compiler version and the set of packages -# to be used for project dependencies. For example: -# -resolver: lts-21.21 -# ghc-9.6.4 -# lts-21.21 -# resolver: nightly-2023-09-24 -# resolver: ghc-9.6.2 -# -# The location of a snapshot can be provided as a file or url. Stack assumes -# a snapshot provided as a file might change, whereas a url resource does not. -# -# resolver: ./custom-snapshot.yaml -# resolver: https://example.com/snapshots/2023-01-01.yaml - -# User packages to be built. -# Various formats can be used as shown in the example below. -# -# packages: -# - some-directory -# - https://example.com/foo/bar/baz-0.0.2.tar.gz -# subdirs: -# - auto-update -# - wai -packages: -- . -# Dependency packages to be pulled from upstream that are not in the resolver. -# These entries can reference officially published versions as well as -# forks / in-progress versions pinned to a git hash. For example: -# -# extra-deps: -# - acme-missiles-0.3 -# - git: https://github.com/commercialhaskell/stack.git -# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a -# -# extra-deps: [] - -# Override default flag values for local packages and extra-deps -# flags: {} - -# Extra package databases containing global packages -# extra-package-dbs: [] - -# Control whether we use the GHC we find on the path -# system-ghc: true -# -# Require a specific version of Stack, using version ranges -# require-stack-version: -any # Default -# require-stack-version: ">=2.13" -# -# Override the architecture used by Stack, especially useful on Windows -# arch: i386 -# arch: x86_64 -# -# Extra directories used by Stack for building -# extra-include-dirs: [/path/to/dir] -# extra-lib-dirs: [/path/to/dir] -# -# Allow a newer minor version of GHC than the snapshot specifies -# compiler-check: newer-minor diff --git a/plug/test/Spec.hs b/plug/test/Spec.hs deleted file mode 100644 index cd4753f..0000000 --- a/plug/test/Spec.hs +++ /dev/null @@ -1,2 +0,0 @@ -main :: IO () -main = putStrLn "Test suite not yet implemented" |