app.dhover×236 error×50all
// X11 F12 demo — cursors (../../../features/f12-cursors.md). Built on the
// scaffold (../scaffold/app.d): same ImportC binding style, same poll(2)
// readiness loop, same instrument.d event log. Rendering is grid lines via
// the default GC — the pixels that matter here are the CURSOR's, and those
// are composited by the SERVER (contrast Wayland, where the client renders
// its cursor into a wl_surface and runs its own animation frame timer).
//
// A 3x3 hover-zone grid: the eight edge/corner zones carry the eight resize
// cursors; the centre zone cycles default -> text -> pointer -> a custom ARGB
// bullseye -> an animated 'watch' on each re-entry. Every switch is one
// `XDefineCursor` + `XFlush`, logged as `cursor_set`. Four mechanisms are
// exercised and distinguished in the log:
//
//   * font   — `XCreateFontCursor(dpy, glyph)`: the core `cursor` font baked
//     into every X server since X11R1; glyph ids from <X11/cursorfont.h>
//     (macros — re-declared below per the scaffold ImportC gotcha).
//   * theme  — `XcursorLibraryLoadCursor(dpy, "nw-resize")`: libXcursor file
//     lookup through XCURSOR_THEME/XCURSOR_PATH/XCURSOR_SIZE (+ the display's
//     Xcursor.theme/.size resources). Startup logs the whole resolution:
//     `XcursorGetTheme`, `XcursorGetDefaultSize`, the env vars, and for every
//     shape BOTH load results — the run.sh driver varies the env and measures
//     which knobs libXcursor honors.
//   * custom — `XcursorImageCreate(24,24)` filled with raw premultiplied-ARGB
//     (a bullseye, hotspot 12,12) -> `XcursorImageLoadCursor`. The legacy
//     core alternative, `XCreatePixmapCursor`, takes a 1-bit source + mask
//     and exactly two colors — libXcursor is the only road to full ARGB.
//   * animated — `XcursorLibraryLoadImages("watch", ...)` -> N frames with
//     per-frame delays -> `XcursorImagesLoadCursor`. One call, then the
//     SERVER animates; the client never wakes up again.
//
// Zones are driven either by the built-in XWarpPointer storm (WSI_AUTO_EXIT=1,
// disable with WSI_NO_WARP=1) or externally via `xdotool mousemove` (run.sh).
// WSI_DURATION_MS bounds the run (default 8 s). Headless-safe: no X server ->
// prints `SKIP:` and exits 0. Findings: ../../f12-cursors.md.
module 
(module) app
app
;
import
(module) c
c
; // ImportC: Xlib + Xcursor + poll
C preprocess command `cpp` failed for file `/home/runner/work/sparkles/sparkles/docs/research/window-system-integration/os-apis/x11/examples/f12-cursors/c.c`, exit status 1
import
(module) instrument
instrument
;
import
(package) core
core
.
(package) core.stdc
stdc
.
(module) core.stdc.config

D compatible types that correspond to various basic types in associated C and C++ compilers.

Source

core/stdc/config.d

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseDistributed under the Boost Software License 1.0. (See accompanying file LICENSE)@authorsSean Kelly@standardsISO/IEC 9899:1999 (E)
config
: c_long, c_ulong;
import
(package) core
core
.
(package) core.stdc
stdc
.
(module) core.stdc.stdio

D header file for C99 <stdio.h>

pubs.opengroup.org/onlinepubs/009695399/basedefs/stdio.h.html, stdio.h

Source

core/stdc/stdio.d

@copyrightCopyright Sean Kelly 2005 - 2009.@licenseDistributed under the Boost Software License 1.0. (See accompanying file LICENSE)@authorsSean Kelly, Alex Rønne Petersen@standardsISO/IEC 9899:1999 (E)
stdio
:
(alias) app.printf = int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogc
printf
;
import
(package) core
core
.
(package) core.stdc
stdc
.
(module) core.stdc.stdlib

D header file for C99.

pubs.opengroup.org/onlinepubs/009695399/basedefs/stdlib.h.html, stdlib.h

Source

core/stdc/stdlib.d

@copyrightCopyright Sean Kelly 2005 - 2014.@licenseDistributed under the Boost Software License 1.0. (See accompanying file LICENSE)@authorsSean Kelly@standardsISO/IEC 9899:1999 (E)
stdlib
:
(alias) app.atoi = int core.stdc.stdlib.atoi(scope const(char*) nptr) nothrow @nogc
atoi
,
(alias) app.getenv = char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogc
getenv
;
// --------------------------------------------------------------------------- // Constants Xlib exposes as macros that ImportC cannot import; re-declared // per the scaffold gotcha (../../scaffold.md). enum : c_long {
(enum value) app.KeyPressMask = 1L
KeyPressMask
= 1L << 0,
(enum value) app.EnterWindowMask = 16L
EnterWindowMask
= 1L << 4,
(enum value) app.LeaveWindowMask = 32L
LeaveWindowMask
= 1L << 5,
(enum value) app.PointerMotionMask = 64L
PointerMotionMask
= 1L << 6,
(enum value) app.ExposureMask = 32768L
ExposureMask
= 1L << 15,
(enum value) app.StructureNotifyMask = 131072L
StructureNotifyMask
= 1L << 17,
} enum // XEvent.type discriminators {
(enum value) app.KeyPress = 2
KeyPress
= 2,
(enum value) app.MotionNotify = 6
MotionNotify
= 6,
(enum value) app.EnterNotify = 7
EnterNotify
= 7,
(enum value) app.LeaveNotify = 8
LeaveNotify
= 8,
(enum value) app.Expose = 12
Expose
= 12,
(enum value) app.ConfigureNotify = 22
ConfigureNotify
= 22,
(enum value) app.ClientMessage = 33
ClientMessage
= 33,
} enum
(constant) int app.False = 0
False
= 0;
enum
(constant) int app.True = 1
True
= 1;
enum
(constant) int app.None = 0
None
= 0;
enum
(constant) int app.POLLIN = 1
POLLIN
= 0x001;
// <X11/cursorfont.h> glyph ids (the header is #defines only). Each shape in // the core `cursor` font; the full table is in the header / XCreateFontCursor(3). enum : uint {
(enum value) app.XC_bottom_left_corner = 12u
XC_bottom_left_corner
= 12,
(enum value) app.XC_bottom_right_corner = 14u
XC_bottom_right_corner
= 14,
(enum value) app.XC_bottom_side = 16u
XC_bottom_side
= 16,
(enum value) app.XC_hand2 = 60u
XC_hand2
= 60,
(enum value) app.XC_left_ptr = 68u
XC_left_ptr
= 68,
(enum value) app.XC_left_side = 70u
XC_left_side
= 70,
(enum value) app.XC_right_side = 96u
XC_right_side
= 96,
(enum value) app.XC_top_left_corner = 134u
XC_top_left_corner
= 134,
(enum value) app.XC_top_right_corner = 136u
XC_top_right_corner
= 136,
(enum value) app.XC_top_side = 138u
XC_top_side
= 138,
(enum value) app.XC_watch = 150u
XC_watch
= 150,
(enum value) app.XC_xterm = 152u
XC_xterm
= 152,
} // --------------------------------------------------------------------------- // The shape vocabulary: one row per shape, carrying its cursor-spec themed // name (the names cursor-shape-v1 / CSS standardized) AND its core-font glyph. struct
(struct) app.Shape
Shape
{ const(char)*
(field) const(char)* app.Shape.name
name
; // themed (cursor-spec/CSS) name for XcursorLibraryLoadCursor
uint
(field) uint app.Shape.glyph
glyph
; // core cursor-font id for XCreateFontCursor
Cursor
(field) _error_ app.Shape.font
font
; // loaded font cursor
undefined identifier `Cursor`
Cursor
(field) _error_ app.Shape.theme
theme
; // loaded themed cursor (0 = lookup failed)
undefined identifier `Cursor`
} // Index 0..8 = grid zones (centre zone 4 is handled dynamically); 9..11 = the // centre-cycle shapes (default arrow, text I-beam, hand/link). __gshared
(struct) app.Shape
Shape
[12]
_error_ app.g_shapes
g_shapes
= [
Shape("nw-resize", XC_top_left_corner), Shape("n-resize", XC_top_side), Shape("ne-resize", XC_top_right_corner), Shape("w-resize", XC_left_side), Shape("default", XC_left_ptr), // placeholder for the centre zone Shape("e-resize", XC_right_side), Shape("sw-resize", XC_bottom_left_corner), Shape("s-resize", XC_bottom_side), Shape("se-resize", XC_bottom_right_corner), Shape("default", XC_left_ptr), Shape("text", XC_xterm), Shape("pointer", XC_hand2), ]; /// Load one shape through BOTH mechanisms and log both results: theme=0x0 /// means the libXcursor lookup failed end-to-end (no theme file found AND no /// core fallback in libXcursor's name->glyph table for this name). void
app.loadShape

Load one shape through BOTH mechanisms and log both results: theme=0x0 means the libXcursor lookup failed end-to-end (no theme file found AND no core fallback in libXcursor's name->glyph table for this name).

loadShape
(Display*
(parameter) Display* dpy
dpy
, ref
(struct) app.Shape
Shape
(parameter) Shape s
s
) @nogc nothrow
undefined identifier `Display`
{ s.
s.font
font
= XCreateFontCursor(dpy, s.
s.glyph
glyph
);
s.
s.theme
theme
= XcursorLibraryLoadCursor(dpy, s.
s.name
name
);
emitf("cursor_load", "name=%s font_glyph=%d font=0x%lx theme=0x%lx", s.
s.name
name
, s.
s.glyph
glyph
, s.
s.font
font
, s.
s.theme
theme
);
} /// Pick a shape's cursor, preferring the themed one; returns the path label. const(char)*
app.pick

Pick a shape's cursor, preferring the themed one; returns the path label.

pick
(const ref
(struct) app.Shape
Shape
(parameter) Shape s
s
, out Cursor
(parameter) Cursor cur
cur
) @nogc nothrow
undefined identifier `Cursor`
{ if (s.
s.theme
theme
!= 0)
{ cur = s.
s.theme
theme
;
return "theme"; } cur = s.
s.font
font
;
return "font"; } /// Log what the theme actually resolves a name to at the file level: frame /// count, nominal size vs actual pixel size, per-frame delay. This is also /// the F12 "log chosen size" requirement — the size XcursorGetDefaultSize /// picked is what the library loads. void
void app.logShapeImages(const(char)* name, const(char)* theme, int size) nothrow @nogc

Log what the theme actually resolves a name to at the file level: frame count, nominal size vs actual pixel size, per-frame delay. This is also the F12 "log chosen size" requirement — the size XcursorGetDefaultSize picked is what the library loads.

logShapeImages
(const(char)*
(parameter) const(char)* name
name
, const(char)*
(parameter) const(char)* theme
theme
, int
(parameter) int size
size
) @nogc nothrow
{ XcursorImages*
(local variable) _error_ imgs
imgs
= XcursorLibraryLoadImages(name, theme, size);
undefined identifier `XcursorImages`
undefined identifier `XcursorLibraryLoadImages`
if (imgs is null || imgs.nimage == 0) {
void instrument.emitf(scope const(char)* kind, scope const(char)* fmt, ...) nothrow @nogc

Emit an event with a printf-formatted key=value ... payload.

emitf
("cursor_images", "name=%s theme=%s size=%d frames=0 (lookup failed)",
(parameter) const(char)* name
name
,
(parameter) const(char)* theme
theme
is null ? "(null)".
(constant) immutable(char)* "(null)".ptr = "(null)"
ptr
:
(parameter) const(char)* theme
theme
,
(parameter) int size
size
);
if (imgs !is null) XcursorImagesDestroy(imgs);
undefined identifier `XcursorImagesDestroy`
return; }
void instrument.emitf(scope const(char)* kind, scope const(char)* fmt, ...) nothrow @nogc

Emit an event with a printf-formatted key=value ... payload.

emitf
("cursor_images", "name=%s theme=%s size_requested=%d frames=%d "
~ "frame0=%ux%u nominal=%u hot=%u,%u delay_ms=%u",
(parameter) const(char)* name
name
,
(parameter) const(char)* theme
theme
is null ? "(null)".
(constant) immutable(char)* "(null)".ptr = "(null)"
ptr
:
(parameter) const(char)* theme
theme
,
(parameter) int size
size
, imgs.nimage,
imgs.images[0].
(field) _error_ (__error)[0].width
width
, imgs.images[0].
(field) _error_ (__error)[0].height
height
, imgs.images[0].
(field) _error_ (__error)[0].size
size
,
imgs.images[0].xhot, imgs.images[0].yhot, imgs.images[0].delay); XcursorImagesDestroy(imgs);
undefined identifier `XcursorImagesDestroy`
} /// The custom cursor: a 24x24 premultiplied-ARGB bullseye, hotspot dead /// centre (12,12) — a hotspot the arrow's (0,0) habit would get wrong. Cursor
app.makeBullseye

The custom cursor: a 24x24 premultiplied-ARGB bullseye, hotspot dead centre (12,12) — a hotspot the arrow's (0,0) habit would get wrong.

makeBullseye
(Display*
(parameter) Display* dpy
dpy
) @nogc nothrow
undefined identifier `Cursor`
undefined identifier `Display`
{ XcursorImage*
_error_ img
img
= XcursorImageCreate(24, 24);
if (img is null) return 0; img.xhot = 12; img.yhot = 12; foreach (
(parameter) y
y
; 0 .. 24)
foreach (
(parameter) x
x
; 0 .. 24)
{ const
_error_ dx
dx
= x - 11.5,
_error_ dy
dy
= y - 11.5;
const
_error_ r2
r2
= dx * dx + dy * dy;
uint
_error_ px
px
= 0x00000000; // transparent outside
if (r2 <= 2.5 * 2.5) px = 0xff000000; // black centre dot else if (r2 <= 5.5 * 5.5) px = 0xffffffff; // white ring else if (r2 <= 8.5 * 8.5) px = 0xffcc2222; // red ring else if (r2 <= 11.5 * 11.5) px = 0xffffffff; // white rim img.pixels[y * 24 + x] = px; // premultiplied ARGB (alpha 0xff/0) } Cursor
_error_ cur
cur
= XcursorImageLoadCursor(dpy, img);
XcursorImageDestroy(img); emitf("cursor_custom", "api=XcursorImageLoadCursor size=24x24 hotspot=12,12 cursor=0x%lx " ~ "(legacy XCreatePixmapCursor: 1-bit source+mask, exactly 2 colors)", cur); return cur; } // --------------------------------------------------------------------------- int
int D main()
main
()
{
void instrument.initInstrument(const(char)* demoName) nothrow @nogc

Names the demo, starts the monotonic clock, and emits init_start. Call this first, before any platform API call.

initInstrument
("f12_x11");
const
(local variable) const(char*) envAuto
envAuto
=
char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogc
getenv
("WSI_AUTO_EXIT");
const
(local variable) const(bool) autoExit
autoExit
=
(local variable) const(char*) envAuto
envAuto
!is null &&
(local variable) const(char*) envAuto
envAuto
[0] == '1';
const
(local variable) const(char*) envNoWarp
envNoWarp
=
char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogc
getenv
("WSI_NO_WARP");
const
(local variable) const(bool) warp
warp
=
(local variable) const(bool) autoExit
autoExit
&& (
(local variable) const(char*) envNoWarp
envNoWarp
is null ||
(local variable) const(char*) envNoWarp
envNoWarp
[0] != '1');
const
(local variable) const(char*) envDur
envDur
=
char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogc
getenv
("WSI_DURATION_MS");
const
(local variable) const(int) durationMs
durationMs
=
(local variable) const(char*) envDur
envDur
!is null ?
int core.stdc.stdlib.atoi(scope const(char*) nptr) nothrow @nogc
atoi
(
(local variable) const(char*) envDur
envDur
) : 8_000;
Display*
(local variable) _error_ dpy
dpy
= XOpenDisplay(null);
undefined identifier `Display`
undefined identifier `XOpenDisplay`
if (dpy is null) {
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogc
printf
("SKIP: no X11 display (XOpenDisplay returned null)\n");
return 0; }
void instrument.emitf(scope const(char)* kind, scope const(char)* fmt, ...) nothrow @nogc

Emit an event with a printf-formatted key=value ... payload.

emitf
("step", "name=XOpenDisplay fd=%d", XConnectionNumber(dpy));
undefined identifier `XConnectionNumber`
const
(local variable) const(_error_) screen
screen
= XDefaultScreen(dpy);
undefined identifier `XDefaultScreen`
Window
(local variable) _error_ root
root
= XRootWindow(dpy, screen);
undefined identifier `Window`
undefined identifier `XRootWindow`
// -- Theme resolution: log every input libXcursor consults -------------- const(char)*
(local variable) const(char)* envTheme
envTheme
=
char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogc
getenv
("XCURSOR_THEME"),
(local variable) const(char)* envPath
envPath
=
char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogc
getenv
("XCURSOR_PATH"),
(local variable) const(char)* envSize
envSize
=
char* core.stdc.stdlib.getenv(scope const(char*) name) nothrow @nogc
getenv
("XCURSOR_SIZE");
char*
(local variable) char* theme
theme
= XcursorGetTheme(dpy);
undefined identifier `XcursorGetTheme`
const
(local variable) const(_error_) size
size
= XcursorGetDefaultSize(dpy);
undefined identifier `XcursorGetDefaultSize`
void instrument.emitf(scope const(char)* kind, scope const(char)* fmt, ...) nothrow @nogc

Emit an event with a printf-formatted key=value ... payload.

emitf
("xcursor_env", "XCURSOR_THEME=%s XCURSOR_PATH=%s XCURSOR_SIZE=%s",
(local variable) const(char)* envTheme
envTheme
?
(local variable) const(char)* envTheme
envTheme
: "(unset)",
(local variable) const(char)* envPath
envPath
?
(local variable) const(char)* envPath
envPath
: "(unset)",
(local variable) const(char)* envSize
envSize
?
(local variable) const(char)* envSize
envSize
: "(unset)");
void instrument.emitf(scope const(char)* kind, scope const(char)* fmt, ...) nothrow @nogc

Emit an event with a printf-formatted key=value ... payload.

emitf
("xcursor_resolved", "XcursorGetTheme=%s XcursorGetDefaultSize=%d "
~ "XcursorSupportsARGB=%d",
(local variable) char* theme
theme
?
(local variable) char* theme
theme
: "(null)", size, cast(int) XcursorSupportsARGB(dpy));
undefined identifier `XcursorSupportsARGB`
// -- Load every shape via BOTH mechanisms -------------------------------- foreach (ref
(parameter) s
s
; g_shapes)
loadShape(dpy, s); // File-level resolution for one static and one animated shape: what size // was actually chosen, and how many frames does 'watch' carry?
void app.logShapeImages(const(char)* name, const(char)* theme, int size) nothrow @nogc

Log what the theme actually resolves a name to at the file level: frame count, nominal size vs actual pixel size, per-frame delay. This is also the F12 "log chosen size" requirement — the size XcursorGetDefaultSize picked is what the library loads.

logShapeImages
("default",
(local variable) char* theme
theme
, size);
void app.logShapeImages(const(char)* name, const(char)* theme, int size) nothrow @nogc

Log what the theme actually resolves a name to at the file level: frame count, nominal size vs actual pixel size, per-frame delay. This is also the F12 "log chosen size" requirement — the size XcursorGetDefaultSize picked is what the library loads.

logShapeImages
("watch",
(local variable) char* theme
theme
, size);
Cursor
(local variable) _error_ custom
custom
= makeBullseye(dpy);
undefined identifier `Cursor`
// The animated cursor: count the frames ourselves, then hand ALL of them // to the server in one cursor object — the server runs the animation. Cursor
(local variable) _error_ animated
animated
= 0;
undefined identifier `Cursor`
const(char)*
(local variable) const(char)* animName
animName
= "watch",
(local variable) const(char)* animPath
animPath
= "animated";
XcursorImages*
(local variable) _error_ anim
anim
= XcursorLibraryLoadImages("watch", theme, size);
undefined identifier `XcursorImages`
undefined identifier `XcursorLibraryLoadImages`
if (anim is null || anim.nimage == 0) { if (anim !is null) XcursorImagesDestroy(anim);
undefined identifier `XcursorImagesDestroy`
(local variable) const(char)* animName
animName
= "progress";
anim = XcursorLibraryLoadImages("progress", theme, size); } if (anim !is null && anim.nimage > 0) { animated = XcursorImagesLoadCursor(dpy, anim);
void instrument.emitf(scope const(char)* kind, scope const(char)* fmt, ...) nothrow @nogc

Emit an event with a printf-formatted key=value ... payload.

emitf
("cursor_animated", "name=%s frames=%d delay_ms=%u cursor=0x%lx "
~ "animator=server (client sets it once, never ticks)",
(local variable) const(char)* animName
animName
, anim.nimage, anim.images[0].delay, animated);
XcursorImagesDestroy(anim);
undefined identifier `XcursorImagesDestroy`
} else
void instrument.emit(scope const(char)* kind) nothrow @nogc

Emit an event with no key=value payload.

emit
("cursor_animated frames=0 (no animated shape in reach; falls back to font XC_watch)");
if (animated == 0) { animated = XCreateFontCursor(dpy, XC_watch); // static fallback
(local variable) const(char)* animName
animName
= "watch";
(local variable) const(char)* animPath
animPath
= "font-fallback-static";
} // -- Window --------------------------------------------------------------- int
(local variable) int width
width
= 480,
(local variable) int height
height
= 480;
Window
(local variable) _error_ win
win
= XCreateSimpleWindow(dpy, root, 20, 20, width, height, 1,
undefined identifier `Window`
undefined identifier `XCreateSimpleWindow`
XBlackPixel(dpy, screen), XWhitePixel(dpy, screen)); XStoreName(dpy, win, "Sparkles · X11 F12 cursors");
undefined identifier `XStoreName`
Atom
(local variable) _error_ wmDelete
wmDelete
= XInternAtom(dpy, "WM_DELETE_WINDOW", False);
undefined identifier `Atom`
undefined identifier `XInternAtom`
XSetWMProtocols(dpy, win, &wmDelete, 1);
undefined identifier `XSetWMProtocols`
XSelectInput(dpy, win, ExposureMask | KeyPressMask | StructureNotifyMask
undefined identifier `XSelectInput`
| PointerMotionMask | EnterWindowMask | LeaveWindowMask); XMapWindow(dpy, win);
undefined identifier `XMapWindow`
void instrument.emitf(scope const(char)* kind, scope const(char)* fmt, ...) nothrow @nogc

Emit an event with a printf-formatted key=value ... payload.

emitf
("window_created", "xid=0x%lx size=%dx%d zones=3x3", win,
(local variable) int width
width
,
(local variable) int height
height
);
GC
(local variable) _error_ gc
gc
= XDefaultGC(dpy, screen);
undefined identifier `GC`
undefined identifier `XDefaultGC`
const
(local variable) const(_error_) fd
fd
= XConnectionNumber(dpy);
undefined identifier `XConnectionNumber`
bool
(local variable) bool running
running
= true;
int
(local variable) int zone
zone
= -1,
(local variable) int centerCycle
centerCycle
= -1,
(local variable) int warpStep
warpStep
= 0;
int
(local variable) int cursorSets
cursorSets
= 0;
// Centre-zone cycle: arrow -> text -> hand -> custom -> animated. // The XWarpPointer storm re-enters the centre after each edge zone, so a // full sweep exercises all five. static immutable int[17]
(immutable global) immutable(int[17]) app.main.warpZones
warpZones
= [0, 4, 1, 4, 2, 4, 3, 4, 5, 4, 6, 4, 7, 4, 8, 4, 0];
void
void app.main.setZoneCursor(int z) pure nothrow @nogc @safe
setZoneCursor
(int
(parameter) int z
z
) @nogc nothrow
{ Cursor
(local variable) _error_ cur
cur
;
undefined identifier `Cursor`
const(char)*
(local variable) const(char)* path
path
,
(local variable) const(char)* name
name
;
if (
(parameter) int z
z
== 4) // centre: advance the cycle on each entry
{
(local variable) int centerCycle
centerCycle
= (
(local variable) int centerCycle
centerCycle
+ 1) % 5;
switch (
(local variable) int centerCycle
centerCycle
)
{ case 0: case 1: case 2:
(local variable) const(char)* name
name
= g_shapes[9 + centerCycle].
(field) _error_ (__error)[9 + centerCycle].name
name
;
(local variable) const(char)* path
path
= pick(g_shapes[9 + centerCycle], cur);
break; case 3:
(local variable) const(char)* name
name
= "custom-bullseye";
(local variable) const(char)* path
path
= "custom";
cur = custom; break; default:
(local variable) const(char)* name
name
=
(local variable) const(char)* animName
animName
;
(local variable) const(char)* path
path
=
(local variable) const(char)* animPath
animPath
;
cur = animated; break; } } else {
(local variable) const(char)* name
name
= g_shapes[z].
(field) _error_ (__error)[z].name
name
;
(local variable) const(char)* path
path
= pick(g_shapes[z], cur);
} XDefineCursor(dpy, win, cur);
undefined identifier `XDefineCursor`
XFlush(dpy); // the request must reach the server before we sleep
undefined identifier `XFlush`
++
(local variable) int cursorSets
cursorSets
;
void instrument.emitf(scope const(char)* kind, scope const(char)* fmt, ...) nothrow @nogc

Emit an event with a printf-formatted key=value ... payload.

emitf
("cursor_set", "zone=%d name=%s path=%s size=%d cursor=0x%lx",
(parameter) int z
z
,
(local variable) const(char)* name
name
,
(local variable) const(char)* path
path
, size, cur);
} while (
(local variable) bool running
running
)
{ while (XPending(dpy) > 0)
undefined identifier `XPending`
{ XEvent
(local variable) _error_ ev
ev
;
undefined identifier `XEvent`
XNextEvent(dpy, &ev);
undefined identifier `XNextEvent`
switch (ev.type) { case MotionNotify: case EnterNotify: const
_error_ x
x
= ev.type == MotionNotify ? ev.xmotion.
ev.xmotion.x
x
: ev.xcrossing.
ev.xcrossing.x
x
;
const
_error_ y
y
= ev.type == MotionNotify ? ev.xmotion.
ev.xmotion.y
y
: ev.xcrossing.
ev.xcrossing.y
y
;
int
_error_ zx
zx
= x * 3 / (width > 0 ? width : 1),
_error_ zy
zy
= y * 3 / (height > 0 ? height : 1);
zx = zx < 0 ? 0 : (zx > 2 ? 2 : zx); zy = zy < 0 ? 0 : (zy > 2 ? 2 : zy); const
_error_ z
z
= zy * 3 + zx;
if (z != zone) { zone = z; setZoneCursor(z); } break; case LeaveNotify: zone = -1; // re-entering the same zone counts as an entry break; case Expose: if (ev.xexpose.count == 0) { foreach (
(parameter) i
i
; 1 .. 3) // the 3x3 grid, server-side lines
{ XDrawLine(dpy, win, gc, width * i / 3, 0, width * i / 3, height); XDrawLine(dpy, win, gc, 0, height * i / 3, width, height * i / 3); } XFlush(dpy); } break; case ConfigureNotify: width = ev.xconfigure.
ev.xconfigure.width
width
;
height = ev.xconfigure.
ev.xconfigure.height
height
;
break; case ClientMessage: if (cast(Atom) ev.xclient.data.l[0] == wmDelete) { emit("close_requested via=WM_DELETE_WINDOW"); running = false; } break; case KeyPress: running = false; break; default: break; } } if (
(local variable) const(bool) autoExit
autoExit
)
{ const
(local variable) const(long) elapsedMs
elapsedMs
=
long instrument.nowUs() nothrow @nogc

Microseconds elapsed since initInstrument.

nowUs
() / 1000;
// The built-in driver: one warp every 300 ms through all zones, // re-entering the centre between edge zones (cycles all 5 centre // cursors). The warp generates real MotionNotify events. if (
(local variable) const(bool) warp
warp
&&
(local variable) int warpStep
warpStep
<
(immutable global) immutable(int[17]) app.main.warpZones
warpZones
.
(constant) ulong immutable(int[17]).length = 17LU
length
&&
(local variable) const(long) elapsedMs
elapsedMs
> 500 + 300 *
(local variable) int warpStep
warpStep
)
{ const
(local variable) immutable(int) z
z
=
(immutable global) immutable(int[17]) app.main.warpZones
warpZones
[
(local variable) int warpStep
warpStep
];
XWarpPointer(dpy, None, win, 0, 0, 0, 0,
undefined identifier `XWarpPointer`
(z % 3) * width / 3 + width / 6, (z / 3) * height / 3 + height / 6); XFlush(dpy);
undefined identifier `XFlush`
++
(local variable) int warpStep
warpStep
;
} if (
(local variable) const(long) elapsedMs
elapsedMs
>
(local variable) const(int) durationMs
durationMs
)
{
void instrument.emit(scope const(char)* kind) nothrow @nogc

Emit an event with no key=value payload.

emit
("auto_exit");
break; } } pollfd
(local variable) _error_ pfd
pfd
;
undefined identifier `pollfd`
pfd.
pfd.fd
fd
= fd;
pfd.events = POLLIN; pfd.revents = 0; poll(&pfd, 1, autoExit ? 50 : -1);
undefined identifier `poll`
}
void instrument.emitf(scope const(char)* kind, scope const(char)* fmt, ...) nothrow @nogc

Emit an event with a printf-formatted key=value ... payload.

emitf
("summary", "cursor_sets=%d theme=%s default_size=%d",
(local variable) int cursorSets
cursorSets
,
(local variable) char* theme
theme
?
(local variable) char* theme
theme
: "(null)", size);
XFreeCursor(dpy, custom);
undefined identifier `XFreeCursor`
XDestroyWindow(dpy, win);
undefined identifier `XDestroyWindow`
XCloseDisplay(dpy);
undefined identifier `XCloseDisplay`
void instrument.emit(scope const(char)* kind) nothrow @nogc

Emit an event with no key=value payload.

emit
("teardown");
return 0; }