132 lines
3.3 KiB
Go
132 lines
3.3 KiB
Go
//This demonstration shows drawing entire generated images to an x window
|
|
//and calculating the speed of the generation and the drawing operations
|
|
//It should be noted that redrawing the entire image is inefficient, this demo
|
|
//was made to show me how fast I could draw to the windows with this method.
|
|
package main
|
|
|
|
import (
|
|
"github.com/jezek/xgb/xproto"
|
|
"github.com/jezek/xgbutil"
|
|
"github.com/jezek/xgbutil/keybind"
|
|
"github.com/jezek/xgbutil/xevent"
|
|
"github.com/jezek/xgbutil/xgraphics"
|
|
"github.com/jezek/xgbutil/xwindow"
|
|
"image"
|
|
"log"
|
|
"time"
|
|
)
|
|
|
|
func main() {
|
|
X, err := xgbutil.NewConn()
|
|
if err != nil {
|
|
log.Println(err)
|
|
return
|
|
}
|
|
|
|
//Initialize the keybind package
|
|
keybind.Initialize(X)
|
|
|
|
//Create a window
|
|
win, err := xwindow.Generate(X)
|
|
if err != nil {
|
|
log.Fatalf("Could not generate a new window X id: %s", err)
|
|
}
|
|
win.Create(X.RootWin(), 0, 0, 1024, 768, xproto.CwBackPixel, 0x606060ff)
|
|
|
|
// Listen for Key{Press,Release} events.
|
|
win.Listen(xproto.EventMaskKeyPress, xproto.EventMaskKeyRelease)
|
|
|
|
// Map the window. This is what makes it on the screen
|
|
win.Map()
|
|
|
|
//Make a ...callback... for the events and connect
|
|
xevent.KeyPressFun(
|
|
func(X *xgbutil.XUtil, e xevent.KeyPressEvent) {
|
|
modStr := keybind.ModifierString(e.State)
|
|
keyStr := keybind.LookupString(X, e.State, e.Detail)
|
|
if len(modStr) > 0 {
|
|
log.Printf("Key: %s-%s\n", modStr, keyStr)
|
|
} else {
|
|
log.Println("Key:", keyStr)
|
|
}
|
|
|
|
if keybind.KeyMatch(X, "Escape", e.State, e.Detail) {
|
|
if e.State&xproto.ModMaskControl > 0 {
|
|
log.Println("Control-Escape detected. Quitting...")
|
|
xevent.Quit(X)
|
|
}
|
|
}
|
|
}).Connect(X, win.Id)
|
|
|
|
//So here i'm going to try to make a image..'
|
|
img := xgraphics.New(X, image.Rect(0, 0, 1024, 768))
|
|
|
|
err = img.XSurfaceSet(win.Id)
|
|
if err != nil {
|
|
log.Printf("Error while setting window surface to image %d: %s\n",
|
|
win, err)
|
|
} else {
|
|
log.Printf("Window %d surface set to image OK\n", win)
|
|
}
|
|
|
|
// I /think/ XDraw actually sends data to server?
|
|
img.XDraw()
|
|
// I /think/ XPaint tells the server to paint image to window
|
|
img.XPaint(win.Id)
|
|
|
|
//Start the routine that updates the window
|
|
go updater(img, win)
|
|
|
|
//This seems to start a main loop for listening to xevents
|
|
xevent.Main(X)
|
|
}
|
|
|
|
func updater(img *xgraphics.Image, win *xwindow.Window) {
|
|
//We keep track of times based on 1024 frames
|
|
frame := 0
|
|
start := time.Now()
|
|
var genStart, drawStart time.Time
|
|
var genTotal, drawTotal time.Duration
|
|
|
|
for {
|
|
frame = frame + 1
|
|
if frame > 1024 {
|
|
frame = 0
|
|
log.Printf("Time elapsed: %s\n", time.Now().Sub(start))
|
|
log.Printf("Time generate: %s\n", genTotal)
|
|
log.Printf("Time drawing: %s\n", drawTotal)
|
|
start = time.Now()
|
|
drawTotal, genTotal = 0, 0
|
|
}
|
|
|
|
genStart = time.Now()
|
|
var x, y, i int
|
|
for y = 0; y < 768; y++ {
|
|
//set last pixel back to black
|
|
img.SetBGRA(frame-1, y, xgraphics.BGRA{0, 0, 0, 255})
|
|
for i = 0; i < 10; i++ {
|
|
x = i + frame
|
|
if x > 1024 {
|
|
x = 1024
|
|
}
|
|
img.SetBGRA(x, y, xgraphics.BGRA{0, 0, 255, 255})
|
|
}
|
|
}
|
|
genTotal += time.Now().Sub(genStart)
|
|
|
|
drawStart = time.Now()
|
|
//hopefully using checked will block us from drawing again before x
|
|
//draws although XDraw might block anyway, we can check for an error
|
|
//here
|
|
err := img.XDrawChecked()
|
|
if err != nil {
|
|
log.Println(err)
|
|
return
|
|
}
|
|
//img.XDraw()
|
|
|
|
img.XPaint(win.Id)
|
|
drawTotal += time.Now().Sub(drawStart)
|
|
}
|
|
}
|