aboutsummaryrefslogtreecommitdiff
path: root/nexgb/doc.go
blob: 90f3ceae035b91f1efe94f76a674abd51b2ab12e (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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
Package nexgb provides the X Go Binding, which is a low-level API to communicate
with the core X protocol and many of the X extensions.

It is *very* closely modeled on XCB, so that experience with XCB (or xpyb) is
easily translatable to neXGB. That is, it uses the same cookie/reply model
and is thread safe. There are otherwise no major differences (in the API).

Most uses of neXGB typically fall under the realm of window manager and GUI kit
development, but other applications (like pagers, panels, tilers, etc.) may
also require neXGB.

Example

This is an extremely terse example that demonstrates how to connect to X,
create a window, listen to StructureNotify events and Key{Press,Release}
events, map the window, and print out all events received. An example with
accompanying documentation can be found in examples/create-window.

	package main

	import (
		"fmt"
		xgb "janouch.name/haven/nexgb"
		"janouch.name/haven/nexgb/xproto"
	)

	func main() {
		X, err := xgb.NewConn()
		if err != nil {
			fmt.Println(err)
			return
		}

		wid, _ := xproto.NewWindowId(X)
		screen := xproto.Setup(X).DefaultScreen(X)
		xproto.CreateWindow(X, screen.RootDepth, wid, screen.Root,
			0, 0, 500, 500, 0,
			xproto.WindowClassInputOutput, screen.RootVisual,
			xproto.CwBackPixel | xproto.CwEventMask,
			[]uint32{ // values must be in the order defined by the protocol
				0xffffffff,
				xproto.EventMaskStructureNotify |
				xproto.EventMaskKeyPress |
				xproto.EventMaskKeyRelease})

		xproto.MapWindow(X, wid)
		for {
			ev, xerr := X.WaitForEvent()
			if ev == nil && xerr == nil {
				fmt.Println("Both event and error are nil. Exiting...")
				return
			}

			if ev != nil {
				fmt.Printf("Event: %s\n", ev)
			}
			if xerr != nil {
				fmt.Printf("Error: %s\n", xerr)
			}
		}
	}

Xinerama Example

This is another small example that shows how to query Xinerama for geometry
information of each active head. Accompanying documentation for this example
can be found in examples/xinerama.

	package main

	import (
		"fmt"
		"log"
		xgb "janouch.name/haven/nexgb"
		"janouch.name/haven/nexgb/xinerama"
	)

	func main() {
		X, err := xgb.NewConn()
		if err != nil {
			log.Fatal(err)
		}

		// Initialize the Xinerama extension.
		// The appropriate 'Init' function must be run for *every*
		// extension before any of its requests can be used.
		err = xinerama.Init(X)
		if err != nil {
			log.Fatal(err)
		}

		reply, err := xinerama.QueryScreens(X).Reply()
		if err != nil {
			log.Fatal(err)
		}

		fmt.Printf("Number of heads: %d\n", reply.Number)
		for i, screen := range reply.ScreenInfo {
			fmt.Printf("%d :: X: %d, Y: %d, Width: %d, Height: %d\n",
				i, screen.XOrg, screen.YOrg, screen.Width, screen.Height)
		}
	}

Parallelism

neXGB can benefit greatly from parallelism due to its concurrent design. For
evidence of this claim, please see the benchmarks in xproto/xproto_test.go.

Tests

xproto/xproto_test.go contains a number of contrived tests that stress
particular corners of neXGB that I presume could be problem areas. Namely:
requests with no replies, requests with replies, checked errors, unchecked
errors, sequence number wrapping, cookie buffer flushing (i.e., forcing a round
trip every N requests made that don't have a reply), getting/setting properties
and creating a window and listening to StructureNotify events.

Code Generator

Both XCB and xpyb use the same Python module (xcbgen) for a code generator.
neXGB (before BurntSushi's fork) used the same code generator as well, but in my
attempt to add support for more extensions, I found the code generator extremely
difficult to work with. Therefore, I re-wrote the code generator in Go. It can
be found in its own sub-package, xgbgen, of xgb. My design of xgbgen includes a
rough consideration that it could be used for other languages.

What works

I am reasonably confident that the core X protocol is in full working form. I've
also tested the Xinerama and RandR extensions sparingly. Many of the other
existing extensions have Go source generated (and are compilable) and are
included in this package, but I am currently unsure of their status. They
*should* work.

What does not work

XKB is the only extension that intentionally does not work, although I suspect
that GLX also does not work (however, there is Go source code for GLX that
compiles, unlike XKB). I don't currently have any intention of getting XKB
working, due to its complexity and my current mental incapacity to test it.

*/
package nexgb