summaryrefslogtreecommitdiff
path: root/drw/x.go
blob: 094b705b4a6668c4d2eae8bb58e12c01283fa0bd (plain)
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
113
114
115
package drw // import "hhvn.uk/hbspbar/drw"

import (
	"os"
	"image"

	"hhvn.uk/hbspbar/config"
	"hhvn.uk/hbspbar/common"

	"github.com/jezek/xgb"
	"github.com/jezek/xgb/xproto"
	"github.com/jezek/xgbutil"
	"github.com/jezek/xgbutil/icccm"
	"github.com/jezek/xgbutil/ewmh"
	"github.com/jezek/xgbutil/xgraphics"
	"github.com/BurntSushi/freetype-go/freetype/truetype"
)

type eventwrap struct {
	Ev  xgb.Event
	Err error
}

var InitErr error
var Events  chan *eventwrap

var xc      *xgb.Conn
var xu      *xgbutil.XUtil
var screen  *xproto.ScreenInfo
var font    *truetype.Font

func init() {
	var err error

	xc, err = xgb.NewConn()
	if err != nil {
		InitErr = err
		return
	}

	xu, err = xgbutil.NewConnXgb(xc)
	if err != nil {
		InitErr = err
		return
	}

	setup := xproto.Setup(xc)
	screen = setup.DefaultScreen(xc)

	read, err := os.Open(config.Font)
	if err != nil {
		InitErr = common.Perror("os.Open", err)
		return
	}

	font, err = xgraphics.ParseFont(read)
	if err != nil {
		InitErr = common.Perror("xgraphics.ParseFont", err)
		return
	}

	Events := make(chan *eventwrap)

	go func() { for {
		ev, err := xc.WaitForEvent()
		w := eventwrap{ev, err}
		Events <- &w
	}}()
}

type Window struct {
	id xproto.Window
}

func WindowCreate(x, y, w, h uint) (*Window, error) {
	var win Window
	var err error

	win.id, err = xproto.NewWindowId(xc)
	if err != nil {
		return nil, common.Perror("xproto.NewWindowId", err)
	}

	xproto.CreateWindow(xc, screen.RootDepth, win.id, screen.Root,
		int16(x), int16(y), uint16(w), uint16(h), 0,
		xproto.WindowClassInputOutput, screen.RootVisual,
		xproto.CwBackPixel|xproto.CwEventMask, []uint32{
			0x00000000,
			xproto.EventMaskStructureNotify })

	class := icccm.WmClass{"hbspbar", "hbspbar"}
	icccm.WmClassSet(xu, win.id, &class)

	ewmh.WmWindowTypeSet(xu, win.id, []string{"_NET_WM_WINDOW_TYPE_DOCK"})
	ewmh.WmStateSet(xu, win.id, []string{"_NET_WM_STATE_STICKY", "_NET_WM_STATE_ABOVE"})

	err = xproto.MapWindowChecked(xc, win.id).Check()
	if err != nil {
		return nil, common.Perror("xproto.MapWindow", err)
	}

	return &win, nil
}

func (w *Window) Paint(i image.Image) {
	xgr := xgraphics.NewConvert(xu, i)

	xgr.XSurfaceSet(w.id)
	xgr.XDraw()
	xgr.XPaint(w.id)
}

func (w *Window) Destroy() {
	xproto.DestroyWindow(xc, w.id)
}