1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
package ui
import (
"fmt"
"image"
"image/draw"
//"log"
"syscall"
"github.com/dkolbly/wl"
"github.com/dkolbly/wl/xdg"
)
type Window struct {
display *Display
surface *wl.Surface
shSurface *wl.ShellSurface
xdgSurface *xdg.Surface
buffer *wl.Buffer
data []byte
image *BGRA
title string
pending Config
current Config
}
func (d *Display) NewWindow(width, height int32) (*Window, error) {
var err error
stride := width * 4
w := new(Window)
pend := Config{
Width: int(width),
Height: int(height),
}
w.pending = pend
w.current = pend
w.display = d
w.surface, err = d.compositor.CreateSurface()
if err != nil {
return nil, fmt.Errorf("Surface creation failed: %s", err)
}
w.buffer, w.data, err = d.newBuffer(width, height, stride)
if err != nil {
return nil, err
}
if d.wmBase != nil {
// New XDG shell
w.setupXDGTopLevel()
} else {
// older plain-jane wl_shell
w.shSurface, err = d.shell.GetShellSurface(w.surface)
if err != nil {
return nil, fmt.Errorf("Shell.GetShellSurface failed: %s", err)
}
w.shSurface.AddPingHandler(w)
w.shSurface.SetToplevel()
}
err = w.surface.Attach(w.buffer, width, height)
if err != nil {
return nil, fmt.Errorf("Surface.Attach failed: %s", err)
}
err = w.surface.Damage(0, 0, width, height)
if err != nil {
return nil, fmt.Errorf("Surface.Damage failed: %s", err)
}
if true {
err = w.surface.Commit()
if err != nil {
return nil, fmt.Errorf("Surface.Commit failed: %s", err)
}
w.image = NewBGRAWithData(
image.Rect(0, 0, int(width), int(height)),
w.data)
d.registerWindow(w)
}
return w, nil
}
func (w *Window) DrawUsingFunc(fn func(*BGRA)) {
fn(w.image)
}
func (w *Window) Draw(img image.Image) {
draw.Draw(w.image, img.Bounds(), img, img.Bounds().Min, draw.Src)
}
func (w *Window) Dispose() {
if w.shSurface != nil {
w.shSurface.RemovePingHandler(w)
}
w.surface.Destroy()
w.buffer.Destroy()
syscall.Munmap(w.data)
w.display.unregisterWindow(w)
}
func (w *Window) HandleShellSurfacePing(ev wl.ShellSurfacePingEvent) {
w.shSurface.Pong(ev.Serial)
}
|