Skip to main content

RANDR extension

Resize, rotate and reflect the screen, and inspect/configure the CRTCs, outputs and modes behind it. This is the modern interface to multi-monitor setups (see ext/xinerama.md for the legacy view). All RANDR 1.3 requests are implemented (minor opcodes 0-31, except the deprecated 1.0 OldGetScreenInfo/OldScreenChangeSelectInput at 1 and 3).

X.require('randr', (err, Randr) => {
// you MUST negotiate the version you intend to use before other
// requests, otherwise the server may not behave as expected
Randr.QueryVersion(1, 3, (err, version) => {
Randr.GetScreenResources(root, (err, res) => {
Randr.GetOutputInfo(res.outputs[0], 0, (err, info) => {
// info.name, info.connection, info.modes, ...
});
});
});
});

X.require calls QueryVersion(255, 255) automatically and stores the result as Randr.major_version / Randr.minor_version. Despite that, call QueryVersion yourself with the version you actually target before issuing other requests (see Notes).

Requests​

QueryVersion(clientMajor, clientMinor, cb)​

Negotiates the protocol version. cb(err, [major, minor]) — the version the server will speak to this client.

SetScreenConfig(win, timestamp, configTimestamp, sizeId, rotation, rate, cb)​

RANDR 1.0-style screen configuration: pick size sizeId from GetScreenInfo().screens, a rotation (Randr.Rotation bit) and refresh rate. cb(err, {status, newTs, configTs, root, subpixelOrder}). When the server answers with a non-zero status, err is an Error with err.code set to the status (Randr.ConfigStatus) and the reply object is still passed as the second argument.

SelectInput(win, mask)​

Selects RANDR event delivery for win; mask is a bitwise OR of Randr.NotifyMask values. No reply. Note that only RRScreenChangeNotify has an event parser (see Events).

GetScreenInfo(win, cb)​

1.0-style screen state. cb(err, info) with

{
rotations, // bitmask of supported Rotation values
root, timestamp, config_timestamp,
sizeID, // index into screens of the current size
rotation, rate, // current rotation and refresh rate
screens, // [{px_width, px_height, mm_width, mm_height}, ...]
rates // flat CARD16 rate-info entries, as on the wire:
// for each size a count followed by that many rates
}

GetScreenSizeRange(win, cb)​

cb(err, {minWidth, minHeight, maxWidth, maxHeight}) — the sizes accepted by SetScreenSize.

SetScreenSize(win, width, height, mmWidth, mmHeight)​

Sets the screen size; width/height in pixels, mmWidth/mmHeight in millimeters. No reply.

GetScreenResources(win, cb)​

cb(err, resources) with

{
timestamp, config_timestamp,
crtcs, // [crtc, ...] XIDs
outputs, // [output, ...] XIDs
modeinfos // [{id, width, height, dot_clock, h_sync_start, h_sync_end,
// h_total, h_skew, v_sync_start, v_sync_end, v_total,
// name_len, modeflags, name}, ...]
}

May force a hardware re-probe; prefer GetScreenResourcesCurrent when stale data is acceptable.

GetOutputInfo(output, configTimestamp, cb)​

cb(err, info) with

{
timestamp, crtc,
mm_width, mm_height,
connection, // Randr.Connection value
subpixelOrder,
preferredModes, // count: the first N entries of modes are preferred
crtcs, // [crtc, ...] usable with this output
modes, // [mode, ...] mode XIDs (match modeinfos ids)
clones, // [output, ...] outputs sharing this one's wiring
name // e.g. 'HDMI-1'
}

ListOutputProperties(output, cb)​

cb(err, atoms) — array of property name atoms defined on output.

QueryOutputProperty(output, property, cb)​

cb(err, {pending, range, immutable, validValues}) — booleans plus an array of INT32: a [min, max] pair when range is true, otherwise the list of valid values.

ConfigureOutputProperty(output, property, pending, range, values)​

Sets the property's valid values ([min, max] when range is truthy, else a list) and whether changes are pending until the next SetCrtcConfig. values is an array of INT32. No reply.

ChangeOutputProperty(output, property, type, format, mode, data)​

Sets property contents. type is an atom, format 8/16/32, mode 0 replace / 1 prepend / 2 append. data may be a Buffer (raw bytes), an array of numbers (one per format unit) or a string (latin1). No reply.

DeleteOutputProperty(output, property)​

Deletes the property. No reply. A subsequent QueryOutputProperty yields a BadName error.

GetOutputProperty(output, property, type, longOffset, longLength, del, pending, cb)​

Like core GetProperty but for outputs; longOffset/longLength are in 4-byte units, del deletes after reading, pending reads the pending value. cb(err, {format, type, bytesAfter, numItems, data}) — data is a Buffer of numItems format-sized items.

CreateMode(win, modeInfo, cb)​

Registers a user mode line. modeInfo is {width, height, dot_clock, h_sync_start, h_sync_end, h_total, h_skew, v_sync_start, v_sync_end, v_total, modeflags, name} — all except width/height/name default to 0 and the mode XID is chosen by the server. cb(err, mode). Some servers refuse user modes with a RANDR error.

DestroyMode(mode)​

Destroys a user mode not in use by any output. No reply.

AddOutputMode(output, mode)​

Adds a user mode to the output's mode list. No reply.

DeleteOutputMode(output, mode)​

Removes a user mode from the output's mode list. No reply.

GetCrtcInfo(crtc, configTimestamp, cb)​

cb(err, info) with

{
status, // Randr.ConfigStatus
timestamp, x, y, width, height,
mode, // current mode XID, 0 when disabled
rotation, // current rotation
rotations, // bitmask of supported rotations
output, // [output, ...] currently driven (note: singular name)
possible // [output, ...] connectable to this crtc
}

SetCrtcConfig(crtc, timestamp, configTimestamp, x, y, mode, rotation, outputs, cb)​

Applies a crtc configuration; outputs is an array of output XIDs, mode 0 with outputs [] disables the crtc. cb(err, {status, timestamp}); a non-Success status is reported in status (not converted to an error).

GetCrtcGammaSize(crtc, cb)​

cb(err, size) — length of the gamma ramps (0 when unsupported).

GetCrtcGamma(crtc, cb)​

cb(err, {size, red, green, blue}) — three arrays of size CARD16 values.

SetCrtcGamma(crtc, red, green, blue)​

Sets the gamma ramps; three equal-length arrays of CARD16, length must equal GetCrtcGammaSize. No reply.

GetScreenResourcesCurrent(win, cb)​

Same reply shape as GetScreenResources but returns the server's current idea of the configuration without forcing a re-probe.

SetCrtcTransform(crtc, transform, filterName, filterParams)​

Sets the pending crtc transform. transform is an array of 9 JS numbers (a 3x3 row-major matrix) converted to 16.16 FIXED on the wire — values are rounded to the nearest 1/65536. filterName is a string (e.g. 'bilinear', may be ''), filterParams an array of numbers (also FIXED on the wire). No reply. On crtcs without transform support the server answers BadValue.

GetCrtcTransform(crtc, cb)​

cb(err, info) with

{
pendingTransform, // [9 numbers], FIXED converted back to floats
hasTransforms, // boolean: crtc supports transforms
currentTransform, // [9 numbers]
pendingFilter, // string
pendingParams, // [numbers]
currentFilter,
currentParams
}

GetPanning(crtc, cb)​

cb(err, {status, timestamp, left, top, width, height, trackLeft, trackTop, trackWidth, trackHeight, borderLeft, borderTop, borderRight, borderBottom}).

SetPanning(crtc, timestamp, panning, cb)​

panning is an object with the same fields GetPanning returns (the status/timestamp fields are ignored on input). cb(err, {status, timestamp}). Servers without a panning hook (e.g. Xvfb) answer with a RANDR error.

SetOutputPrimary(win, output)​

Marks output as primary; output 0 (None) clears it. No reply.

GetOutputPrimary(win, cb)​

cb(err, output) — the primary output XID, 0 when none is set.

Events​

RRScreenChangeNotify​

Delivered after SelectInput with NotifyMask.ScreenChange whenever the screen configuration changes. Parsed fields: name ('RRScreenChangeNotify'), type, seq, rotation (new rotation, from the event detail byte), time, configtime, root, requestWindow, sizeId, subpixelOrder, width, height, physWidth, physHeight, raw (Buffer).

The 1.2 RRNotify event (crtc/output/property sub-events selected via CrtcChange/OutputChange/OutputProperty masks) has no parser; only ScreenChange events arrive in usable form.

Notes​

  • Version negotiation matters: the server tailors behavior (and some requests only work) after the client announces the version it speaks. X.require announces 255.255; the test suite explicitly re-negotiates with QueryVersion(1, 2, ...) before touching resources — do the same with the version you target.
  • 16.16 FIXED: crtc transforms and filter parameters travel as 32-bit fixed point (value × 65536). The module converts to/from JS numbers for you; expect quantization to multiples of 1/65536 on read-back.
  • Enums attached to the extension object:
    • Randr.NotifyMask = {ScreenChange: 1, CrtcChange: 2, OutputChange: 4, OutputProperty: 8, All: 15}
    • Randr.Rotation = {Rotate_0: 1, Rotate_90: 2, Rotate_180: 4, Rotate_270: 8, Reflect_X: 16, Reflect_Y: 32} (bitmask)
    • Randr.ConfigStatus = {Success: 0, InvalidConfigTime: 1, InvalidTime: 2, Failed: 3}
    • Randr.Connection = {Connected: 0, Disconnected: 1, Unknown: 2}
    • Randr.ModeFlag = {HSyncPositive: 1, HSyncNegative: 2, ..., ClockDivideBy2: 8192} (mode timing flags bitmask)
  • GetCrtcInfo names its list of driven outputs output (singular); SetCrtcConfig accepts it directly (info.output).
  • Mode name strings are concatenated without separators on the wire; the unpacker splits them using each mode's name_len.