// Repaint paints the backing store onto the X window. func (win *Window) repaint(x, y, w, h int) { cr := cairo.Create(win.winSurface.Surface) cr.Rectangle(float64(x), float64(y), float64(w), float64(h)) cr.Clip() if flip { cr.SetSourceRGB(1, 0, 0) } else { cr.SetSourceSurface(win.bufSurface.Surface, 0, 0) // TODO clip to exposed area? cr.SetOperator(cairo.OperatorSource) } // flip = !flip cr.Paint() }
// Loop runs the main X loop. func (dpy *Display) Loop(uwin ui.Win) { win := uwin.(*Window) awaitEvent := make(chan bool) go func() { xfd := int(C.XConnectionNumber(dpy.dpy)) for { <-awaitEvent err := waitUntilReadable(xfd) if err != nil { log.Fatalf("select %#v", err) } dpy.eventReady <- true } }() C.XFlush(dpy.dpy) awaitEvent <- true draw := false for { nextFrame := dpy.anims.NextFrame(draw) select { case <-dpy.eventReady: dpy.processXEvents(win) awaitEvent <- true case <-dpy.drawReady: draw = true case t := <-nextFrame: dpy.anims.Run() // log.Printf("draw %s", t) t = t cr := cairo.Create(win.bufSurface.Surface) win.delegate.Draw(cr) win.repaint(0, 0, win.width, win.height) C.XSync(dpy.dpy, 0) draw = false case f := <-dpy.funcs: f() case <-dpy.quit: return } } }
// Resize handles a resize of the window. func (win *Window) resize(w, h int) { if win.width == w && win.height == h { return } win.width, win.height = w, h if win.winSurface == nil { visual := C.XDefaultVisual(win.dpy.dpy, 0) win.winSurface = cairo.XlibSurfaceCreate( unsafe.Pointer(win.dpy.dpy), uint64(win.xw), unsafe.Pointer(visual), w, h) } else { win.winSurface.SetSize(w, h) } win.bufSurface = &cairo.XlibSurface{win.winSurface.CreateSimilar(cairo.ContentColor, w, h)} cr := cairo.Create(win.bufSurface.Surface) win.delegate.Draw(cr) win.repaint(0, 0, w, h) }