diff --git a/cmd/tinywl/server.go b/cmd/tinywl/server.go index 89b5921..be4262f 100644 --- a/cmd/tinywl/server.go +++ b/cmd/tinywl/server.go @@ -18,16 +18,16 @@ const ( ) type Server struct { - display wlroots.Display - backend wlroots.Backend - renderer wlroots.Renderer - layout wlroots.OutputLayout - cursor wlroots.Cursor - cursorMgr wlroots.XCursorManager - compositor wlroots.Compositor - dataDevMgr wlroots.DataDeviceManager - seat wlroots.Seat - xdgShell wlroots.XDGShell + display *wlroots.Display + backend *wlroots.Backend + renderer *wlroots.Renderer + layout *wlroots.OutputLayout + cursor *wlroots.Cursor + cursorMgr *wlroots.XCursorManager + compositor *wlroots.Compositor + dataDevMgr *wlroots.DataDeviceManager + seat *wlroots.Seat + xdgShell *wlroots.XDGShell views []*View keyboards []*Keyboard @@ -42,7 +42,7 @@ type Server struct { } type Keyboard struct { - dev wlroots.InputDevice + dev *wlroots.InputDevice } func NewServer() (*Server, error) { @@ -116,22 +116,22 @@ func (s *Server) Run() error { return nil } -func (s *Server) viewAt(lx float64, ly float64) (*View, wlroots.Surface, float64, float64) { +func (s *Server) viewAt(lx float64, ly float64) (*View, *wlroots.Surface, float64, float64) { for i := len(s.views) - 1; i >= 0; i-- { view := s.views[i] surface, sx, sy := view.XDGSurface().SurfaceAt(lx-view.X, ly-view.Y) - if !surface.Nil() { + if surface != nil { return view, surface, sx, sy } } - return nil, wlroots.Surface{}, 0, 0 + return nil, nil, 0, 0 } -func (s *Server) renderView(output wlroots.Output, view *View) { - view.XDGSurface().Walk(func(surface wlroots.Surface, sx int, sy int) { +func (s *Server) renderView(output *wlroots.Output, view *View) { + view.XDGSurface().Walk(func(surface *wlroots.Surface, sx int, sy int) { texture := surface.Texture() - if texture.Nil() { + if texture == nil { return } @@ -160,14 +160,14 @@ func (s *Server) renderView(output wlroots.Output, view *View) { }) } -func (s *Server) focusView(view *View, surface wlroots.Surface) { +func (s *Server) focusView(view *View, surface *wlroots.Surface) { prevSurface := s.seat.KeyboardState().FocusedSurface() if prevSurface == surface { // don't re-focus an already focused surface return } - if !prevSurface.Nil() { + if prevSurface != nil { // deactivate the previously focused surface prev := prevSurface.XDGSurface() prev.TopLevelSetActivated(false) @@ -186,7 +186,7 @@ func (s *Server) focusView(view *View, surface wlroots.Surface) { s.seat.NotifyKeyboardEnter(view.Surface(), s.seat.Keyboard()) } -func (s *Server) handleNewFrame(output wlroots.Output) { +func (s *Server) handleNewFrame(output *wlroots.Output) { output.AttachRender() width, height := output.EffectiveResolution() @@ -207,7 +207,7 @@ func (s *Server) handleNewFrame(output wlroots.Output) { output.Commit() } -func (s *Server) handleNewOutput(output wlroots.Output) { +func (s *Server) handleNewOutput(output *wlroots.Output) { // TODO: pick the preferred mode instead of the first one modes := output.Modes() if len(modes) > 0 { @@ -220,12 +220,12 @@ func (s *Server) handleNewOutput(output wlroots.Output) { output.SetTitle(fmt.Sprintf("tinywl (wlroots) - %s", output.Name())) } -func (s *Server) handleCursorMotion(dev wlroots.InputDevice, time uint32, dx float64, dy float64) { +func (s *Server) handleCursorMotion(dev *wlroots.InputDevice, time uint32, dx float64, dy float64) { s.cursor.Move(dev, dx, dy) s.processCursorMotion(time) } -func (s *Server) handleCursorMotionAbsolute(dev wlroots.InputDevice, time uint32, x float64, y float64) { +func (s *Server) handleCursorMotionAbsolute(dev *wlroots.InputDevice, time uint32, x float64, y float64) { s.cursor.WarpAbsolute(dev, x, y) s.processCursorMotion(time) } @@ -247,7 +247,7 @@ func (s *Server) processCursorMotion(time uint32) { s.cursorMgr.SetCursorImage(s.cursor, "left_ptr") } - if !surface.Nil() { + if surface != nil { s.seat.NotifyPointerEnter(surface, sx, sy) if s.seat.PointerState().FocusedSurface() == surface { // we only need to notify on motion if the focus didn't change @@ -296,14 +296,14 @@ func (s *Server) processCursorResize(time uint32) { s.grabbedView.XDGSurface().TopLevelSetSize(uint32(width), uint32(height)) } -func (s *Server) handleSetCursorRequest(client wlroots.SeatClient, surface wlroots.Surface, serial uint32, hotspotX int32, hotspotY int32) { +func (s *Server) handleSetCursorRequest(client *wlroots.SeatClient, surface *wlroots.Surface, serial uint32, hotspotX int32, hotspotY int32) { focusedClient := s.seat.PointerState().FocusedClient() if focusedClient == client { s.cursor.SetSurface(surface, hotspotX, hotspotY) } } -func (s *Server) handleNewInput(dev wlroots.InputDevice) { +func (s *Server) handleNewInput(dev *wlroots.InputDevice) { switch dev.Type() { case wlroots.InputDeviceTypePointer: s.cursor.AttachInputDevice(dev) @@ -316,7 +316,7 @@ func (s *Server) handleNewInput(dev wlroots.InputDevice) { context.Destroy() keyboard.SetRepeatInfo(25, 600) - keyboard.OnKey(func(keyboard wlroots.Keyboard, time uint32, keyCode uint32, updateState bool, state wlroots.KeyState) { + keyboard.OnKey(func(keyboard *wlroots.Keyboard, time uint32, keyCode uint32, updateState bool, state wlroots.KeyState) { // translate libinput keycode to xkbcommon and obtain keysyms syms := keyboard.XKBState().Syms(xkb.KeyCode(keyCode + 8)) @@ -334,7 +334,7 @@ func (s *Server) handleNewInput(dev wlroots.InputDevice) { } }) - keyboard.OnModifiers(func(keyboard wlroots.Keyboard) { + keyboard.OnModifiers(func(keyboard *wlroots.Keyboard) { s.seat.SetKeyboard(dev) s.seat.NotifyKeyboardModifiers(keyboard) }) @@ -350,20 +350,20 @@ func (s *Server) handleNewInput(dev wlroots.InputDevice) { s.seat.SetCapabilities(caps) } -func (s *Server) handleNewXDGSurface(surface wlroots.XDGSurface) { +func (s *Server) handleNewXDGSurface(surface *wlroots.XDGSurface) { if surface.Role() != wlroots.XDGSurfaceRoleTopLevel { return } view := NewView(surface) - surface.OnMap(func(surface wlroots.XDGSurface) { + surface.OnMap(func(surface *wlroots.XDGSurface) { view.Mapped = true s.focusView(view, surface.Surface()) }) - surface.OnUnmap(func(surface wlroots.XDGSurface) { + surface.OnUnmap(func(surface *wlroots.XDGSurface) { view.Mapped = false }) - surface.OnDestroy(func(surface wlroots.XDGSurface) { + surface.OnDestroy(func(surface *wlroots.XDGSurface) { // TODO: keep track of views some other way for i := range s.views { if s.views[i] == view { @@ -374,17 +374,17 @@ func (s *Server) handleNewXDGSurface(surface wlroots.XDGSurface) { }) toplevel := surface.TopLevel() - toplevel.OnRequestMove(func(client wlroots.SeatClient, serial uint32) { + toplevel.OnRequestMove(func(client *wlroots.SeatClient, serial uint32) { s.beginInteractive(view, CursorModeMove, 0) }) - toplevel.OnRequestResize(func(client wlroots.SeatClient, serial uint32, edges wlroots.Edges) { + toplevel.OnRequestResize(func(client *wlroots.SeatClient, serial uint32, edges wlroots.Edges) { s.beginInteractive(view, CursorModeResize, edges) }) s.views = append(s.views, view) } -func (s *Server) handleCursorButton(dev wlroots.InputDevice, time uint32, button uint32, state wlroots.ButtonState) { +func (s *Server) handleCursorButton(dev *wlroots.InputDevice, time uint32, button uint32, state wlroots.ButtonState) { s.seat.NotifyPointerButton(time, button, state) if state == wlroots.ButtonStateReleased { @@ -397,7 +397,7 @@ func (s *Server) handleCursorButton(dev wlroots.InputDevice, time uint32, button } } -func (s *Server) handleCursorAxis(dev wlroots.InputDevice, time uint32, source wlroots.AxisSource, orientation wlroots.AxisOrientation, delta float64, deltaDiscrete int32) { +func (s *Server) handleCursorAxis(dev *wlroots.InputDevice, time uint32, source wlroots.AxisSource, orientation wlroots.AxisOrientation, delta float64, deltaDiscrete int32) { s.seat.NotifyPointerAxis(time, orientation, delta, deltaDiscrete, source) } diff --git a/cmd/tinywl/view.go b/cmd/tinywl/view.go index 8b5de20..21033b2 100644 --- a/cmd/tinywl/view.go +++ b/cmd/tinywl/view.go @@ -3,20 +3,20 @@ package main import "github.com/swaywm/go-wlroots/wlroots" type View struct { - surface wlroots.XDGSurface + surface *wlroots.XDGSurface Mapped bool X float64 Y float64 } -func NewView(surface wlroots.XDGSurface) *View { +func NewView(surface *wlroots.XDGSurface) *View { return &View{surface: surface} } -func (v *View) Surface() wlroots.Surface { +func (v *View) Surface() *wlroots.Surface { return v.surface.Surface() } -func (v *View) XDGSurface() wlroots.XDGSurface { +func (v *View) XDGSurface() *wlroots.XDGSurface { return v.surface } diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..aa41f46 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +golang.org/x/sys v0.0.0-20200918174421-af09f7315aff h1:1CPUrky56AcgSpxz/KfgzQWzfG09u5YOL8MvPYBlrL8= +golang.org/x/sys v0.0.0-20200918174421-af09f7315aff/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/wlroots/wlroots.go b/wlroots/wlroots.go index dad2f3a..b2542ee 100644 --- a/wlroots/wlroots.go +++ b/wlroots/wlroots.go @@ -73,27 +73,29 @@ import ( "golang.org/x/sys/unix" ) +//go:notinheap type XWayland struct { - p *C.struct_wlr_xwayland + p C.struct_wlr_xwayland } +//go:notinheap type XWaylandSurface struct { - p *C.struct_wlr_xwayland_surface + p C.struct_wlr_xwayland_surface } -func NewXWayland(display Display, compositor Compositor, lazy bool) XWayland { - p := C.wlr_xwayland_create(display.p, compositor.p, C.bool(lazy)) - return XWayland{p: p} +func NewXWayland(display *Display, compositor *Compositor, lazy bool) *XWayland { + p := C.wlr_xwayland_create(&display.p, &compositor.p, C.bool(lazy)) + return (*XWayland)(unsafe.Pointer(p)) } -func (x XWayland) Destroy() { - C.wlr_xwayland_destroy(x.p) +func (x *XWayland) Destroy() { + C.wlr_xwayland_destroy(&x.p) } -func (x XWayland) OnNewSurface(cb func(XWaylandSurface)) { - man.add(unsafe.Pointer(x.p), &x.p.events.new_surface, func(data unsafe.Pointer) { - surface := XWaylandSurface{p: (*C.struct_wlr_xwayland_surface)(data)} - man.track(unsafe.Pointer(surface.p), &surface.p.events.destroy) +func (x *XWayland) OnNewSurface(cb func(*XWaylandSurface)) { + man.add(unsafe.Pointer(x), &x.p.events.new_surface, func(data unsafe.Pointer) { + surface := (*XWaylandSurface)(data) + man.track(data, &surface.p.events.destroy) man.add(unsafe.Pointer(surface.p.surface), &surface.p.surface.events.destroy, func(data unsafe.Pointer) { man.delete(unsafe.Pointer(surface.p.surface)) }) @@ -101,15 +103,15 @@ func (x XWayland) OnNewSurface(cb func(XWaylandSurface)) { }) } -func (x XWayland) SetCursor(img XCursorImage) { - C.wlr_xwayland_set_cursor(x.p, img.p.buffer, img.p.width*4, img.p.width, img.p.height, C.int32_t(img.p.hotspot_x), C.int32_t(img.p.hotspot_y)) +func (x *XWayland) SetCursor(img *XCursorImage) { + C.wlr_xwayland_set_cursor(&x.p, img.p.buffer, img.p.width*4, img.p.width, img.p.height, C.int32_t(img.p.hotspot_x), C.int32_t(img.p.hotspot_y)) } -func (s XWaylandSurface) Surface() Surface { - return Surface{p: s.p.surface} +func (s *XWaylandSurface) Surface() *Surface { + return (*Surface)(unsafe.Pointer(s.p.surface)) } -func (s XWaylandSurface) Geometry() Box { +func (s *XWaylandSurface) Geometry() Box { return Box{ X: int(s.p.x), Y: int(s.p.y), @@ -118,43 +120,43 @@ func (s XWaylandSurface) Geometry() Box { } } -func (s XWaylandSurface) Configure(x int16, y int16, width uint16, height uint16) { - C.wlr_xwayland_surface_configure(s.p, C.int16_t(x), C.int16_t(y), C.uint16_t(width), C.uint16_t(height)) +func (s *XWaylandSurface) Configure(x int16, y int16, width uint16, height uint16) { + C.wlr_xwayland_surface_configure(&s.p, C.int16_t(x), C.int16_t(y), C.uint16_t(width), C.uint16_t(height)) } -func (s XWaylandSurface) OnMap(cb func(XWaylandSurface)) { - man.add(unsafe.Pointer(s.p), &s.p.events._map, func(data unsafe.Pointer) { +func (s *XWaylandSurface) OnMap(cb func(*XWaylandSurface)) { + man.add(unsafe.Pointer(s), &s.p.events._map, func(data unsafe.Pointer) { cb(s) }) } -func (s XWaylandSurface) OnUnmap(cb func(XWaylandSurface)) { - man.add(unsafe.Pointer(s.p), &s.p.events.unmap, func(data unsafe.Pointer) { +func (s *XWaylandSurface) OnUnmap(cb func(*XWaylandSurface)) { + man.add(unsafe.Pointer(s), &s.p.events.unmap, func(data unsafe.Pointer) { cb(s) }) } -func (s XWaylandSurface) OnDestroy(cb func(XWaylandSurface)) { - man.add(unsafe.Pointer(s.p), &s.p.events.destroy, func(data unsafe.Pointer) { +func (s *XWaylandSurface) OnDestroy(cb func(*XWaylandSurface)) { + man.add(unsafe.Pointer(s), &s.p.events.destroy, func(data unsafe.Pointer) { cb(s) }) } -func (s XWaylandSurface) OnRequestMove(cb func(surface XWaylandSurface)) { - man.add(unsafe.Pointer(s.p), &s.p.events.request_move, func(data unsafe.Pointer) { +func (s *XWaylandSurface) OnRequestMove(cb func(surface *XWaylandSurface)) { + man.add(unsafe.Pointer(s), &s.p.events.request_move, func(data unsafe.Pointer) { cb(s) }) } -func (s XWaylandSurface) OnRequestResize(cb func(surface XWaylandSurface, edges Edges)) { - man.add(unsafe.Pointer(s.p), &s.p.events.request_resize, func(data unsafe.Pointer) { +func (s *XWaylandSurface) OnRequestResize(cb func(surface *XWaylandSurface, edges Edges)) { + man.add(unsafe.Pointer(s), &s.p.events.request_resize, func(data unsafe.Pointer) { event := (*C.struct_wlr_xwayland_resize_event)(data) cb(s, Edges(event.edges)) }) } -func (s XWaylandSurface) OnRequestConfigure(cb func(surface XWaylandSurface, x int16, y int16, width uint16, height uint16)) { - man.add(unsafe.Pointer(s.p), &s.p.events.request_configure, func(data unsafe.Pointer) { +func (s *XWaylandSurface) OnRequestConfigure(cb func(surface *XWaylandSurface, x int16, y int16, width uint16, height uint16)) { + man.add(unsafe.Pointer(s), &s.p.events.request_configure, func(data unsafe.Pointer) { event := (*C.struct_wlr_xwayland_surface_configure_event)(data) cb(s, int16(event.x), int16(event.y), uint16(event.width), uint16(event.height)) }) @@ -170,46 +172,50 @@ const ( var ( // TODO: guard this with a mutex - xdgSurfaceWalkers = map[*C.struct_wlr_xdg_surface]XDGSurfaceWalkFunc{} + xdgSurfaceWalkers = map[*XDGSurface]XDGSurfaceWalkFunc{} xdgSurfaceWalkersMutex sync.RWMutex ) +//go:notinheap type XDGShell struct { - p *C.struct_wlr_xdg_shell + p C.struct_wlr_xdg_shell } +//go:notinheap type XDGSurface struct { - p *C.struct_wlr_xdg_surface + p C.struct_wlr_xdg_surface } +//go:notinheap type XDGPopup struct { - p *C.struct_wlr_xdg_popup + p C.struct_wlr_xdg_popup } -type XDGSurfaceWalkFunc func(surface Surface, sx int, sy int) +type XDGSurfaceWalkFunc func(surface *Surface, sx int, sy int) +//go:notinheap type XDGTopLevel struct { - p *C.struct_wlr_xdg_toplevel + p C.struct_wlr_xdg_toplevel } -func NewXDGShell(display Display) XDGShell { - p := C.wlr_xdg_shell_create(display.p) +func NewXDGShell(display *Display) *XDGShell { + p := C.wlr_xdg_shell_create(&display.p) man.track(unsafe.Pointer(p), &p.events.destroy) - return XDGShell{p: p} + return (*XDGShell)(unsafe.Pointer(p)) } -func (s XDGShell) OnDestroy(cb func(XDGShell)) { - man.add(unsafe.Pointer(s.p), &s.p.events.destroy, func(unsafe.Pointer) { +func (s *XDGShell) OnDestroy(cb func(*XDGShell)) { + man.add(unsafe.Pointer(s), &s.p.events.destroy, func(unsafe.Pointer) { cb(s) }) } -func (s XDGShell) OnNewSurface(cb func(XDGSurface)) { - man.add(unsafe.Pointer(s.p), &s.p.events.new_surface, func(data unsafe.Pointer) { - surface := XDGSurface{p: (*C.struct_wlr_xdg_surface)(data)} - man.add(unsafe.Pointer(surface.p), &surface.p.events.destroy, func(data unsafe.Pointer) { - man.delete(unsafe.Pointer(surface.p)) - man.delete(unsafe.Pointer(surface.TopLevel().p)) +func (s *XDGShell) OnNewSurface(cb func(*XDGSurface)) { + man.add(unsafe.Pointer(s), &s.p.events.new_surface, func(data unsafe.Pointer) { + surface := (*XDGSurface)(data) + man.add(data, &surface.p.events.destroy, func(data unsafe.Pointer) { + man.delete(unsafe.Pointer(surface)) + man.delete(unsafe.Pointer(surface.TopLevel())) }) man.add(unsafe.Pointer(surface.p.surface), &surface.p.surface.events.destroy, func(data unsafe.Pointer) { man.delete(unsafe.Pointer(surface.p.surface)) @@ -221,189 +227,184 @@ func (s XDGShell) OnNewSurface(cb func(XDGSurface)) { //export _wlr_xdg_surface_for_each_cb func _wlr_xdg_surface_for_each_cb(surface *C.struct_wlr_surface, sx C.int, sy C.int, data unsafe.Pointer) { xdgSurfaceWalkersMutex.RLock() - cb := xdgSurfaceWalkers[(*C.struct_wlr_xdg_surface)(data)] + cb := xdgSurfaceWalkers[(*XDGSurface)(data)] xdgSurfaceWalkersMutex.RUnlock() if cb != nil { - cb(Surface{p: surface}, int(sx), int(sy)) + cb((*Surface)(unsafe.Pointer(surface)), int(sx), int(sy)) } } -func (s XDGSurface) Nil() bool { - return s.p == nil -} - -func (s XDGSurface) Walk(visit XDGSurfaceWalkFunc) { +func (s *XDGSurface) Walk(visit XDGSurfaceWalkFunc) { xdgSurfaceWalkersMutex.Lock() - xdgSurfaceWalkers[s.p] = visit + xdgSurfaceWalkers[s] = visit xdgSurfaceWalkersMutex.Unlock() - C._wlr_xdg_surface_for_each_surface(s.p, unsafe.Pointer(s.p)) + C._wlr_xdg_surface_for_each_surface(&s.p, unsafe.Pointer(s)) xdgSurfaceWalkersMutex.Lock() - delete(xdgSurfaceWalkers, s.p) + delete(xdgSurfaceWalkers, s) xdgSurfaceWalkersMutex.Unlock() } -func (s XDGSurface) Role() XDGSurfaceRole { +func (s *XDGSurface) Role() XDGSurfaceRole { return XDGSurfaceRole(s.p.role) } -func (s XDGSurface) TopLevel() XDGTopLevel { +func (s *XDGSurface) TopLevel() *XDGTopLevel { p := *(*unsafe.Pointer)(unsafe.Pointer(&s.p.anon0[0])) - return XDGTopLevel{p: (*C.struct_wlr_xdg_toplevel)(p)} + return (*XDGTopLevel)(p) } -func (s XDGSurface) TopLevelSetActivated(activated bool) { - C.wlr_xdg_toplevel_set_activated(s.p, C.bool(activated)) +func (s *XDGSurface) TopLevelSetActivated(activated bool) { + C.wlr_xdg_toplevel_set_activated(&s.p, C.bool(activated)) } -func (s XDGSurface) TopLevelSetSize(width uint32, height uint32) { - C.wlr_xdg_toplevel_set_size(s.p, C.uint32_t(width), C.uint32_t(height)) +func (s *XDGSurface) TopLevelSetSize(width uint32, height uint32) { + C.wlr_xdg_toplevel_set_size(&s.p, C.uint32_t(width), C.uint32_t(height)) } -func (s XDGSurface) TopLevelSetTiled(edges Edges) { - C.wlr_xdg_toplevel_set_tiled(s.p, C.uint32_t(edges)) +func (s *XDGSurface) TopLevelSetTiled(edges Edges) { + C.wlr_xdg_toplevel_set_tiled(&s.p, C.uint32_t(edges)) } -func (s XDGSurface) SendClose() { - C.wlr_xdg_toplevel_send_close(s.p) +func (s *XDGSurface) SendClose() { + C.wlr_xdg_toplevel_send_close(&s.p) } -func (s XDGSurface) Ping() { - C.wlr_xdg_surface_ping(s.p) +func (s *XDGSurface) Ping() { + C.wlr_xdg_surface_ping(&s.p) } -func (s XDGSurface) Surface() Surface { - return Surface{p: s.p.surface} +func (s *XDGSurface) Surface() *Surface { + return (*Surface)(unsafe.Pointer(s.p.surface)) } -func (s XDGSurface) SurfaceAt(sx float64, sy float64) (surface Surface, subX float64, subY float64) { +func (s *XDGSurface) SurfaceAt(sx float64, sy float64) (surface *Surface, subX float64, subY float64) { var csubX, csubY C.double - p := C.wlr_xdg_surface_surface_at(s.p, C.double(sx), C.double(sy), &csubX, &csubY) - return Surface{p: p}, float64(csubX), float64(csubY) + p := C.wlr_xdg_surface_surface_at(&s.p, C.double(sx), C.double(sy), &csubX, &csubY) + return (*Surface)(unsafe.Pointer(p)), float64(csubX), float64(csubY) } -func (s XDGSurface) OnMap(cb func(XDGSurface)) { - man.add(unsafe.Pointer(s.p), &s.p.events._map, func(data unsafe.Pointer) { +func (s *XDGSurface) OnMap(cb func(*XDGSurface)) { + man.add(unsafe.Pointer(s), &s.p.events._map, func(data unsafe.Pointer) { cb(s) }) } -func (s XDGSurface) OnUnmap(cb func(XDGSurface)) { - man.add(unsafe.Pointer(s.p), &s.p.events.unmap, func(data unsafe.Pointer) { +func (s *XDGSurface) OnUnmap(cb func(*XDGSurface)) { + man.add(unsafe.Pointer(s), &s.p.events.unmap, func(data unsafe.Pointer) { cb(s) }) } -func (s XDGSurface) OnDestroy(cb func(XDGSurface)) { - man.add(unsafe.Pointer(s.p), &s.p.events.destroy, func(data unsafe.Pointer) { +func (s *XDGSurface) OnDestroy(cb func(*XDGSurface)) { + man.add(unsafe.Pointer(s), &s.p.events.destroy, func(data unsafe.Pointer) { cb(s) }) } -func (s XDGSurface) OnPingTimeout(cb func(XDGSurface)) { - man.add(unsafe.Pointer(s.p), &s.p.events.ping_timeout, func(data unsafe.Pointer) { +func (s *XDGSurface) OnPingTimeout(cb func(*XDGSurface)) { + man.add(unsafe.Pointer(s), &s.p.events.ping_timeout, func(data unsafe.Pointer) { cb(s) }) } -func (s XDGSurface) OnNewPopup(cb func(XDGSurface, XDGPopup)) { - man.add(unsafe.Pointer(s.p), &s.p.events.ping_timeout, func(data unsafe.Pointer) { - popup := XDGPopup{p: (*C.struct_wlr_xdg_popup)(data)} +func (s *XDGSurface) OnNewPopup(cb func(*XDGSurface, *XDGPopup)) { + man.add(unsafe.Pointer(s), &s.p.events.ping_timeout, func(data unsafe.Pointer) { + popup := (*XDGPopup)(data) cb(s, popup) }) } -func (s XDGSurface) Geometry() Box { +func (s *XDGSurface) Geometry() Box { var cb C.struct_wlr_box - C.wlr_xdg_surface_get_geometry(s.p, &cb) + C.wlr_xdg_surface_get_geometry(&s.p, &cb) var b Box b.fromC(&cb) return b } -func (t XDGTopLevel) OnRequestMove(cb func(client SeatClient, serial uint32)) { - man.add(unsafe.Pointer(t.p), &t.p.events.request_move, func(data unsafe.Pointer) { +func (t *XDGTopLevel) OnRequestMove(cb func(client *SeatClient, serial uint32)) { + man.add(unsafe.Pointer(t), &t.p.events.request_move, func(data unsafe.Pointer) { event := (*C.struct_wlr_xdg_toplevel_move_event)(data) - client := SeatClient{p: event.seat} + client := (*SeatClient)(unsafe.Pointer(event.seat)) cb(client, uint32(event.serial)) }) } -func (t XDGTopLevel) OnRequestResize(cb func(client SeatClient, serial uint32, edges Edges)) { - man.add(unsafe.Pointer(t.p), &t.p.events.request_resize, func(data unsafe.Pointer) { +func (t *XDGTopLevel) OnRequestResize(cb func(client *SeatClient, serial uint32, edges Edges)) { + man.add(unsafe.Pointer(t), &t.p.events.request_resize, func(data unsafe.Pointer) { event := (*C.struct_wlr_xdg_toplevel_resize_event)(data) - client := SeatClient{p: event.seat} + client := (*SeatClient)(unsafe.Pointer(event.seat)) cb(client, uint32(event.serial), Edges(event.edges)) }) } -func (s XDGTopLevel) Nil() bool { - return s.p == nil -} - -func (t XDGTopLevel) Title() string { +func (t *XDGTopLevel) Title() string { return C.GoString(t.p.title) } +//go:notinheap type XCursor struct { - p *C.struct_wlr_xcursor + p C.struct_wlr_xcursor } +//go:notinheap type XCursorImage struct { - p *C.struct_wlr_xcursor_image + p C.struct_wlr_xcursor_image } +//go:notinheap type XCursorManager struct { - p *C.struct_wlr_xcursor_manager + p C.struct_wlr_xcursor_manager } -func NewXCursorManager() XCursorManager { +func NewXCursorManager() *XCursorManager { p := C.wlr_xcursor_manager_create(nil, 24) - return XCursorManager{p: p} + return (*XCursorManager)(unsafe.Pointer(p)) } -func (m XCursorManager) Destroy() { - C.wlr_xcursor_manager_destroy(m.p) +func (m *XCursorManager) Destroy() { + C.wlr_xcursor_manager_destroy(&m.p) } -func (m XCursorManager) Load() { - C.wlr_xcursor_manager_load(m.p, 1) +func (m *XCursorManager) Load() { + C.wlr_xcursor_manager_load(&m.p, 1) } -func (m XCursorManager) SetCursorImage(cursor Cursor, name string) { +func (m *XCursorManager) SetCursorImage(cursor *Cursor, name string) { s := C.CString(name) - C.wlr_xcursor_manager_set_cursor_image(m.p, s, cursor.p) + C.wlr_xcursor_manager_set_cursor_image(&m.p, s, &cursor.p) C.free(unsafe.Pointer(s)) } -func (m XCursorManager) XCursor(name string, scale float32) XCursor { +func (m *XCursorManager) XCursor(name string, scale float32) *XCursor { s := C.CString(name) - p := C.wlr_xcursor_manager_get_xcursor(m.p, s, C.float(scale)) + p := C.wlr_xcursor_manager_get_xcursor(&m.p, s, C.float(scale)) C.free(unsafe.Pointer(s)) - return XCursor{p: p} + return (*XCursor)(unsafe.Pointer(p)) } -func (c XCursor) Image(i int) XCursorImage { +func (c *XCursor) Image(i int) *XCursorImage { n := c.ImageCount() slice := (*[1 << 30]*C.struct_wlr_xcursor_image)(unsafe.Pointer(c.p.images))[:n:n] - return XCursorImage{p: slice[i]} + return (*XCursorImage)(unsafe.Pointer(slice[i])) } -func (c XCursor) Images() []XCursorImage { - images := make([]XCursorImage, 0, c.ImageCount()) +func (c *XCursor) Images() []*XCursorImage { + images := make([]*XCursorImage, 0, c.ImageCount()) for i := 0; i < cap(images); i++ { images = append(images, c.Image(i)) } return images } -func (c XCursor) ImageCount() int { +func (c *XCursor) ImageCount() int { return int(c.p.image_count) } -func (c XCursor) Name() string { +func (c *XCursor) Name() string { return C.GoString(c.p.name) } @@ -417,16 +418,13 @@ const ( EdgeRight Edges = C.WLR_EDGE_RIGHT ) +//go:notinheap type Texture struct { - p *C.struct_wlr_texture + p C.struct_wlr_texture } -func (t Texture) Destroy() { - C.wlr_texture_destroy(t.p) -} - -func (t Texture) Nil() bool { - return t.p == nil +func (t *Texture) Destroy() { + C.wlr_texture_destroy(&t.p) } type SurfaceType uint32 @@ -437,69 +435,66 @@ const ( SurfaceTypeXWayland ) +//go:notinheap type Surface struct { - p *C.struct_wlr_surface + p C.struct_wlr_surface } type SurfaceState struct { s C.struct_wlr_surface_state } -func (s Surface) Nil() bool { - return s.p == nil -} - -func (s Surface) OnDestroy(cb func(Surface)) { - man.add(unsafe.Pointer(s.p), &s.p.events.destroy, func(unsafe.Pointer) { +func (s *Surface) OnDestroy(cb func(*Surface)) { + man.add(unsafe.Pointer(s), &s.p.events.destroy, func(unsafe.Pointer) { cb(s) }) } -func (s Surface) Type() SurfaceType { - if C.wlr_surface_is_xdg_surface(s.p) { +func (s *Surface) Type() SurfaceType { + if C.wlr_surface_is_xdg_surface(&s.p) { return SurfaceTypeXDG - } else if C.wlr_surface_is_xwayland_surface(s.p) { + } else if C.wlr_surface_is_xwayland_surface(&s.p) { return SurfaceTypeXWayland } return SurfaceTypeNone } -func (s Surface) SurfaceAt(sx float64, sy float64) (surface Surface, subX float64, subY float64) { +func (s *Surface) SurfaceAt(sx float64, sy float64) (surface *Surface, subX float64, subY float64) { var csubX, csubY C.double - p := C.wlr_surface_surface_at(s.p, C.double(sx), C.double(sy), &csubX, &csubY) - return Surface{p: p}, float64(csubX), float64(csubY) + p := C.wlr_surface_surface_at(&s.p, C.double(sx), C.double(sy), &csubX, &csubY) + return (*Surface)(unsafe.Pointer(p)), float64(csubX), float64(csubY) } -func (s Surface) Texture() Texture { - p := C.wlr_surface_get_texture(s.p) - return Texture{p: p} +func (s *Surface) Texture() *Texture { + p := C.wlr_surface_get_texture(&s.p) + return (*Texture)(unsafe.Pointer(p)) } -func (s Surface) CurrentState() SurfaceState { +func (s *Surface) CurrentState() SurfaceState { return SurfaceState{s: s.p.current} } -func (s Surface) Walk(visit func()) { +func (s *Surface) Walk(visit func()) { panic("not implemented") } -func (s Surface) SendFrameDone(when time.Time) { +func (s *Surface) SendFrameDone(when time.Time) { // we ignore the returned error; the only possible error is // ERANGE, when timespec on a platform has int32 precision, but // our time requires 64 bits. This should not occur. t, _ := unix.TimeToTimespec(when) - C.wlr_surface_send_frame_done(s.p, (*C.struct_timespec)(unsafe.Pointer(&t))) + C.wlr_surface_send_frame_done(&s.p, (*C.struct_timespec)(unsafe.Pointer(&t))) } -func (s Surface) XDGSurface() XDGSurface { - p := C.wlr_xdg_surface_from_wlr_surface(s.p) - return XDGSurface{p: p} +func (s *Surface) XDGSurface() *XDGSurface { + p := C.wlr_xdg_surface_from_wlr_surface(&s.p) + return (*XDGSurface)(unsafe.Pointer(p)) } -func (s Surface) XWaylandSurface() XWaylandSurface { - p := C.wlr_xwayland_surface_from_wlr_surface(s.p) - return XWaylandSurface{p: p} +func (s *Surface) XWaylandSurface() *XWaylandSurface { + p := C.wlr_xwayland_surface_from_wlr_surface(&s.p) + return (*XWaylandSurface)(unsafe.Pointer(p)) } func (s SurfaceState) Width() int { @@ -514,12 +509,14 @@ func (s SurfaceState) Transform() uint32 { return uint32(s.s.transform) } +//go:notinheap type Seat struct { - p *C.struct_wlr_seat + p C.struct_wlr_seat } +//go:notinheap type SeatClient struct { - p *C.struct_wlr_seat_client + p C.struct_wlr_seat_client } type SeatKeyboardState struct { @@ -538,249 +535,249 @@ const ( SeatCapabilityTouch SeatCapability = C.WL_SEAT_CAPABILITY_TOUCH ) -func NewSeat(display Display, name string) Seat { +func NewSeat(display *Display, name string) *Seat { s := C.CString(name) - p := C.wlr_seat_create(display.p, s) + p := C.wlr_seat_create(&display.p, s) C.free(unsafe.Pointer(s)) man.track(unsafe.Pointer(p), &p.events.destroy) - return Seat{p: p} + return (*Seat)(unsafe.Pointer(p)) } -func (s Seat) Destroy() { - C.wlr_seat_destroy(s.p) +func (s *Seat) Destroy() { + C.wlr_seat_destroy(&s.p) } -func (s Seat) OnDestroy(cb func(Seat)) { - man.add(unsafe.Pointer(s.p), &s.p.events.destroy, func(unsafe.Pointer) { +func (s *Seat) OnDestroy(cb func(*Seat)) { + man.add(unsafe.Pointer(s), &s.p.events.destroy, func(unsafe.Pointer) { cb(s) }) } -func (s Seat) OnSetCursorRequest(cb func(client SeatClient, surface Surface, serial uint32, hotspotX int32, hotspotY int32)) { - man.add(unsafe.Pointer(s.p), &s.p.events.request_set_cursor, func(data unsafe.Pointer) { +func (s *Seat) OnSetCursorRequest(cb func(client *SeatClient, surface *Surface, serial uint32, hotspotX int32, hotspotY int32)) { + man.add(unsafe.Pointer(s), &s.p.events.request_set_cursor, func(data unsafe.Pointer) { event := (*C.struct_wlr_seat_pointer_request_set_cursor_event)(data) - client := SeatClient{p: event.seat_client} - surface := Surface{p: event.surface} + client := (*SeatClient)(unsafe.Pointer(event.seat_client)) + surface := (*Surface)(unsafe.Pointer(event.surface)) cb(client, surface, uint32(event.serial), int32(event.hotspot_x), int32(event.hotspot_y)) }) } -func (s Seat) SetCapabilities(caps SeatCapability) { - C.wlr_seat_set_capabilities(s.p, C.uint32_t(caps)) +func (s *Seat) SetCapabilities(caps SeatCapability) { + C.wlr_seat_set_capabilities(&s.p, C.uint32_t(caps)) } -func (s Seat) SetKeyboard(dev InputDevice) { - C.wlr_seat_set_keyboard(s.p, dev.p) +func (s *Seat) SetKeyboard(dev *InputDevice) { + C.wlr_seat_set_keyboard(&s.p, &dev.p) } -func (s Seat) NotifyPointerButton(time uint32, button uint32, state ButtonState) { - C.wlr_seat_pointer_notify_button(s.p, C.uint32_t(time), C.uint32_t(button), uint32(state)) +func (s *Seat) NotifyPointerButton(time uint32, button uint32, state ButtonState) { + C.wlr_seat_pointer_notify_button(&s.p, C.uint32_t(time), C.uint32_t(button), uint32(state)) } -func (s Seat) NotifyPointerAxis(time uint32, orientation AxisOrientation, delta float64, deltaDiscrete int32, source AxisSource) { - C.wlr_seat_pointer_notify_axis(s.p, C.uint32_t(time), C.enum_wlr_axis_orientation(orientation), C.double(delta), C.int32_t(deltaDiscrete), C.enum_wlr_axis_source(source)) +func (s *Seat) NotifyPointerAxis(time uint32, orientation AxisOrientation, delta float64, deltaDiscrete int32, source AxisSource) { + C.wlr_seat_pointer_notify_axis(&s.p, C.uint32_t(time), C.enum_wlr_axis_orientation(orientation), C.double(delta), C.int32_t(deltaDiscrete), C.enum_wlr_axis_source(source)) } -func (s Seat) NotifyPointerEnter(surface Surface, sx float64, sy float64) { - C.wlr_seat_pointer_notify_enter(s.p, surface.p, C.double(sx), C.double(sy)) +func (s *Seat) NotifyPointerEnter(surface *Surface, sx float64, sy float64) { + C.wlr_seat_pointer_notify_enter(&s.p, &surface.p, C.double(sx), C.double(sy)) } -func (s Seat) NotifyPointerMotion(time uint32, sx float64, sy float64) { - C.wlr_seat_pointer_notify_motion(s.p, C.uint32_t(time), C.double(sx), C.double(sy)) +func (s *Seat) NotifyPointerMotion(time uint32, sx float64, sy float64) { + C.wlr_seat_pointer_notify_motion(&s.p, C.uint32_t(time), C.double(sx), C.double(sy)) } -func (s Seat) NotifyPointerFrame() { - C.wlr_seat_pointer_notify_frame(s.p) +func (s *Seat) NotifyPointerFrame() { + C.wlr_seat_pointer_notify_frame(&s.p) } -func (s Seat) NotifyKeyboardEnter(surface Surface, k Keyboard) { - C.wlr_seat_keyboard_notify_enter(s.p, surface.p, &k.p.keycodes[0], k.p.num_keycodes, &k.p.modifiers) +func (s *Seat) NotifyKeyboardEnter(surface *Surface, k *Keyboard) { + C.wlr_seat_keyboard_notify_enter(&s.p, &surface.p, &k.p.keycodes[0], k.p.num_keycodes, &k.p.modifiers) } -func (s Seat) NotifyKeyboardModifiers(k Keyboard) { - C.wlr_seat_keyboard_notify_modifiers(s.p, &k.p.modifiers) +func (s *Seat) NotifyKeyboardModifiers(k *Keyboard) { + C.wlr_seat_keyboard_notify_modifiers(&s.p, &k.p.modifiers) } -func (s Seat) NotifyKeyboardKey(time uint32, keyCode uint32, state KeyState) { - C.wlr_seat_keyboard_notify_key(s.p, C.uint32_t(time), C.uint32_t(keyCode), C.uint32_t(state)) +func (s *Seat) NotifyKeyboardKey(time uint32, keyCode uint32, state KeyState) { + C.wlr_seat_keyboard_notify_key(&s.p, C.uint32_t(time), C.uint32_t(keyCode), C.uint32_t(state)) } -func (s Seat) ClearPointerFocus() { - C.wlr_seat_pointer_clear_focus(s.p) +func (s *Seat) ClearPointerFocus() { + C.wlr_seat_pointer_clear_focus(&s.p) } -func (s Seat) Keyboard() Keyboard { - p := C.wlr_seat_get_keyboard(s.p) - return Keyboard{p: p} +func (s *Seat) Keyboard() *Keyboard { + p := C.wlr_seat_get_keyboard(&s.p) + return (*Keyboard)(unsafe.Pointer(p)) } -func (s Seat) KeyboardState() SeatKeyboardState { +func (s *Seat) KeyboardState() SeatKeyboardState { return SeatKeyboardState{s: s.p.keyboard_state} } -func (s Seat) PointerState() SeatPointerState { +func (s *Seat) PointerState() SeatPointerState { return SeatPointerState{s: s.p.pointer_state} } -func (s SeatKeyboardState) FocusedSurface() Surface { - return Surface{p: s.s.focused_surface} +func (s SeatKeyboardState) FocusedSurface() *Surface { + return (*Surface)(unsafe.Pointer(s.s.focused_surface)) } -func (s SeatPointerState) FocusedSurface() Surface { - return Surface{p: s.s.focused_surface} +func (s SeatPointerState) FocusedSurface() *Surface { + return (*Surface)(unsafe.Pointer(s.s.focused_surface)) } -func (s SeatPointerState) FocusedClient() SeatClient { - return SeatClient{p: s.s.focused_client} +func (s SeatPointerState) FocusedClient() *SeatClient { + return (*SeatClient)(unsafe.Pointer(s.s.focused_client)) } +//go:notinheap type Renderer struct { - p *C.struct_wlr_renderer + p C.struct_wlr_renderer } -func (r Renderer) Destroy() { - C.wlr_renderer_destroy(r.p) +func (r *Renderer) Destroy() { + C.wlr_renderer_destroy(&r.p) } -func (r Renderer) OnDestroy(cb func(Renderer)) { - man.add(unsafe.Pointer(r.p), &r.p.events.destroy, func(unsafe.Pointer) { +func (r *Renderer) OnDestroy(cb func(*Renderer)) { + man.add(unsafe.Pointer(r), &r.p.events.destroy, func(unsafe.Pointer) { cb(r) }) } -func (r Renderer) InitDisplay(display Display) { - C.wlr_renderer_init_wl_display(r.p, display.p) +func (r *Renderer) InitDisplay(display *Display) { + C.wlr_renderer_init_wl_display(&r.p, &display.p) } -func (r Renderer) Begin(output Output, width int, height int) { - C.wlr_renderer_begin(r.p, C.int(width), C.int(height)) +func (r *Renderer) Begin(output *Output, width int, height int) { + C.wlr_renderer_begin(&r.p, C.int(width), C.int(height)) } -func (r Renderer) Clear(color *Color) { +func (r *Renderer) Clear(color *Color) { c := color.toC() - C.wlr_renderer_clear(r.p, &c[0]) + C.wlr_renderer_clear(&r.p, &c[0]) } -func (r Renderer) End() { - C.wlr_renderer_end(r.p) +func (r *Renderer) End() { + C.wlr_renderer_end(&r.p) } -func (r Renderer) RenderTextureWithMatrix(texture Texture, matrix *Matrix, alpha float32) { +func (r *Renderer) RenderTextureWithMatrix(texture *Texture, matrix *Matrix, alpha float32) { m := matrix.toC() - C.wlr_render_texture_with_matrix(r.p, texture.p, &m[0], C.float(alpha)) + C.wlr_render_texture_with_matrix(&r.p, &texture.p, &m[0], C.float(alpha)) } -func (r Renderer) RenderRect(box *Box, color *Color, projection *Matrix) { +func (r *Renderer) RenderRect(box *Box, color *Color, projection *Matrix) { b := box.toC() c := color.toC() pm := projection.toC() - C.wlr_render_rect(r.p, &b, &c[0], &pm[0]) + C.wlr_render_rect(&r.p, &b, &c[0], &pm[0]) } +//go:notinheap type Output struct { - p *C.struct_wlr_output + p C.struct_wlr_output } +//go:notinheap type OutputMode struct { - p *C.struct_wlr_output_mode -} - -func wrapOutput(p unsafe.Pointer) Output { - return Output{p: (*C.struct_wlr_output)(p)} + p C.struct_wlr_output_mode } -func (o Output) OnDestroy(cb func(Output)) { - man.add(unsafe.Pointer(o.p), &o.p.events.destroy, func(unsafe.Pointer) { +func (o *Output) OnDestroy(cb func(*Output)) { + man.add(unsafe.Pointer(o), &o.p.events.destroy, func(unsafe.Pointer) { cb(o) }) } -func (o Output) Name() string { +func (o *Output) Name() string { return C.GoString(&o.p.name[0]) } -func (o Output) Scale() float32 { +func (o *Output) Scale() float32 { return float32(o.p.scale) } -func (o Output) TransformMatrix() Matrix { +func (o *Output) TransformMatrix() Matrix { var matrix Matrix matrix.fromC(&o.p.transform_matrix) return matrix } -func (o Output) OnFrame(cb func(Output)) { - man.add(unsafe.Pointer(o.p), &o.p.events.frame, func(data unsafe.Pointer) { +func (o *Output) OnFrame(cb func(*Output)) { + man.add(unsafe.Pointer(o), &o.p.events.frame, func(data unsafe.Pointer) { cb(o) }) } -func (o Output) RenderSoftwareCursors() { - C.wlr_output_render_software_cursors(o.p, nil) +func (o *Output) RenderSoftwareCursors() { + C.wlr_output_render_software_cursors(&o.p, nil) } -func (o Output) TransformedResolution() (int, int) { +func (o *Output) TransformedResolution() (int, int) { var width, height C.int - C.wlr_output_transformed_resolution(o.p, &width, &height) + C.wlr_output_transformed_resolution(&o.p, &width, &height) return int(width), int(height) } -func (o Output) EffectiveResolution() (int, int) { +func (o *Output) EffectiveResolution() (int, int) { var width, height C.int - C.wlr_output_effective_resolution(o.p, &width, &height) + C.wlr_output_effective_resolution(&o.p, &width, &height) return int(width), int(height) } -func (o Output) AttachRender() (int, error) { +func (o *Output) AttachRender() (int, error) { var bufferAge C.int - if !C.wlr_output_attach_render(o.p, &bufferAge) { + if !C.wlr_output_attach_render(&o.p, &bufferAge) { return 0, errors.New("can't make output context current") } return int(bufferAge), nil } -func (o Output) Rollback() { - C.wlr_output_rollback(o.p) +func (o *Output) Rollback() { + C.wlr_output_rollback(&o.p) } -func (o Output) CreateGlobal() { - C.wlr_output_create_global(o.p) +func (o *Output) CreateGlobal() { + C.wlr_output_create_global(&o.p) } -func (o Output) DestroyGlobal() { - C.wlr_output_destroy_global(o.p) +func (o *Output) DestroyGlobal() { + C.wlr_output_destroy_global(&o.p) } -func (o Output) Commit() { - C.wlr_output_commit(o.p) +func (o *Output) Commit() { + C.wlr_output_commit(&o.p) } -func (o Output) Modes() []OutputMode { +func (o *Output) Modes() []*OutputMode { // TODO: figure out what to do with this ridiculous for loop // perhaps this can be refactored into a less ugly hack that uses reflection - var modes []OutputMode + var modes []*OutputMode var mode *C.struct_wlr_output_mode for mode := (*C.struct_wlr_output_mode)(unsafe.Pointer(uintptr(unsafe.Pointer(o.p.modes.next)) - unsafe.Offsetof(mode.link))); &mode.link != &o.p.modes; mode = (*C.struct_wlr_output_mode)(unsafe.Pointer(uintptr(unsafe.Pointer(mode.link.next)) - unsafe.Offsetof(mode.link))) { - modes = append(modes, OutputMode{p: mode}) + modes = append(modes, (*OutputMode)(unsafe.Pointer(mode))) } return modes } -func (o Output) SetMode(mode OutputMode) { - C.wlr_output_set_mode(o.p, mode.p) +func (o *Output) SetMode(mode *OutputMode) { + C.wlr_output_set_mode(&o.p, &mode.p) } -func (o Output) Enable(enable bool) { - C.wlr_output_enable(o.p, C.bool(enable)) +func (o *Output) Enable(enable bool) { + C.wlr_output_enable(&o.p, C.bool(enable)) } -func (o Output) SetTitle(title string) error { - if C.wlr_output_is_wl(o.p) { - C.wlr_wl_output_set_title(o.p, C.CString(title)) - } else if C.wlr_output_is_x11(o.p) { - C.wlr_x11_output_set_title(o.p, C.CString(title)) +func (o *Output) SetTitle(title string) error { + // FIXME(dh): who owns the *char? do we need to free it, now or later? + if C.wlr_output_is_wl(&o.p) { + C.wlr_wl_output_set_title(&o.p, C.CString(title)) + } else if C.wlr_output_is_x11(&o.p) { + C.wlr_x11_output_set_title(&o.p, C.CString(title)) } else { return errors.New("this output type cannot have a title") } @@ -788,27 +785,28 @@ func (o Output) SetTitle(title string) error { return nil } +//go:notinheap type OutputLayout struct { - p *C.struct_wlr_output_layout + p C.struct_wlr_output_layout } -func NewOutputLayout() OutputLayout { +func NewOutputLayout() *OutputLayout { p := C.wlr_output_layout_create() man.track(unsafe.Pointer(p), &p.events.destroy) - return OutputLayout{p: p} + return (*OutputLayout)(unsafe.Pointer(p)) } -func (l OutputLayout) Destroy() { - C.wlr_output_layout_destroy(l.p) +func (l *OutputLayout) Destroy() { + C.wlr_output_layout_destroy(&l.p) } -func (l OutputLayout) AddOutputAuto(output Output) { - C.wlr_output_layout_add_auto(l.p, output.p) +func (l *OutputLayout) AddOutputAuto(output *Output) { + C.wlr_output_layout_add_auto(&l.p, &output.p) } -func (l OutputLayout) Coords(output Output) (x float64, y float64) { +func (l *OutputLayout) Coords(output *Output) (x float64, y float64) { var ox, oy C.double - C.wlr_output_layout_output_coords(l.p, output.p, &ox, &oy) + C.wlr_output_layout_output_coords(&l.p, &output.p, &ox, &oy) return float64(ox), float64(oy) } @@ -816,15 +814,15 @@ func OutputTransformInvert(transform uint32) uint32 { return uint32(C.wlr_output_transform_invert(C.enum_wl_output_transform(transform))) } -func (m OutputMode) Width() int32 { +func (m *OutputMode) Width() int32 { return int32(m.p.width) } -func (m OutputMode) Height() int32 { +func (m *OutputMode) Height() int32 { return int32(m.p.height) } -func (m OutputMode) RefreshRate() int32 { +func (m *OutputMode) RefreshRate() int32 { return int32(m.p.refresh) } @@ -899,38 +897,39 @@ const ( KeyboardModifierMod5 KeyboardModifier = C.WLR_MODIFIER_MOD5 ) +//go:notinheap type Keyboard struct { - p *C.struct_wlr_keyboard + p C.struct_wlr_keyboard } -func (k Keyboard) SetKeymap(keymap xkb.Keymap) { - C.wlr_keyboard_set_keymap(k.p, (*C.struct_xkb_keymap)(keymap.Ptr())) +func (k *Keyboard) SetKeymap(keymap xkb.Keymap) { + C.wlr_keyboard_set_keymap(&k.p, (*C.struct_xkb_keymap)(keymap.Ptr())) } -func (k Keyboard) RepeatInfo() (rate int32, delay int32) { +func (k *Keyboard) RepeatInfo() (rate int32, delay int32) { return int32(k.p.repeat_info.rate), int32(k.p.repeat_info.delay) } -func (k Keyboard) SetRepeatInfo(rate int32, delay int32) { - C.wlr_keyboard_set_repeat_info(k.p, C.int32_t(rate), C.int32_t(delay)) +func (k *Keyboard) SetRepeatInfo(rate int32, delay int32) { + C.wlr_keyboard_set_repeat_info(&k.p, C.int32_t(rate), C.int32_t(delay)) } -func (k Keyboard) XKBState() xkb.State { +func (k *Keyboard) XKBState() xkb.State { return xkb.WrapState(unsafe.Pointer(k.p.xkb_state)) } -func (k Keyboard) Modifiers() KeyboardModifier { - return KeyboardModifier(C.wlr_keyboard_get_modifiers(k.p)) +func (k *Keyboard) Modifiers() KeyboardModifier { + return KeyboardModifier(C.wlr_keyboard_get_modifiers(&k.p)) } -func (k Keyboard) OnModifiers(cb func(keyboard Keyboard)) { - man.add(unsafe.Pointer(k.p), &k.p.events.modifiers, func(data unsafe.Pointer) { +func (k *Keyboard) OnModifiers(cb func(keyboard *Keyboard)) { + man.add(unsafe.Pointer(k), &k.p.events.modifiers, func(data unsafe.Pointer) { cb(k) }) } -func (k Keyboard) OnKey(cb func(keyboard Keyboard, time uint32, keyCode uint32, updateState bool, state KeyState)) { - man.add(unsafe.Pointer(k.p), &k.p.events.key, func(data unsafe.Pointer) { +func (k *Keyboard) OnKey(cb func(keyboard *Keyboard, time uint32, keyCode uint32, updateState bool, state KeyState)) { + man.add(unsafe.Pointer(k), &k.p.events.key, func(data unsafe.Pointer) { event := (*C.struct_wlr_event_keyboard_key)(data) cb(k, uint32(event.time_msec), uint32(event.keycode), bool(event.update_state), KeyState(event.state)) }) @@ -970,25 +969,26 @@ const ( AxisOrientationHorizontal AxisOrientation = C.WLR_AXIS_ORIENTATION_HORIZONTAL ) +//go:notinheap type InputDevice struct { - p *C.struct_wlr_input_device + p C.struct_wlr_input_device } -func (d InputDevice) OnDestroy(cb func(InputDevice)) { - man.add(unsafe.Pointer(d.p), &d.p.events.destroy, func(unsafe.Pointer) { +func (d *InputDevice) OnDestroy(cb func(*InputDevice)) { + man.add(unsafe.Pointer(d), &d.p.events.destroy, func(unsafe.Pointer) { cb(d) }) } -func (d InputDevice) Type() InputDeviceType { return InputDeviceType(d.p._type) } -func (d InputDevice) Vendor() int { return int(d.p.vendor) } -func (d InputDevice) Product() int { return int(d.p.product) } -func (d InputDevice) Name() string { return C.GoString(d.p.name) } -func (d InputDevice) Width() float64 { return float64(d.p.width_mm) } -func (d InputDevice) Height() float64 { return float64(d.p.height_mm) } -func (d InputDevice) OutputName() string { return C.GoString(d.p.output_name) } +func (d *InputDevice) Type() InputDeviceType { return InputDeviceType(d.p._type) } +func (d *InputDevice) Vendor() int { return int(d.p.vendor) } +func (d *InputDevice) Product() int { return int(d.p.product) } +func (d *InputDevice) Name() string { return C.GoString(d.p.name) } +func (d *InputDevice) Width() float64 { return float64(d.p.width_mm) } +func (d *InputDevice) Height() float64 { return float64(d.p.height_mm) } +func (d *InputDevice) OutputName() string { return C.GoString(d.p.output_name) } -func validateInputDeviceType(d InputDevice, fn string, req InputDeviceType) { +func validateInputDeviceType(d *InputDevice, fn string, req InputDeviceType) { if typ := d.Type(); typ != req { if int(typ) >= len(inputDeviceNames) { panic(fmt.Sprintf("%s called on input device of type %d", fn, typ)) @@ -998,100 +998,99 @@ func validateInputDeviceType(d InputDevice, fn string, req InputDeviceType) { } } -func (d InputDevice) Keyboard() Keyboard { +func (d *InputDevice) Keyboard() *Keyboard { validateInputDeviceType(d, "Keyboard", InputDeviceTypeKeyboard) p := *(*unsafe.Pointer)(unsafe.Pointer(&d.p.anon0[0])) - return Keyboard{p: (*C.struct_wlr_keyboard)(p)} -} - -func wrapInputDevice(p unsafe.Pointer) InputDevice { - return InputDevice{p: (*C.struct_wlr_input_device)(p)} + return (*Keyboard)(p) } +//go:notinheap type DMABuf struct { - p *C.struct_wlr_linux_dmabuf_v1 + p C.struct_wlr_linux_dmabuf_v1 } -func NewDMABuf(display Display, renderer Renderer) DMABuf { - p := C.wlr_linux_dmabuf_v1_create(display.p, renderer.p) +func NewDMABuf(display *Display, renderer *Renderer) *DMABuf { + p := C.wlr_linux_dmabuf_v1_create(&display.p, &renderer.p) man.track(unsafe.Pointer(p), &p.events.destroy) - return DMABuf{p: p} + return (*DMABuf)(unsafe.Pointer(p)) } -func (b DMABuf) OnDestroy(cb func(DMABuf)) { - man.add(unsafe.Pointer(b.p), &b.p.events.destroy, func(unsafe.Pointer) { +func (b *DMABuf) OnDestroy(cb func(*DMABuf)) { + man.add(unsafe.Pointer(b), &b.p.events.destroy, func(unsafe.Pointer) { cb(b) }) } +//go:notinheap type EventLoop struct { - p *C.struct_wl_event_loop + p C.struct_wl_event_loop } -func (evl EventLoop) OnDestroy(cb func(EventLoop)) { - l := man.add(unsafe.Pointer(evl.p), nil, func(data unsafe.Pointer) { +func (evl *EventLoop) OnDestroy(cb func(*EventLoop)) { + l := man.add(unsafe.Pointer(evl), nil, func(data unsafe.Pointer) { cb(evl) }) - C.wl_event_loop_add_destroy_listener(evl.p, l.p) + C.wl_event_loop_add_destroy_listener(&evl.p, l.p) } -func (evl EventLoop) Fd() uintptr { - return uintptr(C.wl_event_loop_get_fd(evl.p)) +func (evl *EventLoop) Fd() uintptr { + return uintptr(C.wl_event_loop_get_fd(&evl.p)) } -func (evl EventLoop) Dispatch(timeout time.Duration) { +func (evl *EventLoop) Dispatch(timeout time.Duration) { var d int if timeout >= 0 { d = int(timeout / time.Millisecond) } else { d = -1 } - C.wl_event_loop_dispatch(evl.p, C.int(d)) + C.wl_event_loop_dispatch(&evl.p, C.int(d)) } +//go:notinheap type Display struct { - p *C.struct_wl_display + p C.struct_wl_display } -func NewDisplay() Display { +func NewDisplay() *Display { p := C.wl_display_create() - d := Display{p: p} - d.OnDestroy(func(Display) { + d := (*Display)(unsafe.Pointer(p)) + d.OnDestroy(func(*Display) { man.delete(unsafe.Pointer(p)) }) return d } -func (d Display) Destroy() { - C.wl_display_destroy(d.p) +func (d *Display) Destroy() { + C.wl_display_destroy(&d.p) } -func (d Display) OnDestroy(cb func(Display)) { - l := man.add(unsafe.Pointer(d.p), nil, func(data unsafe.Pointer) { +func (d *Display) OnDestroy(cb func(*Display)) { + l := man.add(unsafe.Pointer(d), nil, func(data unsafe.Pointer) { cb(d) }) - C.wl_display_add_destroy_listener(d.p, l.p) + C.wl_display_add_destroy_listener(&d.p, l.p) } -func (d Display) Run() { - C.wl_display_run(d.p) +func (d *Display) Run() { + C.wl_display_run(&d.p) } -func (d Display) Terminate() { - C.wl_display_terminate(d.p) +func (d *Display) Terminate() { + C.wl_display_terminate(&d.p) } -func (d Display) EventLoop() EventLoop { - p := C.wl_display_get_event_loop(d.p) - evl := EventLoop{p: p} - evl.OnDestroy(func(EventLoop) { +func (d *Display) EventLoop() *EventLoop { + p := C.wl_display_get_event_loop(&d.p) + evl := (*EventLoop)(unsafe.Pointer(p)) + evl.OnDestroy(func(*EventLoop) { man.delete(unsafe.Pointer(p)) }) return evl } -func (d Display) AddSocketAuto() (string, error) { - socket := C.wl_display_add_socket_auto(d.p) +func (d *Display) AddSocketAuto() (string, error) { + socket := C.wl_display_add_socket_auto(&d.p) if socket == nil { return "", errors.New("can't auto add wayland socket") } @@ -1099,8 +1098,8 @@ func (d Display) AddSocketAuto() (string, error) { return C.GoString(socket), nil } -func (d Display) FlushClients() { - C.wl_display_flush_clients(d.p) +func (d *Display) FlushClients() { + C.wl_display_flush_clients(&d.p) } type ServerDecorationManagerMode uint32 @@ -1111,164 +1110,167 @@ const ( ServerDecorationManagerModeServer ServerDecorationManagerMode = C.WLR_SERVER_DECORATION_MANAGER_MODE_SERVER ) +//go:notinheap type ServerDecorationManager struct { - p *C.struct_wlr_server_decoration_manager + p C.struct_wlr_server_decoration_manager } +//go:notinheap type ServerDecoration struct { - p *C.struct_wlr_server_decoration + p C.struct_wlr_server_decoration } -func NewServerDecorationManager(display Display) ServerDecorationManager { - p := C.wlr_server_decoration_manager_create(display.p) +func NewServerDecorationManager(display *Display) *ServerDecorationManager { + p := C.wlr_server_decoration_manager_create(&display.p) man.track(unsafe.Pointer(p), &p.events.destroy) - return ServerDecorationManager{p: p} + return (*ServerDecorationManager)(unsafe.Pointer(p)) } -func (m ServerDecorationManager) OnDestroy(cb func(ServerDecorationManager)) { - man.add(unsafe.Pointer(m.p), &m.p.events.destroy, func(unsafe.Pointer) { +func (m *ServerDecorationManager) OnDestroy(cb func(*ServerDecorationManager)) { + man.add(unsafe.Pointer(m), &m.p.events.destroy, func(unsafe.Pointer) { cb(m) }) } -func (m ServerDecorationManager) SetDefaultMode(mode ServerDecorationManagerMode) { - C.wlr_server_decoration_manager_set_default_mode(m.p, C.uint32_t(mode)) +func (m *ServerDecorationManager) SetDefaultMode(mode ServerDecorationManagerMode) { + C.wlr_server_decoration_manager_set_default_mode(&m.p, C.uint32_t(mode)) } -func (m ServerDecorationManager) OnNewMode(cb func(ServerDecorationManager, ServerDecoration)) { - man.add(unsafe.Pointer(m.p), &m.p.events.new_decoration, func(data unsafe.Pointer) { - dec := ServerDecoration{ - p: (*C.struct_wlr_server_decoration)(data), - } - man.track(unsafe.Pointer(dec.p), &dec.p.events.destroy) +func (m *ServerDecorationManager) OnNewMode(cb func(*ServerDecorationManager, *ServerDecoration)) { + man.add(unsafe.Pointer(m), &m.p.events.new_decoration, func(data unsafe.Pointer) { + dec := (*ServerDecoration)(data) + man.track(unsafe.Pointer(&dec.p), &dec.p.events.destroy) cb(m, dec) }) } -func (d ServerDecoration) OnDestroy(cb func(ServerDecoration)) { - man.add(unsafe.Pointer(d.p), &d.p.events.destroy, func(unsafe.Pointer) { +func (d *ServerDecoration) OnDestroy(cb func(*ServerDecoration)) { + man.add(unsafe.Pointer(d), &d.p.events.destroy, func(unsafe.Pointer) { cb(d) }) } -func (d ServerDecoration) OnMode(cb func(ServerDecoration)) { - man.add(unsafe.Pointer(d.p), &d.p.events.mode, func(unsafe.Pointer) { +func (d *ServerDecoration) OnMode(cb func(*ServerDecoration)) { + man.add(unsafe.Pointer(d), &d.p.events.mode, func(unsafe.Pointer) { cb(d) }) } -func (d ServerDecoration) Mode() ServerDecorationManagerMode { +func (d *ServerDecoration) Mode() ServerDecorationManagerMode { return ServerDecorationManagerMode(d.p.mode) } +//go:notinheap type DataDeviceManager struct { - p *C.struct_wlr_data_device_manager + p C.struct_wlr_data_device_manager } -func NewDataDeviceManager(display Display) DataDeviceManager { - p := C.wlr_data_device_manager_create(display.p) +func NewDataDeviceManager(display *Display) *DataDeviceManager { + p := C.wlr_data_device_manager_create(&display.p) man.track(unsafe.Pointer(p), &p.events.destroy) - return DataDeviceManager{p: p} + return (*DataDeviceManager)(unsafe.Pointer(p)) } -func (m DataDeviceManager) OnDestroy(cb func(DataDeviceManager)) { - man.add(unsafe.Pointer(m.p), &m.p.events.destroy, func(unsafe.Pointer) { +func (m *DataDeviceManager) OnDestroy(cb func(*DataDeviceManager)) { + man.add(unsafe.Pointer(m), &m.p.events.destroy, func(unsafe.Pointer) { cb(m) }) } +//go:notinheap type Cursor struct { - p *C.struct_wlr_cursor + p C.struct_wlr_cursor } -func NewCursor() Cursor { +func NewCursor() *Cursor { p := C.wlr_cursor_create() - return Cursor{p: p} + return (*Cursor)(unsafe.Pointer(p)) } -func (c Cursor) Destroy() { - C.wlr_cursor_destroy(c.p) - man.delete(unsafe.Pointer(c.p)) +func (c *Cursor) Destroy() { + C.wlr_cursor_destroy(&c.p) + man.delete(unsafe.Pointer(c)) } -func (c Cursor) X() float64 { +func (c *Cursor) X() float64 { return float64(c.p.x) } -func (c Cursor) Y() float64 { +func (c *Cursor) Y() float64 { return float64(c.p.y) } -func (c Cursor) AttachOutputLayout(layout OutputLayout) { - C.wlr_cursor_attach_output_layout(c.p, layout.p) +func (c *Cursor) AttachOutputLayout(layout *OutputLayout) { + C.wlr_cursor_attach_output_layout(&c.p, &layout.p) } -func (c Cursor) AttachInputDevice(dev InputDevice) { - C.wlr_cursor_attach_input_device(c.p, dev.p) +func (c *Cursor) AttachInputDevice(dev *InputDevice) { + C.wlr_cursor_attach_input_device(&c.p, &dev.p) } -func (c Cursor) Move(dev InputDevice, dx float64, dy float64) { - C.wlr_cursor_move(c.p, dev.p, C.double(dx), C.double(dy)) +func (c *Cursor) Move(dev *InputDevice, dx float64, dy float64) { + C.wlr_cursor_move(&c.p, &dev.p, C.double(dx), C.double(dy)) } -func (c Cursor) WarpAbsolute(dev InputDevice, x float64, y float64) { - C.wlr_cursor_warp_absolute(c.p, dev.p, C.double(x), C.double(y)) +func (c *Cursor) WarpAbsolute(dev *InputDevice, x float64, y float64) { + C.wlr_cursor_warp_absolute(&c.p, &dev.p, C.double(x), C.double(y)) } -func (c Cursor) SetSurface(surface Surface, hotspotX int32, hotspotY int32) { - C.wlr_cursor_set_surface(c.p, surface.p, C.int32_t(hotspotX), C.int32_t(hotspotY)) +func (c *Cursor) SetSurface(surface *Surface, hotspotX int32, hotspotY int32) { + C.wlr_cursor_set_surface(&c.p, &surface.p, C.int32_t(hotspotX), C.int32_t(hotspotY)) } -func (c Cursor) OnMotion(cb func(dev InputDevice, time uint32, dx float64, dy float64)) { - man.add(unsafe.Pointer(c.p), &c.p.events.motion, func(data unsafe.Pointer) { +func (c *Cursor) OnMotion(cb func(dev *InputDevice, time uint32, dx float64, dy float64)) { + man.add(unsafe.Pointer(c), &c.p.events.motion, func(data unsafe.Pointer) { event := (*C.struct_wlr_event_pointer_motion)(data) - dev := InputDevice{p: event.device} + dev := (*InputDevice)(unsafe.Pointer(event.device)) cb(dev, uint32(event.time_msec), float64(event.delta_x), float64(event.delta_y)) }) } -func (c Cursor) OnMotionAbsolute(cb func(dev InputDevice, time uint32, x float64, y float64)) { - man.add(unsafe.Pointer(c.p), &c.p.events.motion_absolute, func(data unsafe.Pointer) { +func (c *Cursor) OnMotionAbsolute(cb func(dev *InputDevice, time uint32, x float64, y float64)) { + man.add(unsafe.Pointer(c), &c.p.events.motion_absolute, func(data unsafe.Pointer) { event := (*C.struct_wlr_event_pointer_motion_absolute)(data) - dev := InputDevice{p: event.device} + dev := (*InputDevice)(unsafe.Pointer(event.device)) cb(dev, uint32(event.time_msec), float64(event.x), float64(event.y)) }) } -func (c Cursor) OnButton(cb func(dev InputDevice, time uint32, button uint32, state ButtonState)) { - man.add(unsafe.Pointer(c.p), &c.p.events.button, func(data unsafe.Pointer) { +func (c *Cursor) OnButton(cb func(dev *InputDevice, time uint32, button uint32, state ButtonState)) { + man.add(unsafe.Pointer(c), &c.p.events.button, func(data unsafe.Pointer) { event := (*C.struct_wlr_event_pointer_button)(data) - dev := InputDevice{p: event.device} + dev := (*InputDevice)(unsafe.Pointer(event.device)) cb(dev, uint32(event.time_msec), uint32(event.button), ButtonState(event.state)) }) } -func (c Cursor) OnAxis(cb func(dev InputDevice, time uint32, source AxisSource, orientation AxisOrientation, delta float64, deltaDiscrete int32)) { - man.add(unsafe.Pointer(c.p), &c.p.events.axis, func(data unsafe.Pointer) { +func (c *Cursor) OnAxis(cb func(dev *InputDevice, time uint32, source AxisSource, orientation AxisOrientation, delta float64, deltaDiscrete int32)) { + man.add(unsafe.Pointer(c), &c.p.events.axis, func(data unsafe.Pointer) { event := (*C.struct_wlr_event_pointer_axis)(data) - dev := InputDevice{p: event.device} + dev := (*InputDevice)(unsafe.Pointer(event.device)) cb(dev, uint32(event.time_msec), AxisSource(event.source), AxisOrientation(event.orientation), float64(event.delta), int32(event.delta_discrete)) }) } -func (c Cursor) OnFrame(cb func()) { - man.add(unsafe.Pointer(c.p), &c.p.events.frame, func(data unsafe.Pointer) { +func (c *Cursor) OnFrame(cb func()) { + man.add(unsafe.Pointer(c), &c.p.events.frame, func(data unsafe.Pointer) { cb() }) } +//go:notinheap type Compositor struct { - p *C.struct_wlr_compositor + p C.struct_wlr_compositor } -func NewCompositor(display Display, renderer Renderer) Compositor { - p := C.wlr_compositor_create(display.p, renderer.p) +func NewCompositor(display *Display, renderer *Renderer) *Compositor { + p := C.wlr_compositor_create(&display.p, &renderer.p) man.track(unsafe.Pointer(p), &p.events.destroy) - return Compositor{p: p} + return (*Compositor)(unsafe.Pointer(p)) } -func (c Compositor) OnDestroy(cb func(Compositor)) { - man.add(unsafe.Pointer(c.p), &c.p.events.destroy, func(unsafe.Pointer) { +func (c *Compositor) OnDestroy(cb func(*Compositor)) { + man.add(unsafe.Pointer(c), &c.p.events.destroy, func(unsafe.Pointer) { cb(c) }) } @@ -1320,59 +1322,60 @@ func (b *Box) fromC(cb *C.struct_wlr_box) { b.Height = int(cb.height) } +//go:notinheap type Backend struct { - p *C.struct_wlr_backend + p C.struct_wlr_backend } -func NewBackend(display Display) Backend { - p := C.wlr_backend_autocreate(display.p, nil) +func NewBackend(display *Display) *Backend { + p := C.wlr_backend_autocreate(&display.p, nil) man.track(unsafe.Pointer(p), &p.events.destroy) - return Backend{p: p} + return (*Backend)(unsafe.Pointer(p)) } -func (b Backend) Destroy() { - C.wlr_backend_destroy(b.p) +func (b *Backend) Destroy() { + C.wlr_backend_destroy(&b.p) } -func (b Backend) OnDestroy(cb func(Backend)) { - man.add(unsafe.Pointer(b.p), &b.p.events.destroy, func(unsafe.Pointer) { +func (b *Backend) OnDestroy(cb func(*Backend)) { + man.add(unsafe.Pointer(b), &b.p.events.destroy, func(unsafe.Pointer) { cb(b) }) } -func (b Backend) Start() error { - if !C.wlr_backend_start(b.p) { +func (b *Backend) Start() error { + if !C.wlr_backend_start(&b.p) { return errors.New("can't start backend") } return nil } -func (b Backend) OnNewOutput(cb func(Output)) { - man.add(unsafe.Pointer(b.p), &b.p.events.new_output, func(data unsafe.Pointer) { - output := wrapOutput(data) - man.track(unsafe.Pointer(output.p), &output.p.events.destroy) +func (b *Backend) OnNewOutput(cb func(*Output)) { + man.add(unsafe.Pointer(b), &b.p.events.new_output, func(data unsafe.Pointer) { + output := (*Output)(data) + man.track(data, &output.p.events.destroy) cb(output) }) } -func (b Backend) OnNewInput(cb func(InputDevice)) { - man.add(unsafe.Pointer(b.p), &b.p.events.new_input, func(data unsafe.Pointer) { - dev := wrapInputDevice(data) - man.add(unsafe.Pointer(dev.p), &dev.p.events.destroy, func(data unsafe.Pointer) { +func (b *Backend) OnNewInput(cb func(*InputDevice)) { + man.add(unsafe.Pointer(b), &b.p.events.new_input, func(data unsafe.Pointer) { + dev := (*InputDevice)(data) + man.add(data, &dev.p.events.destroy, func(data unsafe.Pointer) { // delete the underlying device type first man.delete(*(*unsafe.Pointer)(unsafe.Pointer(&dev.p.anon0[0]))) // then delete the wlr_input_device itself - man.delete(unsafe.Pointer(dev.p)) + man.delete(unsafe.Pointer(&dev.p)) }) cb(dev) }) } -func (b Backend) Renderer() Renderer { - p := C.wlr_backend_get_renderer(b.p) +func (b *Backend) Renderer() *Renderer { + p := C.wlr_backend_get_renderer(&b.p) man.track(unsafe.Pointer(p), &p.events.destroy) - return Renderer{p: p} + return (*Renderer)(unsafe.Pointer(p)) } // This whole mess has to exist for a number of reasons: