summaryrefslogtreecommitdiff
path: root/lib/Wayland/Display.lean
diff options
context:
space:
mode:
authorHannes Schulze <haschu0103@outlook.de>2026-04-05 16:15:03 +0200
committerHannes Schulze <haschu0103@outlook.de>2026-04-05 16:15:03 +0200
commit1f5491a5af7bd0f1ec4046994d6344886465cba5 (patch)
tree9ca3af2221cdbc302b932b67965791a8065699a9 /lib/Wayland/Display.lean
parentad4d34bba7671fdf75850a312c7eeeaeb990a9d3 (diff)
initial codegen
Diffstat (limited to 'lib/Wayland/Display.lean')
-rw-r--r--lib/Wayland/Display.lean43
1 files changed, 34 insertions, 9 deletions
diff --git a/lib/Wayland/Display.lean b/lib/Wayland/Display.lean
index 7bf55c5..9b3b0da 100644
--- a/lib/Wayland/Display.lean
+++ b/lib/Wayland/Display.lean
@@ -32,6 +32,12 @@ structure Object (ι : InterfaceName) : Type where
private proxy : Native.Proxy
deriving Nonempty
+/-- Opaque handle to an object whose type is not statically known. -/
+structure AnyObject : Type where
+ private proxy : Native.Proxy
+ private type : String
+ deriving Nonempty
+
/-- Monad in which arguments can be marshalled one after another. -/
class ArgumentMarshaller (m : Type → Type) extends Monad m where
marshalInt : Int32 → m Unit
@@ -39,6 +45,7 @@ class ArgumentMarshaller (m : Type → Type) extends Monad m where
marshalFixed : Float32 → m Unit
marshalString : Option String → m Unit
marshalObject {ι : InterfaceName} : Option (Object ι) → m Unit
+ marshalAnyObject : Option AnyObject → m Unit
marshalArray : ByteArray → m Unit
marshalFD : Int32 → m Unit
@@ -49,6 +56,7 @@ class ArgumentDemarshaller (m : Type → Type) extends Monad m where
demarshalFixed : m Float32
demarshalString : m (Option String)
demarshalObject {ι : InterfaceName} : m (Option (Object ι))
+ demarshalAnyObject : m (Option AnyObject)
demarshalArray : m ByteArray
demarshalFD : m Int32
@@ -63,8 +71,8 @@ inductive ArgumentDesc where
| uint : ArgumentDesc
| fixed : ArgumentDesc
| string : Nullability → ArgumentDesc
- | object : Nullability → InterfaceName → ArgumentDesc
- | newID : InterfaceName → ArgumentDesc
+ | object : Nullability → (Option InterfaceName) → ArgumentDesc
+ | newID : (Option InterfaceName) → ArgumentDesc
| array : ArgumentDesc
| fd : ArgumentDesc
@@ -239,6 +247,7 @@ private instance : ArgumentMarshaller ArgumentBufferM where
marshalFixed v := do (← read).writeFixed v
marshalString v := do (← read).writeString v
marshalObject v := do (← read).writeObject (v.map Object.proxy)
+ marshalAnyObject v := do (← read).writeObject (v.map AnyObject.proxy)
marshalArray v := do (← read).writeArray v
marshalFD v := do (← read).writeFD v
@@ -247,7 +256,13 @@ private instance : ArgumentDemarshaller ArgumentBufferM where
demarshalUInt := do (← read).readUInt
demarshalFixed := do (← read).readFixed
demarshalString := do (← read).readString
- demarshalObject := do let proxy ← (← read).readObject; return proxy.map Object.mk
+ demarshalObject := do
+ let proxy ← (← read).readObject
+ return proxy.map Object.mk
+ demarshalAnyObject := do
+ let proxy ← (← read).readObject
+ proxy.mapM fun proxy ↦ do
+ return ⟨proxy, ← proxy.getType⟩
demarshalArray := do (← read).readArray
demarshalFD := do (← read).readFD
@@ -271,8 +286,8 @@ private def MessageDesc.toNative (msg : MessageDesc) : Native.Message :=
| .array => "a"
| .fd => "h"
let argType : ArgumentDesc → Option String
- | .object _ iface => .some iface
- | .newID iface => .some iface
+ | .object _ iface => iface
+ | .newID iface => iface
| _ => .none
{ name := msg.name
signature := s!"{msg.since}{String.join (msg.args.toList.map argString)}"
@@ -295,14 +310,16 @@ def DisplayM.getDisplay : DisplayM σ (Object "wl_display") := do
let proxy ← Native.Proxy.fromDisplay (← read).disp
return ⟨proxy⟩
+variable {ι ι' : InterfaceName}
+
/-- Send a request for an object to the server that doesn't construct any new object. -/
-def Object.send {ι : InterfaceName} (obj : Object ι) (marshaller : ∀ {α} [ArgumentMarshaller α], α OpCode) : DisplayM σ Unit := do
+def Object.send (obj : Object ι) (marshaller : ∀ {α} [ArgumentMarshaller α], α OpCode) : DisplayM σ Unit := do
let argBuffer ← Native.ArgumentBuffer.new
let opcode ← ArgumentBufferM.run marshaller argBuffer
obj.proxy.send opcode argBuffer
/-- Send a request for an object to the server, allocating a new id for a constructed object in the process. -/
-def Object.sendConstructor {ι ι' : InterfaceName} [iface : ResolvedInterface ι'] (obj : Object ι) (marshaller : ∀ {α} [ArgumentMarshaller α], α OpCode) : DisplayM σ (Object ι') := do
+def Object.sendConstructor [iface : ResolvedInterface ι'] (obj : Object ι) (marshaller : ∀ {α} [ArgumentMarshaller α], α OpCode) : DisplayM σ (Object ι') := do
DisplayM.ensureInterface ι'
let typeMap := (← read).typeMap
let argBuffer ← Native.ArgumentBuffer.new
@@ -311,7 +328,7 @@ def Object.sendConstructor {ι ι' : InterfaceName} [iface : ResolvedInterface Î
return ⟨proxy⟩
/-- Listen for events from the server for an object. -/
-def Object.listen {ι : InterfaceName} [iface : Interface ι] (obj : Object ι) (handler : iface.event → DisplayM σ Unit) : DisplayM σ Unit := do
+def Object.listen [iface : Interface ι] (obj : Object ι) (handler : iface.event → DisplayM σ Unit) : DisplayM σ Unit := do
let global ← read
let actualHandler (opcode : UInt32) (argBuffer : Native.ArgumentBuffer) : StateT σ IO Unit := do
let event ← ArgumentBufferM.run (iface.demarshalEvent opcode) argBuffer
@@ -319,9 +336,17 @@ def Object.listen {ι : InterfaceName} [iface : Interface ι] (obj : Object ι)
global.listen obj.proxy actualHandler
/-- Shorthand to ensure the reference count of an `Object` does not drop to `0`. -/
-def Object.keep {ι : InterfaceName} (obj : Object ι) : DisplayM σ Unit :=
+def Object.keep (obj : Object ι) : DisplayM σ Unit :=
obj.proxy.keep
+/-- Erase the type information from an object. -/
+def Object.toAny (obj : Object ι) : AnyObject :=
+ ⟨obj.proxy, ι⟩
+
+/-- Try to cast a type-erased object into a typed object. -/
+def AnyObject.cast (obj : AnyObject) : Option (Object ι) :=
+ if obj.type == ι then .some ⟨obj.proxy⟩ else .none
+
end Proxies
end Wayland