diff options
| -rw-r--r-- | prototypes/xgb-window.go | 133 | 
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() +		} +	} + +} | 
