aboutsummaryrefslogtreecommitdiff
path: root/prototypes/xgb-window.go
diff options
context:
space:
mode:
authorPřemysl Janouch <p@janouch.name>2018-08-18 01:18:24 +0200
committerPřemysl Janouch <p@janouch.name>2018-09-02 18:24:14 +0200
commit1fdf14f351f274a5d6690985c854e12ab6e05fbc (patch)
treeccbaa0e212f5a6310cb65397aaeb879d97907bf3 /prototypes/xgb-window.go
parent0ef66c72828b202dcb25f3264e8ce2509f9f3411 (diff)
downloadhaven-1fdf14f351f274a5d6690985c854e12ab6e05fbc.tar.gz
haven-1fdf14f351f274a5d6690985c854e12ab6e05fbc.tar.xz
haven-1fdf14f351f274a5d6690985c854e12ab6e05fbc.zip
xgb-window: add a basic xgb demo
Demonstrating RGBA visuals and direct pixel values.
Diffstat (limited to 'prototypes/xgb-window.go')
-rw-r--r--prototypes/xgb-window.go133
1 files changed, 133 insertions, 0 deletions
diff --git a/prototypes/xgb-window.go b/prototypes/xgb-window.go
new file mode 100644
index 0000000..2519fe9
--- /dev/null
+++ b/prototypes/xgb-window.go
@@ -0,0 +1,133 @@
+package main
+
+import (
+ "github.com/BurntSushi/xgb"
+ "github.com/BurntSushi/xgb/xproto"
+ "log"
+ "math/rand"
+)
+
+func main() {
+ X, err := xgb.NewConn()
+ if err != nil {
+ log.Fatalln(err)
+ }
+
+ setup := xproto.Setup(X)
+ screen := setup.DefaultScreen(X)
+
+ var visual xproto.Visualid
+ var depth byte
+ for _, i := range screen.AllowedDepths {
+ if i.Depth == 32 {
+ // TODO: Could/should check other parameters.
+ for _, v := range i.Visuals {
+ if v.Class == xproto.VisualClassTrueColor {
+ visual = v.VisualId
+ depth = i.Depth
+ break
+ }
+ }
+ }
+ }
+ if visual == 0 {
+ log.Fatalln("cannot find an RGBA TrueColor visual")
+ }
+
+ mid, err := xproto.NewColormapId(X)
+ if err != nil {
+ log.Fatalln(err)
+ }
+
+ _ = xproto.CreateColormap(
+ X, xproto.ColormapAllocNone, mid, screen.Root, visual)
+
+ wid, err := xproto.NewWindowId(X)
+ if err != nil {
+ log.Fatalln(err)
+ }
+
+ // Border pixel and colormap are required when depth differs from parent.
+ _ = xproto.CreateWindow(X, depth, wid, screen.Root,
+ 0, 0, 500, 500, 0, xproto.WindowClassInputOutput,
+ visual, xproto.CwBorderPixel|xproto.CwColormap,
+ []uint32{0, uint32(mid)})
+
+ // This could be included in CreateWindow parameters.
+ _ = xproto.ChangeWindowAttributes(X, wid,
+ xproto.CwBackPixel|xproto.CwEventMask, []uint32{0x80808080,
+ xproto.EventMaskStructureNotify | xproto.EventMaskKeyPress |
+ xproto.EventMaskExposure})
+
+ title := "Gradient"
+ _ = xproto.ChangeProperty(X, xproto.PropModeReplace, wid, xproto.AtomWmName,
+ xproto.AtomString, 8, uint32(len(title)), []byte(title))
+
+ _ = xproto.MapWindow(X, wid)
+
+ cid, err := xproto.NewGcontextId(X)
+ if err != nil {
+ log.Fatalln(err)
+ }
+
+ _ = xproto.CreateGC(X, cid, xproto.Drawable(wid),
+ xproto.GcGraphicsExposures, []uint32{0})
+
+ var w, h uint16
+ var start, end uint32 = 0xabcdef, 0x32ab54
+ gradient := func() {
+ ra, ga, ba := (start>>16)&0xff, (start>>8)&0xff, start&0xff
+ rb, gb, bb := (end>>16)&0xff, (end>>8)&0xff, end&0xff
+
+ var low, high uint16 = 50, h - 50
+ if high > h {
+ return
+ }
+
+ for y := low; y < high; y++ {
+ ratio := float64(y-low) / (float64(high) - float64(low))
+ iratio := 1 - ratio
+
+ rR := uint32(ratio*float64(ra)+iratio*float64(rb)) & 0xff
+ gG := uint32(ratio*float64(ga)+iratio*float64(gb)) & 0xff
+ bB := uint32(ratio*float64(ba)+iratio*float64(bb)) & 0xff
+
+ _ = xproto.ChangeGC(X, cid, xproto.GcForeground,
+ []uint32{0xff000000 | rR<<16 | gG<<8 | bB})
+ _ = xproto.PolyLine(X, xproto.CoordModeOrigin, xproto.Drawable(wid),
+ cid, []xproto.Point{
+ {X: 50, Y: int16(y)},
+ {X: int16(w - 50), Y: int16(y)},
+ })
+ }
+ }
+
+ for {
+ ev, xerr := X.WaitForEvent()
+ if xerr != nil {
+ log.Printf("Error: %s\n", xerr)
+ return
+ }
+ if ev == nil {
+ return
+ }
+
+ log.Printf("Event: %s\n", ev)
+ switch e := ev.(type) {
+ case xproto.UnmapNotifyEvent:
+ return
+
+ case xproto.ConfigureNotifyEvent:
+ w, h = e.Width, e.Height
+
+ case xproto.KeyPressEvent:
+ start = rand.Uint32() & 0xffffff
+ end = rand.Uint32() & 0xffffff
+ gradient()
+
+ case xproto.ExposeEvent:
+ gradient()
+ }
+ }
+
+}