x11

package
v0.19.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 11, 2026 License: BSD-3-Clause Imports: 11 Imported by: 0

Documentation

Overview

Package x11 is a from-scratch, pure-Go (CGO-free, zero non-stdlib dependency) implementation of the X Window System core protocol, version 11.0, spoken directly over a byte stream (a unix-domain socket in practice).

It mirrors the sovereign transport+codec approach of github.com/go-freedesktop/dbus: no Xlib, no XCB, no cgo — the wire format is encoded and decoded here, byte for byte, per the X11 protocol specification.

The package is deliberately transport-agnostic. A Conn wraps any io.ReadWriteCloser, so the whole request/reply/error/event machine is exercisable in-process over a net.Pipe against a scripted fake server, which is how the suite reaches full coverage on every platform without a running X server.

Index

Constants

View Source
const (
	ModShift   = 0x0001
	ModLock    = 0x0002
	ModControl = 0x0004
	ModMod1    = 0x0008 // typically Alt
	ModMod4    = 0x0040 // typically Super / the Meta (⌘/Windows/logo) key
	ModButton1 = 0x0100
	ModButton2 = 0x0200
	ModButton3 = 0x0400
)

Modifier / button state-mask bits carried in pointer and key events.

View Source
const (
	Button1         = 1 // left
	Button2         = 2 // middle
	Button3         = 3 // right
	ButtonWheelUp   = 4
	ButtonWheelDown = 5
)

Pointer button numbers as reported in a Button event's detail byte.

View Source
const (
	EventMaskKeyPress         = 0x00000001
	EventMaskKeyRelease       = 0x00000002
	EventMaskButtonPress      = 0x00000004
	EventMaskButtonRelease    = 0x00000008
	EventMaskPointerMotion    = 0x00000040
	EventMaskButton1Motion    = 0x00000100
	EventMaskExposure         = 0x00008000
	EventMaskStructureNotify  = 0x00020000
	EventMaskButtonMotionMask = 0x00002000
)

Event-mask bits selected on our window. These are the events the host loop translates into toolkit events plus the structure/exposure notifies needed to drive relayout and repaint.

View Source
const (
	AtomNone      = 0
	AtomPrimary   = 1
	AtomAtom      = 4
	AtomCardinal  = 6
	AtomString    = 31
	AtomWMName    = 39
	AtomWMClass   = 67
	AtomWMHints   = 35
	AtomWMIconNm  = 37
	AtomWMNormalH = 40
)

Predefined atoms (X11/Xatom.h). Interned atoms (WM_PROTOCOLS, WM_DELETE_WINDOW) are obtained at runtime via InternAtom.

View Source
const (
	VisualStaticGray  = 0
	VisualGrayScale   = 1
	VisualStaticColor = 2
	VisualPseudoColor = 3
	VisualTrueColor   = 4
	VisualDirectColor = 5
)

TrueColor and DirectColor are the visual classes whose pixels are directly RGB-decomposable via the masks (no palette lookup).

View Source
const CopyFromParent = 0

CopyFromParent (0) is used for a CreateWindow depth/visual/border so the new window inherits the root's TrueColor visual with no BadMatch risk.

View Source
const CurrentTime = 0

CurrentTime asks the server to substitute its own clock, which is what a selection request should use when it has no user event to point at.

DefaultEventMask is the mask CreateWindow selects for the host window.

Variables

This section is empty.

Functions

func IsModifier

func IsModifier(ks uint32) bool

IsModifier reports whether ks is a Shift/Control/Alt modifier keysym, which the host tracks for Event.Ctrl/Event.Shift but does not deliver as a character.

func KeysymName

func KeysymName(ks uint32) string

KeysymName returns the toolkit key name for a keysym, or "" when the keysym has no named binding (it is either printable — see KeysymRune — or unhandled).

func KeysymRune

func KeysymRune(ks uint32) (rune, bool)

KeysymRune returns the printable rune a keysym produces and whether it is printable. Latin-1 keysyms (0x20–0xff) are their own codepoint; the 0x01000000-flagged range carries a direct Unicode codepoint. The space key is treated as a named key (KeysymName == "Space"), not a rune, so it is excluded here.

func LoadAuthCookie

func LoadAuthCookie(authFile, host, display string) (name string, data []byte, err error)

LoadAuthCookie resolves the MIT-MAGIC-COOKIE-1 for (host, display) from the given authority file. A missing file (or no match) is not an error: it returns empty name/data so the caller falls back to an unauthenticated setup, exactly as Xlib does. host defaults to the machine hostname when empty.

func WrapUnix added in v0.3.0

func WrapUnix(c *net.UnixConn) io.ReadWriteCloser

WrapUnix wraps a dialed *net.UnixConn as an fd-passing transport for Handshake. A connection built over it reports SupportsFDPassing() == true.

Types

type AuthEntry

type AuthEntry struct {
	Family  uint16
	Address []byte
	Number  string // display number as ASCII, "" is a wildcard
	Name    string // authorization protocol name
	Data    []byte // the cookie
}

AuthEntry is one record parsed from an Xauthority file.

type ByteOrder

type ByteOrder = binary.ByteOrder

ByteOrder is the wire byte order negotiated at connection setup. X11 lets the client pick; the server then speaks the client's order for the whole session.

type Conn

type Conn struct {
	// contains filtered or unexported fields
}

Conn is a connection to an X11 server speaking the core protocol over an arbitrary byte stream. It is transport-agnostic: NewConn wraps any io.ReadWriteCloser (a dialed unix socket in production, one half of a net.Pipe in tests) after the setup handshake has completed.

func Handshake

func Handshake(rw io.ReadWriteCloser, order ByteOrder, authName string, authData []byte) (*Conn, error)

Handshake runs the client connection setup over rw: it sends the byte-order sentinel, protocol 11.0 and the authorization name+data, then parses the reply. On success it returns a ready Conn. order selects the wire byte order (little- or big-endian); both are valid and the server adopts the client's choice.

func (*Conn) ChangeProperty

func (c *Conn) ChangeProperty(window, property, typ uint32, format byte, count int, data []byte) error

ChangeProperty replaces property on window with data of the given type and format (8, 16 or 32 bits per element). count is the number of elements; data must already be laid out in the wire order.

func (*Conn) Close

func (c *Conn) Close() error

Close closes the underlying transport.

func (*Conn) ConvertSelection added in v0.19.0

func (c *Conn) ConvertSelection(requestor, selection, target, property, time uint32) error

ConvertSelection asks the current owner to write selection, converted to target, into property on requestor. The answer does not come back here: the owner replies with a SelectionNotify event, and the data is read from the property afterwards.

func (*Conn) CreateGC

func (c *Conn) CreateGC(gc, drawable uint32) error

CreateGC creates a graphics context on drawable with default values.

func (*Conn) CreateWindow

func (c *Conn) CreateWindow(wid, parent uint32, x, y int16, w, h uint16, backPixel, borderPixel, eventMask uint32) error

CreateWindow creates an InputOutput child of parent that inherits the parent's (root's) TrueColor visual and depth via CopyFromParent, setting only the background pixel, border pixel and event mask. Inheriting the visual sidesteps the BadMatch a differing-visual/colormap window would raise, while still landing on the screen's TrueColor root visual.

func (*Conn) FetchKeymap

func (c *Conn) FetchKeymap() (*Keymap, error)

FetchKeymap fetches the full keyboard mapping for the server's advertised keycode range.

func (*Conn) GetKeyboardMapping

func (c *Conn) GetKeyboardMapping(first, count uint8) (*Keymap, error)

GetKeyboardMapping fetches the keysym table for keycodes [first, first+count).

func (*Conn) GetProperty added in v0.19.0

func (c *Conn) GetProperty(window, property, typ uint32, del bool, maxWords uint32) (retTyp uint32, format byte, data []byte, err error)

GetProperty reads up to maxWords 32-bit words of a property, optionally deleting it. It returns the property's type (0 when the property does not exist), its format in bits, and the raw bytes.

Deleting on read is what the requestor side wants: the property is a mailbox the owner wrote into, and leaving it behind would make the next paste read a stale answer if the owner failed to reply.

func (*Conn) GetSelectionOwner added in v0.19.0

func (c *Conn) GetSelectionOwner(selection uint32) (uint32, error)

GetSelectionOwner returns the window currently owning selection, or 0 when nobody does — which is the normal state of a fresh session, not an error.

func (*Conn) InternAtom

func (c *Conn) InternAtom(name string, onlyIfExists bool) (uint32, error)

InternAtom resolves (or, when onlyIfExists is false, creates) an atom by name and returns its id.

func (*Conn) MapWindow

func (c *Conn) MapWindow(wid uint32) error

MapWindow makes the window visible.

func (*Conn) NewID

func (c *Conn) NewID() uint32

NewID allocates a fresh resource identifier from the server-granted range (base | (n & mask)).

func (*Conn) NextEvent

func (c *Conn) NextEvent() (Event, error)

NextEvent returns the next input/notify event, blocking on the transport until one arrives. Buffered events (queued during a roundTrip) drain first. Error packets encountered on the stream are returned as *XError.

func (*Conn) Order

func (c *Conn) Order() ByteOrder

Order returns the negotiated wire byte order.

func (*Conn) PutImage

func (c *Conn) PutImage(p *Presenter, drawable, gc uint32, src []byte, srcStride, sx, sy, w, h, dstX, dstY int) error

PutImage blits the w×h rectangle at (sx, sy) of the RGBA source buffer onto drawable at (dstX, dstY) via one or more ZPixmap PutImage requests, each kept under the server's maximum request length by horizontal banding.

func (*Conn) QueryExtension added in v0.3.0

func (c *Conn) QueryExtension(name string) (present bool, major, firstEvent, firstError byte, err error)

QueryExtension resolves an extension by name, returning whether the server implements it and, if so, its major opcode plus its first event and error codes. It is the standard gate before using any extension's requests.

func (*Conn) QueryShm added in v0.3.0

func (c *Conn) QueryShm() (*Shm, error)

QueryShm queries the MIT-SHM extension and its version. It returns (nil, nil) — no error — when the server does not implement the extension, so the caller simply falls back to PutImage. FDCapable additionally requires the connection's transport to support descriptor passing.

func (*Conn) SendSelectionNotify added in v0.19.0

func (c *Conn) SendSelectionNotify(requestor, selection, target, property, time uint32) error

SendSelectionNotify answers a SelectionRequest. property is the one the requestor named once the data has been written there, or 0 to refuse — which is the correct answer for a target we cannot produce, and much better than silence, since a requestor with no reply can only wait.

func (*Conn) Seq

func (c *Conn) Seq() uint16

Seq returns the sequence number of the most recently sent request.

func (*Conn) SetSelectionOwner added in v0.19.0

func (c *Conn) SetSelectionOwner(owner, selection, time uint32) error

SetSelectionOwner claims (owner non-zero) or releases (owner zero) a selection. The server sends the previous owner a SelectionClear.

Claiming is not the same as having copied: nothing is transferred here. The owner has to stay alive and answer SelectionRequest events for as long as the text is meant to remain pasteable.

func (*Conn) SetWMClass

func (c *Conn) SetWMClass(window uint32, instance, class string) error

SetWMClass sets WM_CLASS to the two NUL-separated (and NUL-terminated) instance/class strings.

func (*Conn) SetWMName

func (c *Conn) SetWMName(window uint32, name string) error

SetWMName sets the window's WM_NAME (an ISO-8859-1 STRING property).

func (*Conn) SetWMProtocols

func (c *Conn) SetWMProtocols(window, wmProtocols uint32, atoms ...uint32) error

SetWMProtocols sets WM_PROTOCOLS to the given atom list (format 32).

func (*Conn) Setup

func (c *Conn) Setup() *Setup

Setup returns the parsed server setup.

func (*Conn) SupportsFDPassing added in v0.3.0

func (c *Conn) SupportsFDPassing() bool

SupportsFDPassing reports whether the connection's transport can pass a file descriptor to the server (required for MIT-SHM AttachFd).

type Depth

type Depth struct {
	Depth   uint8
	Visuals []VisualType
}

Depth groups the visuals available at a given colour depth.

type Event

type Event struct {
	Code   byte   // event type with the SendEvent bit stripped
	Synth  bool   // set if the SendEvent bit was present
	Detail byte   // keycode (key events) or button number (button events)
	Seq    uint16 // low 16 bits of the sequence number
	Time   uint32
	Window uint32 // event window
	RootX  int16
	RootY  int16
	EventX int16
	EventY int16
	State  uint16 // modifier + button mask
	X      int16  // Expose/ConfigureNotify origin
	Y      int16
	Width  uint16 // Expose/ConfigureNotify extent
	Height uint16
	Count  uint16 // Expose: remaining rectangles
	Atom   uint32 // ClientMessage: message type
	Format byte   // ClientMessage: data format
	Data32 uint32 // ClientMessage: first 32-bit data word (WM_DELETE_WINDOW)

	// Selection events. Requestor is the window asking (SelectionRequest) or
	// asked (SelectionNotify); Property is the one to write the answer into, or
	// 0 in a SelectionNotify that refuses.
	Requestor uint32
	Selection uint32
	Target    uint32
	Property  uint32
}

Event is a decoded X11 event in a flat, protocol-level form. The host layer maps it to a toolkit.Event; keeping this struct free of toolkit types lets the whole decoder be unit-tested with no UI dependency.

type FDSender added in v0.3.0

type FDSender interface {
	// SendFD writes one already-framed request with fd attached as a single
	// SCM_RIGHTS control message.
	SendFD(msg []byte, fd int) error
}

FDSender is implemented by a transport that can pass a file descriptor alongside a request over the same socket (a UNIX-domain stream, via SCM_RIGHTS). The production connection's transport (see WrapUnix) implements it; the in-process net.Pipe transport used by most tests does not, so the MIT-SHM fd-passing path degrades to plain PutImage when it is absent. The method is exported so an alternative transport (a measurement or test harness) can provide it too.

type Format

type Format struct {
	Depth       uint8
	BitsPerPix  uint8
	ScanlinePad uint8
}

Format is one entry of the server's pixmap-format list: for a given colour depth it fixes the bits-per-pixel and scanline padding a ZPixmap image of that depth must use on the wire.

type Keymap

type Keymap struct {
	Min     uint8
	PerCode int
	Syms    []uint32
}

Keymap holds a decoded GetKeyboardMapping reply: for each keycode in [Min, Min+len/PerCode) a run of PerCode keysyms, level 0 being the unshifted symbol and level 1 the shifted one.

func (*Keymap) Keysym

func (k *Keymap) Keysym(keycode uint8, shift bool) uint32

Keysym returns the keysym bound to keycode at the given shift level (false = level 0, true = level 1). A level-1 lookup that resolves to NoSymbol (0) falls back to level 0, matching the core-protocol rule that an absent shifted symbol repeats the unshifted one. Out-of-range keycodes yield 0.

type Presenter

type Presenter struct {
	// contains filtered or unexported fields
}

Presenter converts a toolkit RGBA framebuffer (R,G,B,A byte order) into the exact ZPixmap wire bytes a given visual + pixmap-format expect, and tiles PutImage requests so none exceeds the server's maximum request length.

Pixel bytes are laid out per the server's image-byte-order (independent of the protocol byte order): each pixel value is assembled from the RGB channels via the visual's masks, then serialised LSB- or MSB-first in bpp/8 bytes.

func NewPresenter

func NewPresenter(setup *Setup, vis VisualType, depth uint8) (*Presenter, error)

NewPresenter derives the pixel-packing parameters for depth from the screen's visual and the server setup.

func (*Presenter) BytesPerPixel

func (p *Presenter) BytesPerPixel() int

BytesPerPixel is the on-the-wire size of one pixel.

func (*Presenter) EncodeRectInto added in v0.3.0

func (p *Presenter) EncodeRectInto(seg []byte, totalW int, src []byte, srcStride, sx, sy, w, h int) error

EncodeRectInto packs the rectangle (sx, sy, w, h) of an RGBA source buffer (srcStride bytes per row) into seg — a shared segment laid out as a totalW-wide ZPixmap image for this visual — at the matching position, so seg mirrors the framebuffer and ShmPutImage can blit any sub-rectangle of it. seg must hold at least SegmentSize(totalW, sy+h) bytes.

func (*Presenter) SegmentSize added in v0.3.0

func (p *Presenter) SegmentSize(w, h int) int

SegmentSize is the byte size a w×h ZPixmap image occupies in a shared segment for this visual (padded scanlines).

type Screen

type Screen struct {
	Root          uint32
	DefaultColmap uint32
	WhitePixel    uint32
	BlackPixel    uint32
	Width         uint16
	Height        uint16
	RootVisual    uint32
	RootDepth     uint8
	Depths        []Depth
}

Screen is one root screen: its root window, default colormap, root visual and the allowed depths (each carrying its visuals).

func (*Screen) FindVisual

func (sc *Screen) FindVisual(id uint32) (VisualType, bool)

FindVisual returns the VisualType with the given id on screen sc, and whether it was found.

func (*Screen) RootVisualType

func (sc *Screen) RootVisualType() VisualType

RootVisualType returns the screen's root visual descriptor, falling back to a synthesized 24-bit TrueColor BGRX visual if the root visual id is somehow absent from the depth list (defensive; real servers always list it).

type Segment added in v0.3.0

type Segment struct {
	Seg  uint32
	FD   int
	Data []byte
	// contains filtered or unexported fields
}

Segment is an mmap'd anonymous shared-memory region backing a MIT-SHM attachment: Data is the client-writable pixel store, FD is handed to the X server over SCM_RIGHTS by Shm.AttachFd, and Seg is the resource id the server knows it by.

The segment struct and its lifecycle are transport-agnostic; the actual shared-memory syscalls (anonymous file, mmap/munmap, close) live behind the mmapRegion/munmapRegion/closeFD indirection and createAnonFile, which are provided per-platform (syscalls_linux.go / syscalls_other.go). Off Linux there is no X server to attach to, so createAnonFile returns ErrUnsupported and no segment is ever created.

func NewSegment added in v0.3.0

func NewSegment(seg uint32, size int) (*Segment, error)

NewSegment allocates and maps a shared-memory segment of size bytes and assigns it the resource id seg. The caller registers it with the server via Shm.AttachFd and frees it with (*Segment).Close.

func (*Segment) Close added in v0.3.0

func (s *Segment) Close() error

Close unmaps the region and closes its descriptor, returning the first error (both steps are attempted regardless).

func (*Segment) Size added in v0.3.0

func (s *Segment) Size() int

Size returns the segment's byte length.

type Setup

type Setup struct {
	Release        uint32
	ResourceIDBase uint32
	ResourceIDMask uint32
	Vendor         string
	MaxRequestLen  uint16 // in 4-byte units
	ImageByteOrder uint8  // 0 = LSBFirst, 1 = MSBFirst
	BitmapBitOrder uint8
	BitmapUnit     uint8
	BitmapPad      uint8
	MinKeycode     uint8
	MaxKeycode     uint8
	Formats        []Format
	Screens        []Screen
}

Setup is the parsed server connection-setup reply: everything the client needs to allocate resource IDs, pick a visual, size images correctly and map keycodes.

func (*Setup) FormatFor

func (s *Setup) FormatFor(depth uint8) (Format, bool)

FormatFor returns the pixmap Format matching depth, and whether one exists. PutImage needs it to size each pixel and pad each scanline.

type Shm added in v0.3.0

type Shm struct {
	VerMajor  uint16
	VerMinor  uint16
	SharedPix bool  // server supports shared pixmaps
	PixmapFmt uint8 // pixmap format for shared pixmaps
	FDCapable bool  // AttachFd usable: version >= 1.2 AND transport passes fds
	// contains filtered or unexported fields
}

Shm is a queried, ready-to-use MIT-SHM extension handle: the negotiated major opcode and version, and whether AttachFd (>= 1.2) is usable on this connection.

func (*Shm) AttachFd added in v0.3.0

func (s *Shm) AttachFd(seg uint32, fd int, readOnly bool) error

AttachFd registers the shared-memory segment named by seg, backed by fd, with the server (MIT-SHM 1.2). The descriptor is passed over SCM_RIGHTS; readOnly declares whether the server may only read the segment. The server takes ownership of the passed descriptor.

func (*Shm) Detach added in v0.3.0

func (s *Shm) Detach(seg uint32) error

Detach releases a previously attached segment.

func (*Shm) PutImage added in v0.3.0

func (s *Shm) PutImage(p *Presenter, drawable, gc uint32, seg uint32, offset uint32,
	totalW, totalH, srcX, srcY, w, h, dstX, dstY int) error

PutImage blits a w×h source region located at byte offset in segment seg (whose full geometry is totalW×totalH) onto drawable at (dstX, dstY), taking its top-left from (srcX, srcY) within the segment image. depth and the visual's ZPixmap format come from the Presenter. It is a single fixed-size request regardless of image size — the pixels travel through shared memory.

type VisualType

type VisualType struct {
	ID          uint32
	Class       uint8
	BitsPerRGB  uint8
	ColormapEnt uint16
	RedMask     uint32
	GreenMask   uint32
	BlueMask    uint32
}

VisualType describes a visual: its class and the RGB channel masks a TrueColor/DirectColor visual packs a pixel with. The masks drive the RGBA→wire byte conversion in PutImage.

type XError

type XError struct {
	Code     byte
	Seq      uint16
	BadValue uint32
	Major    byte
	Minor    uint16
}

XError is a decoded X11 error reply.

func (*XError) Error

func (e *XError) Error() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL