// Minimal X11 window — the irreducible Xlib sequence that GLFW/SDL/winit wrap on
// Linux: XOpenDisplay -> XCreateSimpleWindow -> XMapWindow -> XNextEvent. All
// types and functions come from the real <X11/Xlib.h> via the ImportC shim
// (`c.c`); nothing is hand-declared. See ../index.md (the X11 OS-API survey).
//
// Headless-safe: if no X server is reachable, XOpenDisplay returns null, we print
// `SKIP:` and exit 0. With a live $DISPLAY it opens a real window, draws on the
// first Expose, and exits (a real app loops until WM_DELETE_WINDOW).
module (module) appapp;
import (module) cc; // ImportC: <X11/Xlib.h>
import (package) corecore.(package) core.stdcstdc.(module) core.stdc.configD compatible types that correspond to various basic types in associated
C and C++ compilers.
Source
core/stdc/config.d
config : c_long;
import (package) corecore.(package) core.stdcstdc.(module) core.stdc.stdioD header file for C99 <stdio.h>
pubs.opengroup.org/onlinepubs/009695399/basedefs/stdio.h.html, stdio.h
Source
core/stdc/stdio.d
stdio : (alias) app.printf = int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogcprintf;
// Xlib exposes these as expression/object-like macros (e.g. `(1L<<15)`), which
// ImportC does not reliably import — re-declare the few we use, per the ImportC
// guide. (Function macros DefaultScreen/RootWindow/BlackPixel are likewise
// avoided in favour of their real function forms XDefaultScreen/XRootWindow/….)
enum : c_long
{
(enum value) app.ExposureMask = 32768LExposureMask = 1L << 15,
(enum value) app.KeyPressMask = 1LKeyPressMask = 1L << 0,
(enum value) app.StructureNotifyMask = 131072LStructureNotifyMask = 1L << 17,
}
enum
{
(enum value) app.Expose = 12Expose = 12,
(enum value) app.KeyPress = 2KeyPress = 2,
(enum value) app.ClientMessage = 33ClientMessage = 33,
}
int int D main()main()
{
// 1. Connect to the X server named by $DISPLAY (null = default).
Display* (local variable) _error_ dpydpy = XOpenDisplay(null);
if (dpy is null)
{
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogcprintf("SKIP: no X11 display (XOpenDisplay returned null)\n");
return 0; // green on a headless runner
}
scope (exit)
XCloseDisplay(dpy);
const (local variable) const(_error_) screenscreen = XDefaultScreen(dpy);
const (local variable) const(_error_) rootroot = XRootWindow(dpy, screen);
// 2. Create a top-level window as a child of the root window.
Window (local variable) _error_ winwin = XCreateSimpleWindow(dpy, root,
0, 0, 480, 320, // x, y, width, height
1, // border width
XBlackPixel(dpy, screen), XWhitePixel(dpy, screen));
XStoreName(dpy, win, "Sparkles · X11 (Xlib)");
// 3. Route the window-manager close button to us as a ClientMessage.
Atom (local variable) _error_ wmDeletewmDelete = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
XSetWMProtocols(dpy, win, &wmDelete, 1);
// 4. Subscribe to events, then map (show) the window.
XSelectInput(dpy, win, ExposureMask | KeyPressMask | StructureNotifyMask);
XMapWindow(dpy, win);
// 5. Event loop. A real app loops until WM_DELETE_WINDOW / a key; here we draw
// once on the first Expose and exit so CI never blocks.
GC (local variable) _error_ gcgc = XDefaultGC(dpy, screen);
XEvent (local variable) _error_ evev;
while (true)
{
XNextEvent(dpy, &ev);
if (ev.type == (enum value) app.Expose = 12Expose)
{
XSetForeground(dpy, gc, XBlackPixel(dpy, screen));
XFillRectangle(dpy, win, gc, 190, 130, 100, 60);
XFlush(dpy);
int core.stdc.stdio.printf(scope const(char*) format, scope const ...) nothrow @nogcprintf("ok: mapped a 480x320 window and drew on Expose\n");
return 0;
}
if (ev.type == (enum value) app.KeyPress = 2KeyPress || ev.type == (enum value) app.ClientMessage = 33ClientMessage)
return 0;
}
}