xgb: github.com/BurntSushi/xgb Index | Files | Directories

package xgb

import "github.com/BurntSushi/xgb"

Package XGB 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 XGB. 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 XGB typically fall under the realm of window manager and GUI kit development, but other applications (like pagers, panels, tilers, etc.) may also require XGB. Moreover, it is a near certainty that if you need to work with X, xgbutil will be of great use to you as well: https://github.com/BurntSushi/xgbutil

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"
	"github.com/BurntSushi/xgb"
	"github.com/BurntSushi/xgb/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"
	"github.com/BurntSushi/xgb"
	"github.com/BurntSushi/xgb/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

XGB 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 XGB 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. XGB (before this 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.

Index

Package Files

auth.go conn.go cookie.go doc.go help.go sync.go xgb.go

Variables

var (
    // Where to log error-messages. Defaults to stderr.
    // To disable logging, just set this to log.New(ioutil.Discard, "", 0)
    Logger = log.New(os.Stderr, "XGB: ", log.Lshortfile)

    // ExtLock is a lock used whenever new extensions are initialized.
    // It should not be used. It is exported for use in the extension
    // sub-packages.
    ExtLock sync.Mutex
)
var NewErrorFuncs = make(map[int]NewErrorFun)

NewErrorFuncs is a map from error numbers to functions that create the corresponding error. It should not be used. It is exported for use in the extension sub-packages.

var NewEventFuncs = make(map[int]NewEventFun)

NewEventFuncs is a map from event numbers to functions that create the corresponding event. It should not be used. It is exported for use in the extension sub-packages.

var NewExtErrorFuncs = make(map[string]map[int]NewErrorFun)

NewExtErrorFuncs is a temporary map that stores error constructor functions for each extension. When an extension is initialized, each error for that extension is added to the 'NewErrorFuncs' map. It should not be used. It is exported for use in the extension sub-packages.

var NewExtEventFuncs = make(map[string]map[int]NewEventFun)

NewExtEventFuncs is a temporary map that stores event constructor functions for each extension. When an extension is initialized, each event for that extension is added to the 'NewEventFuncs' map. It should not be used. It is exported for use in the extension sub-packages.

func Errorf

func Errorf(format string, v ...interface{}) error

Errorf is just a wrapper for fmt.Errorf. Exists for the same reason that 'stringsJoin' and 'sprintf' exists.

func Get16

func Get16(buf []byte) uint16

Get16 constructs a 16 bit integer from the beginning of a byte slice.

func Get32

func Get32(buf []byte) uint32

Get32 constructs a 32 bit integer from the beginning of a byte slice.

func Get64

func Get64(buf []byte) uint64

Get64 constructs a 64 bit integer from the beginning of a byte slice.

func Pad

func Pad(n int) int

Pad a length to align on 4 bytes.

func PopCount

func PopCount(mask0 int) int

PopCount counts the number of bits set in a value list mask.

func Put16

func Put16(buf []byte, v uint16)

Put16 takes a 16 bit integer and copies it into a byte slice.

func Put32

func Put32(buf []byte, v uint32)

Put32 takes a 32 bit integer and copies it into a byte slice.

func Put64

func Put64(buf []byte, v uint64)

Put64 takes a 64 bit integer and copies it into a byte slice.

func Sprintf

func Sprintf(format string, v ...interface{}) string

Sprintf is so we don't need to import 'fmt' in the generated Go files.

func StringsJoin

func StringsJoin(ss []string, sep string) string

StringsJoin is an alias to strings.Join. It allows us to avoid having to import 'strings' in each of the generated Go files.

type Conn

type Conn struct {
    DisplayNumber int
    DefaultScreen int
    SetupBytes    []byte

    // Extensions is a map from extension name to major opcode. It should
    // not be used. It is exported for use in the extension sub-packages.
    Extensions map[string]byte
    // contains filtered or unexported fields
}

A Conn represents a connection to an X server.

func NewConn

func NewConn() (*Conn, error)

NewConn creates a new connection instance. It initializes locks, data structures, and performs the initial handshake. (The code for the handshake has been relegated to conn.go.)

func NewConnDisplay

func NewConnDisplay(display string) (*Conn, error)

NewConnDisplay is just like NewConn, but allows a specific DISPLAY string to be used. If 'display' is empty it will be taken from os.Getenv("DISPLAY").

Examples:

NewConn(":1") -> net.Dial("unix", "", "/tmp/.X11-unix/X1")
NewConn("/tmp/launch-12/:0") -> net.Dial("unix", "", "/tmp/launch-12/:0")
NewConn("hostname:2.1") -> net.Dial("tcp", "", "hostname:6002")
NewConn("tcp/hostname:1.0") -> net.Dial("tcp", "", "hostname:6001")

func (*Conn) Close

func (c *Conn) Close()

Close gracefully closes the connection to the X server.

func (*Conn) NewCookie

func (c *Conn) NewCookie(checked, reply bool) *Cookie

NewCookie creates a new cookie with the correct channels initialized depending upon the values of 'checked' and 'reply'. Together, there are four different kinds of cookies. (See more detailed comments in the function for more info on those.) Note that a sequence number is not set until just before the request corresponding to this cookie is sent over the wire.

Unless you're building requests from bytes by hand, this method should not be used.

func (*Conn) NewId

func (c *Conn) NewId() (uint32, error)

NewId generates a new unused ID for use with requests like CreateWindow. If no new ids can be generated, the id returned is 0 and error is non-nil. This shouldn't be used directly, and is exported for use in the extension sub-packages. If you need identifiers, use the appropriate constructor. e.g., For a window id, use xproto.NewWindowId. For a new pixmap id, use xproto.NewPixmapId. And so on.

func (*Conn) NewRequest

func (c *Conn) NewRequest(buf []byte, cookie *Cookie)

NewRequest takes the bytes and a cookie of a particular request, constructs a request type, and sends it over the Conn.reqChan channel. Note that the sequence number is added to the cookie after it is sent over the request channel, but before it is sent to X.

Note that you may safely use NewRequest to send arbitrary byte requests to X. The resulting cookie can be used just like any normal cookie and abides by the same rules, except that for replies, you'll get back the raw byte data. This may be useful for performance critical sections where every allocation counts, since all X requests in XGB allocate a new byte slice. In contrast, NewRequest allocates one small request struct and nothing else. (Except when the cookie buffer is full and has to be flushed.)

If you're using NewRequest manually, you'll need to use NewCookie to create a new cookie.

In all likelihood, you should be able to copy and paste with some minor edits the generated code for the request you want to issue.

func (*Conn) PollForEvent

func (c *Conn) PollForEvent() (Event, Error)

PollForEvent returns the next event from the server if one is available in the internal queue without blocking. Note that unlike WaitForEvent, both Event and Error could be nil. Indeed, they are both nil when the event queue is empty.

func (*Conn) Sync

func (c *Conn) Sync()

Sync sends a round trip request and waits for the response. This forces all pending cookies to be dealt with. You actually shouldn't need to use this like you might with Xlib. Namely, buffers are automatically flushed using Go's channels and round trip requests are forced where appropriate automatically.

func (*Conn) WaitForEvent

func (c *Conn) WaitForEvent() (Event, Error)

WaitForEvent returns the next event from the server. It will block until an event is available. WaitForEvent returns either an Event or an Error. (Returning neither or both is a bug.) Note than an Error here is an X error and not an XGB error. That is, X errors are sometimes completely expected (and you may want to ignore them in some cases).

type Cookie struct {
    Sequence uint16
    // contains filtered or unexported fields
}

Cookie is the internal representation of a cookie, where one is generated for *every* request sent by XGB. 'cookie' is most frequently used by embedding it into a more specific kind of cookie, i.e., 'GetInputFocusCookie'.

func (Cookie) Check

func (c Cookie) Check() error

Check is used for checked requests that have no replies. It is a mechanism by which to report "success" or "error" in a synchronous fashion. (Therefore, unchecked requests without replies cannot use this method.) If the request causes an error, it is sent to this cookie's errorChan. If the request was successful, there is no response from the server. Thus, pingChan is sent a value when the *next* reply is read. If no more replies are being processed, we force a round trip request with GetInputFocus.

Unless you're building requests from bytes by hand, this method should not be used.

func (Cookie) Reply

func (c Cookie) Reply() ([]byte, error)

Reply detects whether this is a checked or unchecked cookie, and calls 'replyChecked' or 'replyUnchecked' appropriately.

Unless you're building requests from bytes by hand, this method should not be used.

type Error

type Error interface {
    SequenceId() uint16
    BadId() uint32
    Error() string
}

Error is an interface that can contain any of the errors returned by the server. Use a type assertion switch to extract the Error structs.

type Event

type Event interface {
    Bytes() []byte
    String() string
}

Event is an interface that can contain any of the events returned by the server. Use a type assertion switch to extract the Event structs.

type NewErrorFun

type NewErrorFun func(buf []byte) Error

NewErrorFun is the type of function use to construct errors from raw bytes. It should not be used. It is exported for use in the extension sub-packages.

type NewEventFun

type NewEventFun func(buf []byte) Event

NewEventFun is the type of function use to construct events from raw bytes. It should not be used. It is exported for use in the extension sub-packages.

Directories

PathSynopsis
bigreqPackage bigreq is the X client API for the BIG-REQUESTS extension.
compositePackage composite is the X client API for the Composite extension.
damagePackage damage is the X client API for the DAMAGE extension.
dpmsPackage dpms is the X client API for the DPMS extension.
dri2Package dri2 is the X client API for the DRI2 extension.
examples/atoms
examples/create-windowExample create-window shows how to create a window, map it, resize it, and listen to structure and key events (i.e., when the window is resized by the window manager, or when key presses/releases are made when the window has focus).
examples/get-active-windowExample get-active-window reads the _NET_ACTIVE_WINDOW property of the root window and uses the result (a window id) to get the name of the window.
examples/randrExample randr uses the randr protocol to get information about the active heads.
examples/xineramaExample xinerama shows how to query the geometry of all active heads.
gePackage ge is the X client API for the Generic Event Extension extension.
glxPackage glx is the X client API for the GLX extension.
randrPackage randr is the X client API for the RANDR extension.
recordPackage record is the X client API for the RECORD extension.
renderPackage render is the X client API for the RENDER extension.
resPackage res is the X client API for the X-Resource extension.
screensaverPackage screensaver is the X client API for the MIT-SCREEN-SAVER extension.
shapePackage shape is the X client API for the SHAPE extension.
shmPackage shm is the X client API for the MIT-SHM extension.
xcmiscPackage xcmisc is the X client API for the XC-MISC extension.
xeviePackage xevie is the X client API for the XEVIE extension.
xf86driPackage xf86dri is the X client API for the XFree86-DRI extension.
xf86vidmodePackage xf86vidmode is the X client API for the XFree86-VidModeExtension extension.
xfixesPackage xfixes is the X client API for the XFIXES extension.
xgbgenxgbgen constructs Go source files from xproto XML description files.
xineramaPackage xinerama is the X client API for the XINERAMA extension.
xprintPackage xprint is the X client API for the XpExtension extension.
xprotoPackage xproto is the X client API for the extension.
xselinuxPackage xselinux is the X client API for the SELinux extension.
xtestPackage xtest is the X client API for the XTEST extension.
xvPackage xv is the X client API for the XVideo extension.
xvmcPackage xvmc is the X client API for the XVideo-MotionCompensation extension.

Package xgb imports 10 packages (graph) and is imported by 59 packages. Updated 2014-05-11. Refresh now. Tools for package owners.