From a7b9e28b36b535a501d088b0319b524fe5bb0337 Mon Sep 17 00:00:00 2001 From: Jens Nolte <git@queezle.net> Date: Sun, 21 Aug 2022 21:59:59 +0200 Subject: [PATCH] WIP --- examples/Client.hs | 35 ++++++++++++++---- quasar-wayland.cabal | 1 + src/Quasar/Wayland/Client/Surface.hs | 47 +++++++++++++++++++++++++ src/Quasar/Wayland/Server/LayerShell.hs | 7 ++++ src/Quasar/Wayland/Surface.hs | 11 +++++- 5 files changed, 94 insertions(+), 7 deletions(-) create mode 100644 src/Quasar/Wayland/Client/Surface.hs create mode 100644 src/Quasar/Wayland/Server/LayerShell.hs diff --git a/examples/Client.hs b/examples/Client.hs index 9ebf899..cf5d40e 100644 --- a/examples/Client.hs +++ b/examples/Client.hs @@ -95,6 +95,12 @@ main = do leave = \_ -> pure () } + wlSurface2 <- wlCompositor.create_surface + setMessageHandler wlSurface2 EventHandler_wl_surface { + enter = \_ -> pure (), + leave = \_ -> pure () + } + --xdgWmBase <- bindSingleton @Interface_xdg_wm_base client.registry --setMessageHandler xdgWmBase EventHandler_xdg_wm_base { -- ping = \serial -> xdgWmBase.pong serial @@ -116,6 +122,7 @@ main = do wlrLayerShell <- bindSingleton @Interface_zwlr_layer_shell_v1 client.registry configuredVar <- newTVar False + configuredVar2 <- newTVar False wlrLayerSurface <- wlrLayerShell.get_layer_surface wlSurface Nothing 2 "demo" setMessageHandler wlrLayerSurface EventHandler_zwlr_layer_surface_v1 { @@ -126,8 +133,18 @@ main = do } wlrLayerSurface.set_size 512 512 + wlrLayerSurface2 <- wlrLayerShell.get_layer_surface wlSurface2 Nothing 2 "demo" + setMessageHandler wlrLayerSurface2 EventHandler_zwlr_layer_surface_v1 { + configure = \serial width height -> do + wlrLayerSurface2.ack_configure serial + writeTVar configuredVar2 True, + closed = pure () + } + wlrLayerSurface2.set_size 512 512 + -- Commit role wlSurface.commit + wlSurface2.commit -- Should await first `configure` event pure do @@ -135,24 +152,30 @@ main = do liftIO $ atomically do check =<< readTVar configuredVar + check =<< readTVar configuredVar2 wlSurface.attach (Just buffer) 0 0 wlSurface.commit + wlSurface2.attach (Just buffer) 0 0 + wlSurface2.commit await =<< newDelay 1000000 - buffer2 <- liftIO $ toImageBuffer shm (mkImage solidColor) + --buffer2 <- liftIO $ toImageBuffer shm (mkImage solidColor) - liftIO $ atomically do - wlSurface.attach (Just buffer2) 0 0 - wlSurface.damage 0 0 42 42 - wlSurface.commit + --liftIO $ atomically do + -- wlSurface.attach (Just buffer2) 0 0 + -- wlSurface.damage 0 0 42 42 + -- wlSurface.commit - await =<< newDelay 1000000 + --await =<< newDelay 1000000 liftIO $ atomically do wlSurface.attach (Nothing) 0 0 wlSurface.damage 100 100 42 42 wlSurface.commit + wlSurface2.attach (Nothing) 0 0 + wlSurface2.damage 100 100 42 42 + wlSurface2.commit traceIO . ("shm buffer formats: " <>) . mconcat . intersperse ", " . fmap show . toList =<< await shm.formats diff --git a/quasar-wayland.cabal b/quasar-wayland.cabal index e57de7a..829cafb 100644 --- a/quasar-wayland.cabal +++ b/quasar-wayland.cabal @@ -79,6 +79,7 @@ library Quasar.Wayland.Client.JuicyPixels Quasar.Wayland.Client.Registry Quasar.Wayland.Client.Socket + Quasar.Wayland.Client.Surface Quasar.Wayland.Client.Sync Quasar.Wayland.Connection Quasar.Wayland.Protocol diff --git a/src/Quasar/Wayland/Client/Surface.hs b/src/Quasar/Wayland/Client/Surface.hs new file mode 100644 index 0000000..ce53cf6 --- /dev/null +++ b/src/Quasar/Wayland/Client/Surface.hs @@ -0,0 +1,47 @@ +module Quasar.Wayland.Client.Surface ( + newClientSurface, + initializeClientSurface, +) where + +import Quasar.Prelude +import Quasar.Wayland.Protocol +import Quasar.Wayland.Protocol.Generated +import Quasar.Wayland.Surface +import Quasar.Wayland.Region (Rectangle, appRect) + +newtype ClientSurface b = ClientSurface { + wlSurface :: Object 'Client Interface_wl_surface +} + +newClientSurface :: Object 'Client Interface_wl_compositor -> STM (Surface b) +newClientSurface wlCompositor = do + surface <- newSurface + wlSurface <- wlCompositor.create_surface + initializeClientSurface surface wlSurface + -- TODO: add finalizer, so that the surface is destroyed with the wlSurface + pure surface + +initializeClientSurface :: Surface b -> Object 'Client Interface_wl_surface -> STM () +initializeClientSurface surface wlSurface = do + connectSurfaceDownstream surface (surfaceDownstream (ClientSurface wlSurface)) + +surfaceDownstream :: ClientSurface b -> SurfaceDownstream b +surfaceDownstream surface = commitClientSurface surface + +commitClientSurface :: ClientSurface b -> SurfaceCommit b -> STM () +commitClientSurface surface commit = do + -- TODO catch exceptions and redirect to client owner (so the shared surface can continue to work when one backend fails) + wlBuffer <- mapM getClientBuffer commit.buffer + wlSurface.attach wlBuffer (fst commit.offset) (snd commit.offset) + applyBufferDamage surface.wlSurface commit.bufferDamage + wlSurface.commit + where + wlSurface = surface.wlSurface + +applyBufferDamage :: Object 'Client Interface_wl_surface -> Damage -> STM () +applyBufferDamage wlSurface DamageAll = wlSurface.damage_buffer minBound minBound maxBound maxBound +applyBufferDamage wlSurface (DamageList xs) = mapM_ (appRect wlSurface.damage_buffer) xs + + +getClientBuffer :: Buffer b -> STM (Object 'Client Interface_wl_buffer) +getClientBuffer = undefined diff --git a/src/Quasar/Wayland/Server/LayerShell.hs b/src/Quasar/Wayland/Server/LayerShell.hs new file mode 100644 index 0000000..3b76a3d --- /dev/null +++ b/src/Quasar/Wayland/Server/LayerShell.hs @@ -0,0 +1,7 @@ +module Quasar.Wayland.Server.LayerShell ( +) where + +import Quasar.Prelude + +layerShellGlobal :: Global +layerShellGlobal = undefined diff --git a/src/Quasar/Wayland/Surface.hs b/src/Quasar/Wayland/Surface.hs index 0902461..e947d0d 100644 --- a/src/Quasar/Wayland/Surface.hs +++ b/src/Quasar/Wayland/Surface.hs @@ -11,10 +11,12 @@ module Quasar.Wayland.Surface ( Damage(..), Surface, SurfaceCommit(..), + SurfaceDownstream, defaultSurfaceCommit, newSurface, assignSurfaceRole, commitSurface, + connectSurfaceDownstream, ) where import Control.Monad.Catch @@ -118,6 +120,13 @@ data SurfaceCommit b = SurfaceCommit { bufferDamage :: Damage } +--instance Semigroup (SurfaceCommit b) where +-- old <> new = SurfaceCommit { +-- buffer = new.buffer, +-- offset = new.offset, +-- bufferDamage = old.bufferDamage <> new.bufferDamage +-- } + type SurfaceDownstream b = SurfaceCommit b -> STM () defaultSurfaceCommit :: Damage -> SurfaceCommit b @@ -166,4 +175,4 @@ commitSurface surface commit = do mapM_ ($ commit) downstreams connectSurfaceDownstream :: forall b. Surface b -> SurfaceDownstream b -> STM () -connectSurfaceDownstream = undefined +connectSurfaceDownstream surface = modifyTVar surface.downstreams . (:) -- GitLab