---
title: Windows & drawing
sidebar_position: 2
---

# Windows & drawing

## Creating a window

`CreateWindow` takes the new window id, the parent window, geometry, and a
few optional wire fields. Only the first six arguments are usually needed —
border width, depth, class and visual all default to "inherit from parent"
(`CopyFromParent`):

```js
const x11 = require('x11');

x11.createClient((err, display) => {
  const X = display.client;
  const wid = X.AllocID();
  X.CreateWindow(wid, display.screen[0].root, 100, 100, 400, 300);
  X.MapWindow(wid);
  X.on('error', err => { console.log(err); });
});
```

The full signature is
`CreateWindow(wid, parent, x, y, width, height, borderWidth, depth, class, visual, values)`.
The trailing `values` object sets window attributes at creation time — the
same set `ChangeWindowAttributes` accepts — for example:

```js
X.CreateWindow(wid, root, 0, 0, 500, 500, 0, 0, 0, 0, {
  backgroundPixel: display.screen[0].white_pixel,
  eventMask: x11.eventMask.Exposure | x11.eventMask.ButtonPress,
});
```

A window becomes visible only after `X.MapWindow(wid)`.

<LiveDemo demo="guide-create-window" compact />

## Graphics contexts

All core drawing requests take a graphics context (GC) that carries pen
state: foreground/background pixels, line width, font, raster operation and
so on. Create one with `CreateGC(gc, drawable, values)`:

```js
const gc = X.AllocID();
X.CreateGC(gc, wid, {
  foreground: display.screen[0].black_pixel,
  background: display.screen[0].white_pixel,
});
```

GCs can be mutated later with `ChangeGC(gc, values)` and freed with
`FreeGC(gc)`.

The GC is where nearly all drawing state lives, which is why the same request
can produce very different ink. Below, `PolyFillRectangle` is called four
times with identical arguments — only `ChangeGC` differs between them, and the
last one switches the raster operation to `GXxor` so it combines with what is
already on screen instead of replacing it:

<LiveDemo demo="guide-gc" compact />

## Drawing requests

Core drawing requests target any drawable (a window or a pixmap):

```js
X.on('event', ev => {
  if (ev.name === 'Expose') {
    X.PolyFillRectangle(wid, gc, [0, 0, 500, 500]); // x, y, w, h
    X.PolyLine(0, wid, gc, [10, 10, 100, 100, 10, 100]); // coordMode, points
    X.PolyText8(wid, gc, 50, 50, ['Hello, Node.JS!']);
  }
});
```

Draw from an `Expose` handler — the server does not preserve window contents
for you, and `Expose` tells you when (part of) the window needs repainting.

There are no paths and no curves beyond the ellipse: every shape is one
request carrying a flat list of 16-bit coordinates. Note that `PolyLine` and
`PolyPoint` take `coordMode` as their *first* argument while every other
drawing request takes the drawable first — an inconsistency worth knowing
before it costs you an afternoon:

<LiveDemo demo="shapes" compact />

Drawing can also be masked. A clip list installed on the GC with
`SetClipRectangles` turns it into a stencil, which is how core X11 produces
shapes it has no request for — the fill is ordinary, the rectangle list is
the shape:

<LiveDemo demo="clip-rects" compact />

Pixmaps are off-screen drawables, useful for double buffering:

```js
const pixmap = X.AllocID();
X.CreatePixmap(pixmap, wid, depth, width, height);
// ... draw into the pixmap ...
X.CopyArea(pixmap, wid, gc, 0, 0, 0, 0, width, height);
```

`CopyArea` is a server-side blit: no pixel data crosses the connection, which
makes "draw once into a pixmap, then move it" the cheapest animation the core
protocol offers. The demo below scrolls a 960×200 pixmap drawn a single time,
at two requests per frame:

<LiveDemo demo="copy-area" compact />

The complete list of drawing requests — `PolyPoint`, `PolySegment`,
`PolyArc`, `FillPoly`, `PutImage`, `GetImage`, `CopyPlane` and friends — is
in the [core requests reference](../reference/core-requests.md).

## Anti-aliased drawing and gradients

The core protocol only does flat 1-bit-coverage drawing. For anti-aliasing,
alpha blending and gradients, load the [RENDER](../reference/ext/render.md)
extension. Its unit of work is the *Picture*: a drawable wrapped in a pixel
format, or — for gradients and solid fills — no drawable at all.

:::note Colour components are floats

Everywhere in the RENDER binding, colour components are **0..1 and clamped**,
not the 16-bit values the protocol carries on the wire; the client scales them
for you. Passing `0xffff` gets you 1.0, and passing `0x3000` for alpha gets you
1.0 as well, silently — so a stop list written in 16-bit values comes out fully
opaque rather than translucent.

:::

Gradients are Pictures with nothing behind them: the client sends a few hundred
bytes describing the ramp, and the server evaluates it for every sample the
composite needs.

<LiveDemo demo="render-gradients" compact />

Because a Picture's source can be transformed, a small pixmap goes a long way.
`SetPictureTransform` takes a 3×3 matrix mapping *destination* coordinates back
to source coordinates — the inverse of how you would write it for a canvas —
and `SetPictureFilter` chooses the resampling:

<LiveDemo demo="render-transform" compact />

Compositing itself is Porter-Duff, and the operator is an argument to every
RENDER drawing request. The fourteen operators only differ from one another
where both sides carry alpha, which is what this grid is arranged to show:

<LiveDemo demo="render-operators" compact />

`Render` also provides `RadialGradient`, `ConicalGradient`, `Triangles`,
`FillRectangles` and glyph rendering — see the
[RENDER reference](../reference/ext/render.md).
