# Backend-Specific Branches Remaining in `src/` Policy Code > **Status (2026-05-26):** This document was written during the initial abstraction > analysis. Since then, `wmspec.c` and `xdnd.c` have been **moved to > `src/backend/x11/`** and all `_x11_raw` references have been eliminated from > policy code (`src/*.c` now has zero `_x11_raw` accesses and zero direct Xlib > calls). The information below remains useful as a historical reference for the > abstraction work that was performed. The backend vtable (`wm_backend->*()`) handles most display-system dispatch, but significant X11-specific code still lives directly in the policy files. Here's every category. --- ## 1. Compile-Time `#ifdef` Branches ### `USE_WAYLAND_BACKEND` (2 sites) | File | Line | Purpose | |---|---|---| | `main.c` | 60 | `#include` wayland backend header | | `main.c` | 771 | Select `wl_backend` vs `x11_backend` vtable | This is clean — it's the backend selection switch. ### `XKB_BUTTON_HINT` (38 sites — the biggest offender) Sprayed across the frame window and window management code. Adds a "language indicator" button to the titlebar. | File | Sites | What it guards | |---|---|---| | `framewin.c` | **22** | Language button creation, layout, drawing, click handling, destroy | | `framewin.h` | **10** | Language button fields in `WFrameWindow` struct, function prototypes | | `window.c` | **10** | Language button setup during window manage/unmanage, attribute updates | | `wdefaults.c` | 3 | Language button in per-window attribute defaults | | `WindowMaker.h` | 1 | `WBUT_XKBGROUP*` button constants, `PRED_BPIXMAPS` count | | `window.h` | 1 | `language_button` field in `WWindow` | | `def_pixmaps.h` | 1 | Language button pixmap data | | `dialog.c` | 2 | Feature reporting in info dialog | | `winspector.c` | 1 | Window inspector language option | ### `KEEP_XKB_LOCK_STATUS` (6 sites) | File | Line(s) | What it guards | |---|---|---| | `framewin.c` | 23, 86 | XKB include, language state tracking in frame | | `framewin.h` | 93 | `languagemode` / `last_languagemode` fields | | `event.c` | 1853 | XKB state-change event handling | | `window.c` | 1727 | XKB lock status update on focus | | `WindowMaker.h` | 359, 622 | XKB state in preferences, XKB event base in globals | | `keybind.h` | 161 | `WKBD_TOGGLE` keybinding | ### `USE_DOCK_XDND` (7 sites) | File | Line(s) | What it guards | |---|---|---| | `appicon.c` | 52, 131, 315, 338 | XDND include, DND-aware setup, DND event handling on app icons | | `dock.c` | 76 | XDND include | | `event.c` | (via backend) | XDND client message dispatch | | `dialog.c` | 1433 | Feature reporting | Plus `xdnd.c` itself (312 lines) is **entirely X11-specific** — raw `XInternAtom`, `XGetWindowProperty`, `XSendEvent`, `XGetSelectionOwner` throughout. ### `USE_XSHAPE` (4 sites + headers) | File | Line(s) | What it guards | |---|---|---| | `window.c` | 654, 2012, 2236, 2301 | Shape extension queries on client windows | | `window.h` | 263, 345 | `net_has_shape` flag, shape update prototype | | `WindowMaker.h` | 615 | Shape event base in globals | | `balloon.h` | 26 | `SHAPED_BALLOON` for shaped tooltip windows | ### `USE_XINERAMA` (10 sites) | File | Line(s) | What it guards | |---|---|---| | `workspace.c` | 252, 280, 295, 303, 328 | Per-monitor workspace geometry calculations | | `wmspec.c` | 78, 165, 294, 1043, 1087, 1820 | EWMH multi-monitor strut/workarea handling | | `actions.c` | 975 | Maximize to monitor bounds | | `dialog.c` | 1445, 1447 | Feature reporting, Solaris Xinerama variant | ### `USE_RANDR` (1 site + header) | File | Line(s) | What it guards | |---|---|---| | `dialog.c` | 1458 | Feature reporting | | `WindowMaker.h` | 629 | RandR event base in globals | ### `USE_MWM_HINTS` (2 sites) | File | Line(s) | What it guards | |---|---|---| | `window.c` | 63, 360 | Motif WM hints include and processing | | `dialog.c` | 1429 | Feature reporting | ### `HAVE_INOTIFY` (6 sites) | File | Line(s) | What it guards | |---|---|---| | `main.c` | 23, 487, 787 | Inotify includes, setup, watch creation | | `event.c` | 25 | Inotify includes | | `shutdown.c` | 61, 91 | Inotify fd cleanup | | `WindowMaker.h` | 553 | Inotify fd in globals | ### Minor `HAVE_*` guards | Guard | File | Purpose | |---|---|---| | `HAVE_SETSID` | `main.c:326,378`, `dock.c:3000` | `setsid()` availability | | `HAVE_MALLOC_H` | `dialog.c:39` | Include path | | `HAVE_XINTERNATOMS` | `wmspec.c:662` | Batch atom intern optimization | | `HAVE_STDNORETURN` | `event.h:28`, `main.h:27` | C11 `_Noreturn` | --- ## 2. Runtime `_x11_raw` Escape Hatch (16 sites — NOW ZERO in policy code) The `WMEvent` struct carries a `void *_x11_raw` field — a pointer to the original `XEvent`. Policy code reaches through it when the abstracted event fields aren't sufficient: | File | Line(s) | What it does | |---|---|---| | `event.c` | 249, 264, 269, 276 | `handleConfigureRequest` — passes raw XEvent to backend for RandR, Shape, XKB extension events | | `event.c` | 431 | `handleMapRequest` — raw XEvent for `wManageWindow` | | `event.c` | 446–447 | `handleExtensions` — passes raw event to backend | | `event.c` | 782 | `handleButtonPress` — raw XEvent for `wDockReceiveDNDDrop` | | `event.c` | 831, 834, 852, 857 | `handleClientMessage` — raw XEvent for EWMH, XDND, selection | | `event.c` | 971, 974 | `handleClientMessage` — raw XEvent to `netwm_process_client_message`, `xdnd_process_client_message` | | `event.c` | 993 | `handleClientMessage` — raw XEvent for colormap install | | `event.c` | 1354 | `handleKeyPress` — raw XEvent for root menu shortcuts | | `framewin.c` | 1165 | Frame titlebar click — raw XEvent | | `icon.c` | 861 | Miniwindow double-click — raw XEvent | | `cycling.c` | 227–234 | Window cycling — synthesizes XEvent for switch panel, with Wayland fallback | | `menu.c` | 738 | Menu key handling — raw XEvent | | `winspector.c` | 1038 | Window inspector — raw XEvent | --- ## 3. X11 Types in Function Signatures Functions in policy code that take raw X11 types as parameters — these are API boundaries that can't work on Wayland without the `_x11_raw` escape hatch or a cast: | File | Function | X11 parameter type | |---|---|---| | `client.c:119` | `wClientConfigure()` | `XConfigureRequestEvent *` | | `client.c:247` | `wClientCheckProperty()` | `XPropertyEvent *` | | `rootmenu.c:320` | `wRootMenuPerformShortcut()` | `XEvent *` | | `switchpanel.c:684` | `wSwitchPanelHandleEvent()` | `XEvent *` | | `dock.c:1978` | `findDock()` | `XEvent *` | | `dock.c:2009` | `wDockReceiveDNDDrop()` | `XEvent *` | | `icon.c:57` | `miniwindowDblClick()` | `XEvent *` | | `menu.c:677` | `check_key()` | `XKeyEvent *` | | `window.c:90` | `windowLanguageClick()` | `XEvent *` | | `wmspec.c:1701` | `wNETWMProcessClientMessage()` | `XClientMessageEvent *` | | `event.c:94–95` | `handle_selection_request/clear()` | `XSelectionRequestEvent/ClearEvent *` | --- ## 4. Direct Xlib Calls in Policy Code (by file) Files that call Xlib functions directly instead of going through `wm_backend`: | File | Call count | What's leaking | |---|---|---| | **`wmspec.c`** | **65** | `XGetWindowProperty`, `XChangeProperty`, `XDeleteProperty`, `XInternAtom(s)`, `XFlush` — the entire EWMH implementation is raw Xlib | | **`xdnd.c`** | **33** | `XInternAtom`, `XGetWindowProperty`, `XSendEvent`, `XGetSelectionOwner`, `XFree` — 100% X11 | | **`event.c`** | **26** | `XInternAtom`, `XChangeProperty`, selection handling, `DefaultRootWindow` | | **`defaults.c`** | **20** | `XColor` parsing via `XParseColor`/`XAllocColor` for color preferences | | **`xmodifier.c`** | **11** | `XGetModifierMapping`, `XFreeModifiermap` — keyboard modifier detection | | **`misc.c`** | **8** | `XKeysymToKeycode`, `XLookupString`, `DefaultRootWindow` | | **`moveres.c`** | **6** | `XSetForeground`, `XDrawLine` — XOR rubber-band lines on root window | | **`menu.c`** | **5** | Debug logging with window IDs | | **`icon.c`** | **5** | `XWindowAttributes`, `XGetWindowAttributes` | | **`cycling.c`** | **5** | `XEvent` synthesis for switch panel | | **`usermenu.c`** | **4** | `XSendEvent`, `XStringToKeysym` — synthetic key events to client | | **`dock.c`** | **3** | `XEvent` in DND drop handling | | **`client.c`** | **3** | `XWindowChanges`, `XConfigureRequestEvent` | | **`appicon.c`** | **1** | `XClearArea` for dock icon label | --- ## 5. X11 Types Embedded in Data Structures These X11 types are used as field types in core structs, meaning the data model itself is X11-flavored: | Type | Usage count in `src/*.h` | Where | |---|---|---| | `Pixmap` | ~46 | `screen.h`, `texture.h`, `pixmap.h`, `framewin.h` — everywhere pixmaps are stored | | `GC` | ~10 | `screen.h` (7 GC fields), `texture.h` (6 GC fields), `balloon.h` | | `XColor` | ~39 (in `.c`) | `defaults.c`, `texture.c`, `resources.c` | | `Visual *` | ~5 | `framewin.h`, `screen.h` | | `Colormap` | ~5 | `framewin.h`, `screen.h`, `resources.h` | | `Atom` | ~96 (in `.c`) | `wmspec.c` (95), `xdnd.c` (19), scattered elsewhere | | `Cursor` | in `screen.h` | Cursor array in `WScreen` | --- ## Summary: Heat Map ``` Fully Partially Entirely Abstracted Abstracted X11-Raw ────────── ────────── ──────── wcore.c ██████████ stacking.c ██████████ placement.c ██████████ workspace.c ████████░░ (XINERAMA) actions.c ████████░░ (XINERAMA) window.c ██████░░░░ (XKB, SHAPE, MWM) framewin.c █████░░░░░ (XKB 22 sites, _x11_raw) event.c ████░░░░░░ (_x11_raw 16 sites, Xlib) defaults.c ████░░░░░░ (XColor) cycling.c ███░░░░░░░ (XEvent synthesis) moveres.c ███░░░░░░░ (XDrawLine) dock.c ███░░░░░░░ (XEvent, XDND) icon.c ███░░░░░░░ (XWindowAttributes, _x11_raw) menu.c ███░░░░░░░ (XKeyEvent, _x11_raw) client.c ██░░░░░░░░ (X11 event types in API) wmspec.c ░░░░░░░░░░ ██████████ (65 Xlib calls) xdnd.c ░░░░░░░░░░ ██████████ (33 Xlib calls) xmodifier.c ░░░░░░░░░░ ██████████ (11 Xlib calls) usermenu.c ░░░░░░░░░░ ████████░░ (XSendEvent) ``` **UPDATE (2026-05-26):** All three problems have been resolved: 1. **`wmspec.c`** — moved to `src/backend/x11/wmspec.c`. On Wayland, EWMH vtable slots are no-ops. 2. **`xdnd.c`** — moved to `src/backend/x11/xdnd.c`. Wayland DnD handled by wlroots. 3. **`event.c`'s `_x11_raw` escape hatch** — all 16 sites eliminated from policy code. The remaining `_x11_raw` accesses (15) are exclusively in `src/backend/` where they belong. --- # wrlib/ — Backend-Specific Branch Inventory ## File Classification ### Entirely X11-Free (pure image manipulation) These files have **zero** Xlib calls and no X11 type usage. Some `#include ` transitively through `wraster.h` but don't use it: | File | LOC | Purpose | |---|---|---| | `alpha_combine.c` | 71 | Alpha compositing | | `draw.c` | 504 | Line/pixel drawing on RImage | | `gradient.c` | 501 | Gradient rendering | | `load_gif.c` | 232 | GIF loader | | `load_jpeg.c` | 196 | JPEG loader | | `load_magick.c` | 130 | ImageMagick loader | | `load_png.c` | 220 | PNG loader | | `load_tiff.c` | 153 | TIFF loader | | `load_webp.c` | 172 | WebP loader | | `load_xpm_normalized.c` | 459 | Pure-C XPM parser (no libXpm) | | `save_jpeg.c` | 104 | JPEG saver | | `save_png.c` | 127 | PNG saver | | `save_xpm.c` | 283 | XPM saver | | **Total** | **3152** | **36% of wrlib — fully portable** | ### Gratuitous X11 Header Includes (no actual Xlib calls) These files `#include ` (pulled in transitively via `wraster.h`) but make **zero** Xlib function calls. The include is unnecessary: | File | LOC | Actual purpose | |---|---|---| | `color.c` | 130 | RColor ↔ pixel conversion (uses `RContext` fields only) | | `convolve.c` | 145 | Image convolution/blur | | `flip.c` | 163 | Image flip | | `load.c` | 395 | Format dispatch (calls `RLoadPNG`, etc.) | | `load_ppm.c` | 394 | PPM loader | | `misc.c` | 279 | Error strings, format support queries | | `raster.c` | 640 | `RCreateImage`, `RCloneImage`, `RGetSubImage`, etc. | | `rotate.c` | 434 | Image rotation | | `save.c` | 61 | Save format dispatch | | `scale.c` | 499 | Image scaling | | **Total** | **3140** | **36% of wrlib — portable code with unnecessary X11 header dep** | ### Genuinely X11-Dependent | File | LOC | Xlib calls | What it does | |---|---|---|---| | `context.c` | 772 | **44** | `RCreateContext()` — the big one. Visual selection, colormap allocation, GC creation, XShm probing. Also contains `RCreateContextWayland()` (the Wayland alternative). | | `xutil.c` | 263 | **32** | `RCreateXImage`, `RDestroyXImage`, `RGetXImage`, `RPutXImage` — XImage/XShm lifecycle | | `convert.c` | 985 | **14** | `image2TrueColor`, `image2PseudoColor`, `image2GrayScale`, `image2Bitmap` — RImage→XImage pixel conversion | | `convert_x11.c` | 96 | **6** | `x11_convert_image`, `x11_convert_image_mask` — XImage→Pixmap via `XCreatePixmap`/`XCopyArea` | | `xpixmap.c` | 183 | **13** | `RCreateImageFromXImage`, `RCreateImageFromDrawable` — Pixmap/Drawable→RImage extraction | | `load_xpm.c` | 180 | **2** | `RLoadXPM`, `RGetImageFromXPMData` — uses `libXpm` + `XParseColor` for color resolution | | **Total** | **2479** | **111** | **28% of wrlib — hard X11 dependency** | ### Wayland Backend | File | LOC | What it does | |---|---|---| | `convert_wl.c` | 58 | `wl_convert_image`, `wl_convert_image_mask` — RImage→`pixman_image_t` (cast to `Pixmap`) | --- ## 1. Compile-Time `#ifdef` Branches ### `USE_XSHM` (10 sites — 2 files) The XShm (shared memory) extension for fast image transfer to the X server: | File | Line(s) | What it guards | |---|---|---| | `context.c` | 639 | XShm version check, shared pixmap capability probe | | `xutil.c` | 34, 44, 71, 158, 195, 238, 251 | XShm include, `XShmCreateImage`, `XShmAttach`, `XShmDetach`, `XShmGetImage`, `XShmPutImage`, shared pixmap creation. The entire `RCreateXImage`/`RDestroyXImage` have dual paths (shm vs non-shm). | | `convert_x11.c` | 16, 43 | Shared pixmap fast path in `x11_convert_image` | | `xutil.h` | 24 | `R_CreateXImageMappedPixmap` prototype | ### `HAVE_LIBXMU` (2 sites) | File | Line(s) | What it guards | |---|---|---| | `context.c` | 29, 145 | `XmuLookupStandardColormap` — optional shortcut for standard colormap lookup | ### `USE_*` Image Format Guards (16 sites) All in `load.c`, `save.c`, and `imgformat.h` — these are feature toggles, not backend-specific: | Guard | Sites | Files | |---|---|---| | `USE_TIFF` | 3 | `load.c`, `imgformat.h` | | `USE_PNG` | 3 | `load.c`, `save.c`, `imgformat.h` | | `USE_JPEG` | 3 | `load.c`, `save.c`, `imgformat.h` | | `USE_GIF` | 5 | `load.c`, `load_gif.c`, `imgformat.h` | | `USE_WEBP` | 2 | `load.c`, `imgformat.h` | | `USE_MAGICK` | 3 | `load.c`, `load_magick.c`, `misc.c`, `imgformat.h` | ### Minor Guards | Guard | File | Purpose | |---|---|---| | `WRLIB_DEBUG` | `context.c` (4), `convert.c` (6) | Debug logging | | `HAVE_FLOAT_MATHFUNC` | `context.c:46` | `floorf()` availability | | `HAVE_STDNORETURN` | `load_jpeg.c:34` | C11 `_Noreturn` | | `I18N` | `misc.c:248` | Internationalization | --- ## 2. Runtime Backend Dispatch There is exactly **one** runtime dispatch point — the `convert_image` function pointer in `RContext`: ```c // wraster.h.in:210-211 int (*convert_image)(struct RContext *ctx, RImage *image, Pixmap *pixmap); int (*convert_image_mask)(struct RContext *ctx, RImage *image, Pixmap *pixmap, Pixmap *mask, int threshold); ``` Set at context creation time: - **X11 path** (`context.c:660-661`): `context->convert_image = x11_convert_image` - **Wayland path** (`context.c:768-769`): `context->convert_image = wl_convert_image` Called from `convert.c:869,882`: ```c return context->convert_image(context, image, pixmap); ``` This is the **only** abstraction seam in wrlib. Everything else is either pure image manipulation or hardcoded X11. --- ## 3. X11 Types in the Public API (`wraster.h.in`) The public header exposes X11 types directly: | API function | X11 types in signature | |---|---| | `RCreateContext()` | `Display *dpy` | | `RGetClosestXColor()` | `XColor *retColor` | | `RCreateImageFromXImage()` | `XImage *image, XImage *mask` | | `RCreateImageFromDrawable()` | `Drawable drawable, Pixmap mask` | | `RConvertImage()` | `Pixmap *pixmap` (return) | | `RConvertImageMask()` | `Pixmap *pixmap, Pixmap *mask` (return) | | `RCreateXImage()` | returns `RXImage *` (wraps `XImage`) | | `RGetXImage()` | `Drawable d` | | `RPutXImage()` | `Drawable d, GC gc` | ### `RContext` struct fields that are X11 types | Field | Type | Used by | |---|---|---| | `dpy` | `Display *` | Everything in context.c, xutil.c, xpixmap.c, convert_x11.c, load_xpm.c | | `cmap` | `Colormap` | context.c (colormap allocation), load_xpm.c (color parsing) | | `copy_gc` | `GC` | convert_x11.c (pixmap copy) | | `visual` | `Visual *` | context.c (visual selection), xutil.c (XImage creation) | | `drawable` | `Window` | convert_x11.c (XCreatePixmap root window) | | `colors` | `XColor *` | context.c (PseudoColor palette) | ### `RXImage` struct — entirely X11 ```c // wraster.h.in:265-268 XImage *image; // USE_XSHM: XShmSegmentInfo info; ``` --- ## 4. Direct Xlib Calls by File | File | Calls | Functions used | |---|---|---| | **`context.c`** | **44** | `XAllocColor`, `XQueryColors`, `XInternAtom`, `XGetRGBColormaps`, `XAllocStandardColormap`, `XFree`, `XCreateColormap`, `XGetVisualInfo`, `XCreateWindow`, `XCreateGC`, `XFreeGC`, `XDestroyWindow`, `XShmQueryVersion`, `XShmPixmapFormat`, `XSetWindowAttributes` | | **`xutil.c`** | **32** | `XCreateImage`, `XDestroyImage`, `XShmCreateImage`, `XShmAttach`, `XShmDetach`, `XShmGetImage`, `XShmPutImage`, `XSync`, `XSetErrorHandler`, `XGetGeometry`, `XGetImage`, `XPutImage`, `XCreatePixmap`, `XFreePixmap` | | **`convert.c`** | **14** | `RCreateXImage`, `RDestroyXImage` (wrlib wrappers, but they call Xlib internally) | | **`xpixmap.c`** | **13** | `XGetPixel`, `XGetGeometry`, `XGetImage`, `XDestroyImage` | | **`convert_x11.c`** | **6** | `XCreatePixmap`, `XCopyArea`, `XFreePixmap`, `XCreateGC`, `XFreeGC`, `RPutXImage` | | **`load_xpm.c`** | **2** | `XParseColor` (color name→RGB), `XpmCreateXpmImageFromData`, `XpmReadFileToXpmImage`, `XpmFreeXpmImage` (libXpm, not Xlib proper) | --- ## 5. Summary: Heat Map ``` Pure Gratuitous Genuinely Portable X11 Header X11-Dependent ────────── ────────── ──────── alpha_combine.c ██████████ draw.c ██████████ gradient.c ██████████ load_gif.c ██████████ load_jpeg.c ██████████ load_magick.c ██████████ load_png.c ██████████ load_tiff.c ██████████ load_webp.c ██████████ load_xpm_normalized.c ██████████ save_jpeg.c ██████████ save_png.c ██████████ save_xpm.c ██████████ convert_wl.c ██████████ (Wayland backend) color.c ██████████ convolve.c ██████████ flip.c ██████████ load.c ██████████ load_ppm.c ██████████ misc.c ██████████ raster.c ██████████ rotate.c ██████████ save.c ██████████ scale.c ██████████ load_xpm.c ████████░░ (libXpm + XParseColor) convert.c ██████████ (RXImage converters) convert_x11.c ██████████ (X11 convert backend) xpixmap.c ██████████ (Drawable→RImage) xutil.c ██████████ (XImage/XShm lifecycle) context.c ██████████ (RContext creation, 44 calls) ``` **By the numbers:** | Category | Files | LOC | % of wrlib | |---|---|---|---| | Fully portable | 14 | 3210 | 36% | | Portable but needlessly includes `X11/Xlib.h` | 10 | 3140 | 36% | | Genuinely X11-dependent | 6 | 2479 | 28% | **The Wayland story in wrlib is already partially told.** The `convert_image` function pointer dispatch and `RCreateContextWayland()` exist, and `convert_wl.c` provides the pixman-based conversion path. What remains X11-bound: 1. **`context.c`** — `RCreateContext()` (525 lines of X11 visual/colormap setup) vs `RCreateContextWayland()` (45 lines). The X11 path is 10× larger but they're already separate functions. 2. **`xutil.c` + `xpixmap.c`** — the entire `RXImage` abstraction is X11-only. On Wayland, these are dead code (the `wl_convert_image` path never touches `RXImage`). 3. **`convert.c`** — the `image2TrueColor`/`image2PseudoColor`/etc. converters produce `RXImage` (X11). On Wayland, they're bypassed entirely by the function pointer dispatch. 4. **`load_xpm.c`** — uses `libXpm` and `XParseColor`. The alternative `load_xpm_normalized.c` is a pure-C XPM parser that doesn't need X11 (already exists as the Wayland-compatible path). 5. **The public API** — `wraster.h` exposes `Display *`, `Pixmap`, `Drawable`, `GC`, `XImage`, `XColor` in function signatures. On Wayland, `Pixmap` is reused as a `uintptr_t` cast of `pixman_image_t *` — a type pun, not a real abstraction. --- # wmlib/ — Backend-Specific Branch Inventory wmlib is tiny — 481 lines of C across 4 files, plus 2 headers (238 lines). It's a client-side helper library that lets external applications communicate with the WindowMaker WM via X11 properties and client messages. **It is 100% X11.** ## File Map | File | LOC | Purpose | Xlib calls | |---|---|---|---| | `command.c` | 75 | Send WM commands (hide app, hide others, set GNUstep attributes) via `XSendEvent` + `XChangeProperty` | **5** | | `event.c` | 87 | Process incoming `_WINDOWMAKER_MENU` client messages from the WM | **1** | | `menu.c` | 239 | Build menu tree in memory, serialize to X text property via `XSetTextProperty` | **3** | | `app.c` | 80 | Application context (`WMAppContext`) — stores `Display *`, main window, window list | **0** (stores X11 types, doesn't call Xlib) | | `WMaker.h` | 162 | Public API header | — | | `app.h` | 41 | Private `wmAppContext` struct | — | | `menu.h` | 76 | Private `wmMenu`/`wmMenuEntry` structs | — | ## 1. Compile-Time `#ifdef` Branches **None.** Zero `#ifdef` guards of any kind (beyond header include guards and `__cplusplus`). No conditional compilation, no feature toggles, no backend switches. ## 2. Runtime Backend Dispatch **None.** No function pointers, no vtables, no `is_wayland` checks. ## 3. X11 Types in the Public API (`WMaker.h`) Every public function takes X11 types: | Function | X11 types | |---|---| | `WMAppCreateWithMain()` | `Display *display`, `Window main_window` | | `WMAppCreate()` | `Display *display` | | `WMAppAddWindow()` | `Window window` | | `WMProcessEvent()` | `XEvent *event` | | `WMSetWindowAttributes()` | `Display *dpy`, `Window window` | | `WMMenuAction` callback | `Time timestamp` | The `GNUstepWMAttributes` struct contains `Pixmap` fields. ## 4. X11 Types in Private Structs ### `wmAppContext` (`app.h`) ```c Display *dpy; Window main_window; Window *windows; ``` ### `wmMenuEntry` / `wmMenu` (`menu.h`) No X11 types — pure C data structures (strings, tags, linked list pointers). The X11 dependency comes only at serialization time. ## 5. Direct Xlib Calls — Complete List There are only **9** Xlib calls in the entire library: | File | Line | Call | Purpose | |---|---|---|---| | `command.c:31` | `XInternAtom(dpy, "_WINDOWMAKER_WM_FUNCTION", False)` | Get the WM command atom | | `command.c:47` | `XSendEvent(...)` | Send "hide application" command to WM | | `command.c:62` | `XSendEvent(...)` | Send "hide others" command to WM | | `command.c:70` | `XInternAtom(dpy, "_GNUSTEP_WM_ATTR", False)` | Get the GNUstep attributes atom | | `command.c:71` | `XChangeProperty(...)` | Set GNUstep WM attributes on a window | | `event.c:76` | `XInternAtom(app->dpy, "_WINDOWMAKER_MENU", False)` | Get the menu event atom | | `menu.c:199` | `XInternAtom(dpy, WMMENU_PROPNAME, False)` | Get the menu property atom | | `menu.c:226` | `XStringListToTextProperty(...)` | Serialize menu string list | | `menu.c:232` | `XSetTextProperty(...)` | Write serialized menu to window property | Plus one `XFree()` call (`menu.c:234`). ## 6. Communication Protocol The library implements a simple IPC protocol built entirely on X11 mechanisms: - **App → WM**: `XSendEvent` with `ClientMessage` type `_WINDOWMAKER_WM_FUNCTION` to the root window - **App → WM (menus)**: `XSetTextProperty` writes a serialized menu tree to `_WINDOWMAKER_MENU` on the app's main window - **WM → App**: `ClientMessage` events with type `_WINDOWMAKER_MENU` carrying a menu item tag ## Summary ``` Pure X11-Dependent Portable ────────── ────────── app.c (data only) ████░░░░░░ (stores Display*/Window) menu.c (data + serial) ░░░░░░░░░░ ██████████ (XSetTextProperty) command.c ░░░░░░░░░░ ██████████ (XSendEvent, XChangeProperty) event.c ░░░░░░░░░░ ██████████ (XInternAtom, ClientMessage) WMaker.h ░░░░░░░░░░ ██████████ (Display, Window, Pixmap, XEvent, Time) ``` **wmlib is entirely X11.** There is no abstraction layer, no backend dispatch, no Wayland path, and no compile-time guards. The entire library is a thin wrapper around X11 client messages and properties for the GNUstep/WindowMaker protocol. For a Wayland port, wmlib would either need to be: 1. **Replaced** with a Wayland-native protocol (e.g., a custom `wl_protocol` extension), or 2. **Kept as-is** for XWayland clients only, with a parallel Wayland-native equivalent, or 3. **Dropped** — its functionality (app hide/show, WM-managed menus) could be subsumed into the compositor's own protocol. Given its size (481 lines of C, 9 Xlib calls), any of these options is straightforward. --- # util/ — Backend-Specific Branch Inventory util/ contains **15 standalone CLI programs** (7336 LOC). They range from fully X11-dependent GUI apps to pure file-manipulation tools with zero display-system dependency. ## File Classification ### Entirely X11-Free (pure file/text manipulation) | File | LOC | Purpose | X11 calls | |---|---|---|---| | `convertfonts.c` | 167 | Convert old WM font config to new format | **0** | | `fontconv.c` | 200 | XLFD font name conversion helpers | **0** | | `wdread.c` | 110 | Read a key from the WM defaults database | **0** | | `wdwrite.c` | 114 | Write a key to the WM defaults database | **0** | | `getstyle.c` | 418 | Export style/theme from WM defaults to file | **0** | | `geticonset.c` | 124 | Export icon set from WM defaults to file | **0** | | `seticons.c` | 129 | Import icon set into WM defaults | **0** | | `wmmenugen.c` | 393 | Generate WM menu from `.desktop` files (PropList output) | **0** | | `wmmenugen_misc.c` | 172 | Menu generator helpers (terminal detection) | **0** | | `wmmenugen_parse_xdg.c` | 737 | XDG `.desktop` file parser | **0** | | `wmmenugen_parse_wmconfig.c` | 297 | wmconfig file parser | **0** | | `wmgenmenu.c` | 519 | Another menu generator (hardcoded menu templates) | **0**¹ | | **Total** | **3380** | | | ¹ `wmgenmenu.c` has the string "XTerm" as a menu item label — no actual Xlib call. ### X11-Dependent GUI Applications | File | LOC | Xlib calls | Purpose | |---|---|---|---| | `wmiv.c` + `wmiv.h` | 1020 + 1279 | **60** | Image viewer — full X11 window, event loop, keyboard handling | | `wmsetbg.c` | 1444 | **53** | Set desktop background — pixmap creation, root window manipulation | | `wmagnify.c` | 491 | **20** | Screen magnifier — `XGetImage` from root, WINGs GUI | | `wxpaste.c` | 232 | **18** | Paste from X selection/clipboard | | `wxcopy.c` | 246 | **12** | Copy to X cut buffers/selection | | `setstyle.c` | 523 | **10** | Import style into WM defaults + send reload command via `XSendEvent` | | **Total** | **3956** (excl. `wmiv.h`) | **173** | | --- ## 1. Compile-Time `#ifdef` Branches ### Backend/Extension Guards | Guard | File | Sites | What it guards | |---|---|---|---| | `USE_XINERAMA` | `wmsetbg.c` | **7** | Xinerama include, `XineramaQueryScreens`, per-head background stretching, `--xinerama` CLI flag | | `USE_XPM` | `wmiv.c` | **4** | XPM icon loading for the image viewer window | | `HAVE_EXIF` | `wmiv.c` | **3** | EXIF orientation auto-rotation | | `HAVE_PTHREAD` | `wmiv.c` | **5** | Background image preloading thread | ### Portability Guards (not backend-specific) | Guard | Files | Sites | What it guards | |---|---|---|---| | `__GLIBC__` | 8 files | 8 | `#define _GNU_SOURCE` | | `HAVE_STDNORETURN` | 7 files | 7 | C11 `_Noreturn` | | `_GNU_SOURCE` | `wmiv.c` | 1 | GNU extensions | | `HAVE_SYS_SELECT_H` | `wxpaste.c` | 1 | `` include | | `HAVE_LIBINTL_H` + `I18N` | `wmgenmenu.c` | 1 | Gettext | | `PATH_MAX` | `getstyle.c` | 1 | Fallback definition | | `DEBUG` | `wmsetbg.c` (6), `wmmenugen.c` (2), `wmmenugen_parse_*.c` (3) | 11 | Debug logging | --- ## 2. Runtime Backend Dispatch ### `_x11_raw` Escape Hatch (1 site) | File | Line | What it does | |---|---|---| | `wmagnify.c` | 314 | `XEvent *xev = (XEvent *)event->_x11_raw` — casts the WINGs event to get the raw `XKeyEvent` for `XLookupString` | No other runtime backend checks (`is_wayland`, `dpy == NULL`, etc.) in any util file. --- ## 3. X11 Types in Function Signatures / Structs ### `wmsetbg.c` ```c Display *dpy; // global Pixmap texture->pixmap; // background storage XColor color; // color parsing XRectangle head[]; // Xinerama head geometry ``` ### `wmiv.c` ```c Display *dpy; // global Window win; // viewer window XTextProperty title_property; // window title XClassHint, XSizeHints, XWMHints // window manager hints XEvent e; // event loop XKeyEvent event; // synthetic key events ``` ### `wmagnify.c` ```c Display *dpy, *vdpy; // two display connections (magnify from one, draw to other) XImage *image; // captured screen region XRectangle rects[]; // magnified pixel rectangles GC gc; // drawing context ``` ### `wxcopy.c` / `wxpaste.c` ```c Display *dpy; // global Atom selatom, clipatom; // selection atoms XEvent ev; // selection events Window win; // hidden window for selection protocol ``` ### `setstyle.c` ```c Display *dpy; // opened only to send reload command XEvent ev; // client message XColor color1, color2; // color validation ``` --- ## 4. Direct Xlib Calls — Per File ### `wmiv.c` (60 calls) — Image Viewer Full X11 application: window creation, event loop, pixmap management. | Category | Calls | |---|---| | Window lifecycle | `XOpenDisplay`, `XCreateSimpleWindow`, `XMapWindow`, `XCloseDisplay`, `XSelectInput` | | Drawing | `XCopyArea` (×6), `XClearWindow` (×3), `XResizeWindow` (×4), `XFreePixmap` (×3) | | Window properties | `XSetWMProperties`, `XSetWMName`, `XSetWMProtocols`, `XStringListToTextProperty`, `XAllocClassHint`, `XAllocSizeHints`, `XAllocWMHints` | | Event loop | `XNextEvent`, `XSendEvent`, `XFlush`, `XSync` | | EWMH | `XInternAtom` (×2 — `_NET_WM_STATE`, `_NET_WM_STATE_FULLSCREEN`) | | Input | `XKeysymToKeycode`, `XGetWindowAttributes` | ### `wmsetbg.c` (53 calls) — Background Setter Root window pixmap manipulation, color allocation, property management. | Category | Calls | |---|---| | Color | `XParseColor` (×7), `XAllocColor` (×2), `XFreeColors` | | Pixmap | `XCreatePixmap` (×3), `XFreePixmap` (×2), `XCopyArea` (×3), `XSetForeground` (×2), `XFillRectangle` (×2) | | Root window | `XSetWindowBackground`, `XSetWindowBackgroundPixmap`, `XClearWindow` | | Properties | `XInternAtom`, `XGetWindowProperty`, `XChangeProperty`, `XDeleteProperty` — `_XROOTPMAP_ID` management | | Connection | `XOpenDisplay` (×2 — main + `RetainPermanent` trick), `XCloseDisplay`, `XSetCloseDownMode`, `XSync`, `XFlush`, `XSynchronize` | | Server grab | `XGrabServer`, `XUngrabServer` | | Error handling | `XSetErrorHandler`, `XKillClient` | | Xinerama | `XineramaIsActive`, `XineramaQueryScreens`, `XFree` | ### `wmagnify.c` (20 calls) — Screen Magnifier Captures screen pixels and renders magnified view via WINGs. | Category | Calls | |---|---| | Capture | `XGetImage`, `XDestroyImage`, `XGetPixel`, `XQueryPointer` | | Drawing | `XCreateGC`, `XSetForeground`, `XFillRectangles` (×3) | | Connection | `XOpenDisplay` (×2 — main + virtual display), `XMaxRequestSize` | | Input | `XLookupString` (via `_x11_raw`) | ### `wxpaste.c` (18 calls) — Clipboard Paste X11 selection protocol client. | Category | Calls | |---|---| | Selection | `XConvertSelection`, `XGetWindowProperty`, `XFetchBuffer` | | Connection | `XOpenDisplay`, `XCloseDisplay`, `XDisplayName` | | Window | `XCreateSimpleWindow`, `XSelectInput`, `XStoreName` | | Events | `XNextEvent`, `XPending`, `XInternAtom` (×2) | ### `wxcopy.c` (12 calls) — Clipboard Copy X11 cut buffer / selection protocol. | Category | Calls | |---|---| | Buffers | `XStoreBuffer`, `XRotateBuffers`, `XListProperties`, `XSetSelectionOwner` | | Connection | `XOpenDisplay`, `XCloseDisplay`, `XDisplayName`, `XSetErrorHandler`, `XFlush` | | Properties | `XFree` | ### `setstyle.c` (10 calls) — Style Importer Mostly file manipulation; X11 used only for color validation and sending a reload command. | Category | Calls | |---|---| | Color validation | `XParseColor` (×2) — validates color names in the style | | WM command | `XOpenDisplay`, `XInternAtom` (`_WINDOWMAKER_COMMAND`), `XSendEvent`, `XFlush` | --- ## 5. Summary: Heat Map ``` Pure X11-Dependent Portable ────────── ────────── convertfonts.c ██████████ fontconv.c ██████████ wdread.c ██████████ wdwrite.c ██████████ getstyle.c ██████████ geticonset.c ██████████ seticons.c ██████████ wmmenugen.c ██████████ wmmenugen_misc.c ██████████ wmmenugen_parse_xdg.c ██████████ wmmenugen_parse_wmc.. ██████████ wmgenmenu.c ██████████ setstyle.c ██████░░░░ (XParseColor, XSendEvent for reload) wxcopy.c ░░░░░░░░░░ ██████████ (X cut buffers/selection) wxpaste.c ░░░░░░░░░░ ██████████ (X selection protocol) wmagnify.c ░░░░░░░░░░ ██████████ (XGetImage, WINGs GUI) wmsetbg.c ░░░░░░░░░░ ██████████ (root pixmap, 53 Xlib calls) wmiv.c ░░░░░░░░░░ ██████████ (full X11 app, 60 Xlib calls) ``` **By the numbers:** | Category | Files | LOC | % of util | |---|---|---|---| | Fully portable (no X11) | 12 | 3380 | 46% | | Mostly portable (minor X11 for WM command) | 1 (`setstyle.c`) | 523 | 7% | | Entirely X11-dependent | 5 | 3433 | 47% | **The five X11-dependent utilities are all standalone GUI programs.** For a Wayland port, each would need either: 1. **`wmsetbg.c`** — Wayland compositors typically own the background; this tool would become a protocol message to the compositor rather than root window pixmap manipulation. 2. **`wmiv.c`** — Full rewrite against Wayland client APIs (or just use WINGs, which already has a Wayland view backend). 3. **`wmagnify.c`** — Already uses WINGs widgets; the X11 dependency is `XGetImage` for screen capture (no Wayland equivalent without a screencopy protocol). 4. **`wxcopy.c` / `wxpaste.c`** — X11 selection protocol → Wayland `wl_data_device` / `zwp_primary_selection_v1`. Completely different protocol, complete rewrite. The 12 portable utilities (defaults DB tools, menu generators, font converters) work on any platform unchanged. --- # WINGs/ — Backend-Specific Branch Inventory WINGs is the largest component at ~40k LOC across 62 `.c` files. It has a well-developed **five-vtable backend abstraction** but significant X11 leakage remains in widget code. ## Architecture: The Five Backend Vtables WINGs uses runtime vtable dispatch set in `widgets.c:777-812` based on `WMAKER_USE_WAYLAND` env var: ```c scrPtr->viewBackend = wayland ? &W_ViewBackendWL : &W_ViewBackendX11; scrPtr->eventBackend = wayland ? &W_EventBackendWL : &W_EventBackendX11; scrPtr->renderBackend = wayland ? &W_RenderBackendWL : &W_RenderBackendX11; scrPtr->fontBackend = wayland ? &W_FontBackendWL : &W_FontBackendX11; scrPtr->colorBackend = wayland ? &W_ColorBackendWL : &W_ColorBackendX11; ``` | Vtable | Slots | X11 impl | Wayland impl | |---|---|---|---| | `W_ViewBackend` | 19 (realize, map, unmap, move, resize, raise, lower, reparent, destroy, set_background_color, set_cursor, redisplay, selection, flush…) | `wview_x11.c` (238 LOC) | `wview_wl.c` (368 LOC) | | `W_EventBackend` | 5 (screen_init, screen_fini, fetch, check_mask, post_dispatch) | `wevent_x11.c` (354 LOC) | `wevent_wl.c` (235 LOC) | | `W_RenderBackend` | 12 (pixmap_create, pixmap_free, pixmap_copy, draw_line, draw_rect, fill_rect, fill_stippled, composite_pixmap, fill_polygon, fill_arc, create_disabled_mask) | `wrender_x11.c` (175 LOC) | `wrender_wl.c` (279 LOC) | | `W_FontBackend` | 8 (screen_init, screen_fini, create, destroy, measure, draw_string, draw_image_string, height) | `wfont_x11.c` (212 LOC) | `wfont_wl.c` (235 LOC) | | `W_ColorBackend` | 5 (screen_init, screen_fini, alloc_color, find_close_color, free_color, parse_named) | `wcolor_x11.c` (130 LOC) | `wcolor_wl.c` (106 LOC) | **Backend split files total**: X11 = 1109 LOC, Wayland = 1223 LOC. --- ## File Classification ### Fully Portable (zero Xlib calls, zero X11 types) | File | LOC | Purpose | |---|---|---| | `proplist.c` | 1878 | NeXTSTEP property list parser/serializer | | `wfilepanel.c` | 896 | File open/save panel | | `wpanel.c` | 847 | Alert/input panels | | `wscroller.c` | 830 | Scrollbar widget | | `wfontpanel.c` | 825 | Font chooser panel | | `wbutton.c` | 755 | Button widget | | `bagtree.c` | 745 | Balanced tree data structure | | `userdefaults.c` | 641 | User defaults system | | `handlers.c` | 566 | Timer/idle handler dispatch | | `wscrollview.c` | 561 | Scroll container widget | | `notification.c` | 482 | Notification center | | `string.c` | 425 | String utilities | | `hashtable.c` | 422 | Hash table | | `array.c` | 363 | Dynamic array | | `wfont.c` | 329 | Font dispatch (delegates to fontBackend) | | `data.c` | 289 | WMData wrapper | | `tree.c` | 255 | Tree data structure | | `wbox.c` | 247 | Box layout widget | | `wprogressindicator.c` | 243 | Progress bar widget | | `wframe.c` | 230 | Group box widget | | `wmenuitem.c` | 226 | Menu item data | | `memory.c` | 223 | Memory allocation wrappers | | `wapplication.c` | 216 | Application context | | `wlabel.c` | 214 | Label widget | | `wcolor.c` | 187 | Color dispatch (delegates to colorBackend) | | `configuration.c` | 132 | Configuration file handling | | `usleep.c` | 26 | Microsecond sleep | | `wutil.c` | 24 | Misc utilities | | **+ Wayland backends** | | | | `wview_wl.c` | 368 | Wayland view backend | | `wevent_wl.c` | 235 | Wayland event backend | | `wfont_wl.c` | 235 | Wayland font backend | | `wrender_wl.c` | 279 | Wayland render backend | | `wcolor_wl.c` | 106 | Wayland color backend | | **Total** | **12,474** | **31% of WINGs** | ### X11 Backend Split Files (properly abstracted) | File | LOC | Xlib calls | Purpose | |---|---|---|---| | `wview_x11.c` | 238 | 29 | X11 view lifecycle (XCreateWindow, XMapWindow, etc.) | | `wrender_x11.c` | 175 | 24 | X11 drawing (XCreatePixmap, XFillRectangle, etc.) | | `wevent_x11.c` | 354 | 20 | X11 event fetching (XNextEvent, XPending, etc.) | | `wcolor_x11.c` | 130 | 11 | X11 color allocation (XAllocColor, etc.) | | `wfont_x11.c` | 212 | 2 | X11 font rendering (Xft) | | **Total** | **1109** | **86** | **3% of WINGs — properly isolated** | ### Widget Files with Xlib Leakage (should be backend-neutral but aren't) | File | LOC | Xlib calls | What's leaking | |---|---|---|---| | **`wcolorpanel.c`** | 3556 | **89** | `XCreatePixmap`, `XCopyArea`, `XFillRectangle`, `XFreePixmap`, `XGetImage`, `XGetPixel`, `XPutPixel`, `XPutImage`, `XSubImage`, `XDestroyImage`, `XImage`, `XColor`, `XGrabPointer`, `XUngrabPointer`, `XQueryPointer`, `XSetWindowBackgroundPixmap`, `XRecolorCursor`, `XSetForeground`, `XSetClipMask`, `XSetClipOrigin`, `XCreatePixmapCursor`, `XFreeCursor`, `XCreatePixmapFromBitmapData`, `XFlush`, `XPending`, `XPeekEvent`, `XNextEvent`, `XCheckTypedEvent` | | **`dragsource.c`** | 1179 | **45** | XDND protocol: `XSendEvent`, `XGetWindowProperty`, `XChangeProperty`, `XSetSelectionOwner`, `XConvertSelection`, `XGrabPointer`, `XUngrabPointer`, `XInternAtom`, `XGetInputFocus`, `XQueryTree`, `XTranslateCoordinates`, shape extension | | **`wwindow.c`** | 712 | **41** | Window properties: `XSetWMName`, `XSetWMProtocols`, `XGetWMProtocols`, `XSetWMHints`, `XGetWMHints`, `XSetWMNormalHints`, `XSetClassHint`, `XSetTransientForHint`, `XChangeProperty`, `XWithdrawWindow`, `XAllocSizeHints`, `XAllocWMHints`, `XAllocClassHint`, `XmbTextListToTextProperty`, `XStoreName`, `XSetIconName`, `XFree` | | **`winputmethod.c`** | 243 | **40** | XIM/XIC: `XOpenIM`, `XCreateIC`, `XDestroyIC`, `XSetICValues`, `XGetICValues`, `XSetICFocus`, `XUnsetICFocus`, `XSetIMValues`, `XGetIMValues`, `XRegisterIMInstantiateCallback`, `XUnregisterIMInstantiateCallback`, `XVaCreateNestedList`, `XSetInputFocus`, `XLookupString`, `XSelectInput`, `XDisplayKeycodes`, `XGetKeyboardMapping`, `XFree` | | **`dragdestination.c`** | 999 | **37** | XDND protocol: `XSendEvent`, `XGetWindowProperty`, `XChangeProperty`, `XConvertSelection`, `XInternAtom`, `XTranslateCoordinates` | | **`widgets.c`** | 1137 | **35** | Screen init: `XOpenDisplay`, `XCreateGC` (×8), `XCreateBitmapFromData`, `XCreatePixmap`, `XCreateFontCursor`, `XCreatePixmapCursor`, `XSetForeground`, `XFillRectangle`, `XFreePixmap`, `XInternAtom(s)`, `XListProperties`, `XStoreBuffer`, `XGetModifierMapping`, `XFreeModifiermap`, `XKeysymToKeycode`, `XDisplayName`, `XColor` | | **`wballoon.c`** | 476 | **28** | Tooltip drawing: `XFillArc`, `XFillRectangle`, `XFillPolygon`, `XSetForeground`, `XCreateGC`, `XTranslateCoordinates`, shape extension | | **`wtext.c`** | 3998 | **23** | Rich text: `XBell`, `XFetchBuffer`, `XStoreBuffer`, `XFree`, `XUngrabPointer`, `XGrabPointer`, `XFlush`, `XInternAtom`, `XCreateGC`, `XCreateBitmapFromData`, `XChangeWindowAttributes`, `XSetWindowAttributes`, `XMapWindow`, `XRectangle`, `XEvent` | | **`selection.c`** | 392 | **21** | X selection protocol: `XConvertSelection`, `XGetWindowProperty`, `XChangeProperty`, `XSendEvent`, `XSetSelectionOwner`, `XGetSelectionOwner`, `XDeleteProperty`, `XInternAtom`, `XFree` | | **`dragcommon.c`** | 259 | **16** | XDND shared: `XInternAtom`, `XGetWindowProperty`, `XChangeProperty`, `XFree` | | **`wappresource.c`** | 148 | **15** | App icon: `XGetWindowProperty`, `XFree`, `XInternAtom` | | **`wtextfield.c`** | 1579 | **10** | Text input: `XBell`, `XFetchBuffer`, `XStoreBuffer`, `XFree`, `XUngrabPointer`, `XGrabPointer`, `XFlush`, `XInternAtom`, `XDrawRectangle` | | **`wpopupbutton.c`** | 697 | **7** | Popup: `XGrabPointer`, `XUngrabPointer`, `XFlush` | | **`wruler.c`** | 526 | **3** | Ruler: `XRectangle` type usage | | **`wmisc.c`** | 351 | **2** | Misc: `XTranslateCoordinates` | | **Total** | **16,252** | **412** | **41% of WINGs** | ### Utility Files (WUtil sub-library, no X11) | File | LOC | Purpose | |---|---|---| | `menuparser.c` | 652 | Menu file parser | | `menuparser_macros.c` | 723 | Menu parser macro expansion | | `findfile.c` | 523 | File path search | | `error.c` | 147 | Error/warning output | | `misc.c` | 45 | Misc WUtil helpers | | **Total** | **2090** | **5% of WINGs** | --- ## 1. Compile-Time `#ifdef` Branches ### Backend/Extension Guards | Guard | File(s) | Sites | What it guards | |---|---|---|---| | `USE_XSHAPE` | `dragsource.c` (2), `wballoon.c` (2), `wcolorpanel.c` (6) | **10** | Shape extension for DND drag icons, balloon tooltips, color picker magnifier | | `USE_PANGO` | `wfont_x11.c` | **9** | Pango text rendering in X11 font backend | | `XDND_DEBUG` | `dragsource.c` (4), `dragdestination.c` (3), `dragcommon.c` (3) | **10** | DND protocol debug logging | | `HAVE_XINTERNATOMS` | `widgets.c` | **1** | Batch atom intern optimization | | `X_HAVE_UTF8_STRING` | `winputmethod.c` | **1** | `Xutf8LookupString` availability | | `DOUBLE_BUFFER` | `wmisc.c` (3), `wscroller.c` (8) | **11** | Double-buffered drawing | ### Portability Guards (not backend-specific) | Guard | File(s) | Sites | What it guards | |---|---|---|---| | `HAVE_SYSLOG` / `HAVE_SYSLOG_H` | `error.c`, `misc.c` | 6 | Syslog logging | | `HAVE_INOTIFY` | `userdefaults.c` | 4 | File change monitoring | | `USE_BOEHM_GC` | `memory.c` | 6 | Boehm garbage collector | | `HAVE_SYS_SELECT_H` | `handlers.c` | 1 | `` | | `HAVE_POLL` | `handlers.c` | 1 | `poll()` vs `select()` | | `HAVE_MKSTEMP` | `proplist.c` | 2 | Secure temp file creation | | `HAVE_STDNORETURN` | `memory.c` | 1 | C11 `_Noreturn` | | `HAVE_STRLCAT` / `HAVE_STRLCPY` | `string.c` | 2 | BSD string functions | | `HAVE_BSD_STRING_H` | `string.c` | 1 | BSD string header | | `HAVE_SYSCONF` | `error.c` | 1 | `sysconf()` | | `HAVE_SELECT` | `handlers.c` | 1 | `select()` availability | | `STRICT_NEXT_BEHAVIOUR` | `wscroller.c` (3), `wslider.c` (1) | 4 | NeXTSTEP-strict scrollbar behavior | | `I18N` | `wapplication.c` | 1 | Internationalization | | `DEBUG` | `menuparser_macros.c` (4), various | ~6 | Debug logging | | `VERBOSE` | `wfilepanel.c` (2), `memory.c` (3) | 5 | Verbose logging | --- ## 2. X11 Types in Core Structs (`WINGsP.h.in`) ### `W_Screen` (the WINGs screen object) | Field | Type | Count | |---|---|---| | `display` | `Display *` | 1 | | `rootWin` | `Window` | 1 | | `applicationIconWindow`, `groupLeader` | `Window` | 2 | | `stipple` | `Pixmap` | 1 | | GCs | `GC` | **8** (`stippleGC`, `copyGC`, `clipGC`, `monoGC`, `xorGC`, `ixorGC`, `drawStringGC`, `drawImStringGC`) | | `colormap` | `Colormap` | 1 | | `visual` | `Visual *` | 1 | | Cursors | `Cursor` | (in `defaultCursor`, `textCursor`, `invisibleCursor`) | | Atoms | `Atom` | (multiple protocol atoms) | ### `W_DragSourceInfo` / `W_DragDestinationInfo` | Field | Type | |---|---| | `sourceAction`, `destinationAction` | `Atom` | --- ## 3. Direct Xlib Calls — Summary by Category ### In properly-split `_x11` files (86 calls — correctly isolated) | File | Calls | Category | |---|---|---| | `wview_x11.c` | 29 | Window create/map/unmap/move/resize/destroy | | `wrender_x11.c` | 24 | Pixmap create/free/copy, drawing primitives | | `wevent_x11.c` | 20 | Event fetch, pending check, XSync | | `wcolor_x11.c` | 11 | Color allocation | | `wfont_x11.c` | 2 | Xft font rendering | ### In non-split widget files (412 calls — leaking) | Category | Calls | Files | |---|---|---| | **DND (XDND protocol)** | **98** | `dragsource.c` (45), `dragdestination.c` (37), `dragcommon.c` (16) | | **Color picker** | **89** | `wcolorpanel.c` — pixmap manipulation, image capture, pointer grabs | | **Window properties** | **41** | `wwindow.c` — ICCCM hints, WM protocols | | **Input methods** | **40** | `winputmethod.c` — XIM/XIC lifecycle | | **Screen init** | **35** | `widgets.c` — GC creation, cursor creation, modifier mapping | | **Tooltips** | **28** | `wballoon.c` — shaped balloon drawing | | **Rich text** | **23** | `wtext.c` — clipboard, grabs | | **Selection/clipboard** | **21** | `selection.c` — X selection protocol | | **App resources** | **15** | `wappresource.c` — icon property reading | | **Text field** | **10** | `wtextfield.c` — clipboard, grabs | | **Popup button** | **7** | `wpopupbutton.c` — pointer grabs | | **Ruler** | **3** | `wruler.c` — `XRectangle` type | | **Misc** | **2** | `wmisc.c` — coordinate translation | --- ## 4. Summary: Heat Map ``` Fully Backend-Split Xlib Portable (vtable) Leaking ────────── ────────── ──────── WUtil layer: proplist.c ██████████ bagtree/array/hash/.. ██████████ handlers.c ██████████ menuparser*.c ██████████ findfile/string/etc ██████████ Backend split files: wview_x11/wl.c ██████████ wevent_x11/wl.c ██████████ wrender_x11/wl.c ██████████ wfont_x11/wl.c ██████████ wcolor_x11/wl.c ██████████ Clean widgets (0 Xlib): wbutton.c ██████████ wscroller.c ██████████ wscrollview.c ██████████ wlist.c ██████████ wbrowser.c ██████████ wslider.c ██████████ wsplitview.c ██████████ wtabview.c ██████████ wfilepanel.c ██████████ wfontpanel.c ██████████ wpanel.c ██████████ wframe.c ██████████ wlabel.c ██████████ wbox.c ██████████ wprogressindicator.c ██████████ wcolorwell.c ██████████ wmenuitem.c ██████████ Leaking widgets: wcolorpanel.c ██████████ (89 calls) dragsource.c ██████████ (45 calls) wwindow.c ██████████ (41 calls) winputmethod.c ██████████ (40 calls) dragdestination.c ██████████ (37 calls) widgets.c ██████████ (35 calls) wballoon.c ██████████ (28 calls) wtext.c ████████░░ (23 calls) selection.c ████████░░ (21 calls) dragcommon.c ██████░░░░ (16 calls) wappresource.c ████░░░░░░ (15 calls) wtextfield.c ███░░░░░░░ (10 calls) wpopupbutton.c ██░░░░░░░░ (7 calls) wruler.c █░░░░░░░░░ (3 calls) wmisc.c █░░░░░░░░░ (2 calls) ``` **By the numbers:** | Category | Files | LOC | Xlib calls | % of WINGs | |---|---|---|---|---| | Fully portable (WUtil + clean widgets + Wayland backends) | 34 | 14,564 | 0 | 36% | | Backend-split `_x11` files (properly isolated) | 5 | 1,109 | 86 | 3% | | Leaking widget files (X11 in non-split code) | 15 | 16,252 | 412 | 41% | | WUtil utility code (no X11) | 8 | 2,090 | 0 | 5% | | Remaining clean widgets (0 calls but use X11 types transitively) | ~6k | | | 15% | **The three biggest remaining problems for Wayland parity:** 1. **DND subsystem** (`dragsource.c` + `dragdestination.c` + `dragcommon.c` = 2437 LOC, 98 Xlib calls) — the entire XDND protocol implementation. Wayland has `wl_data_device`. Needs a sixth vtable or full replacement. 2. **`wcolorpanel.c`** (3556 LOC, 89 Xlib calls) — the color picker does raw pixmap manipulation, screen capture (`XGetImage`), pointer grabs, and cursor recoloring. Needs to route through `renderBackend` and `viewBackend`. 3. **`wwindow.c`** + **`winputmethod.c`** + **`widgets.c`** (2092 LOC, 116 Xlib calls combined) — ICCCM window properties, XIM/XIC input method lifecycle, and screen initialization. These are protocol-level concerns that need backend abstraction (ICCCM doesn't exist on Wayland; input methods use `zwp_text_input_v3`). --- # WPrefs.app/ — Backend-Specific Branch Inventory WPrefs.app is the WindowMaker preferences editor — a WINGs-based GUI application with 15,540 LOC across 21 `.c` files. Each file is a preference panel. ## File Map | File | LOC | Purpose | |---|---|---| | `Appearance.c` | 2356 | Titlebar/menu texture and color configuration | | `Menu.c` | 1825 | Menu structure editor | | `TexturePanel.c` | 1549 | Texture creation/editing dialog | | `editmenu.c` | 1361 | Drag-and-drop menu editor widget | | `WPrefs.c` | 927 | Main window, panel switching, save/revert | | `MouseSettings.c` | 798 | Mouse speed, button mapping, modifier keys | | `FontSimple.c` | 751 | Font configuration for titlebars, menus, etc. | | `KeyboardShortcuts.c` | 695 | Keyboard shortcut binding editor | | `WindowHandling.c` | 612 | Window placement, focus, maximize behavior | | `Icons.c` | 485 | Icon size, position, animation | | `HotCornerShortcuts.c` | 465 | Screen corner actions | | `Configurations.c` | 445 | Misc settings (icon size, edge resistance, etc.) | | `Expert.c` | 363 | Expert-level toggle options | | `Focus.c` | 362 | Focus mode, auto-raise delay | | `Preferences.c` | 359 | Size/position display, dialog behavior | | `Docks.c` | 335 | Dock/clip behavior | | `Paths.c` | 328 | Pixmap/icon search paths | | `xmodifier.c` | 311 | Keyboard modifier detection (from XEmacs) | | `Workspace.c` | 240 | Workspace naming | | `MenuPreferences.c` | 234 | Menu behavior options | | `Themes.c` | 221 | Theme import/export | | `main.c` | 180 | Entry point, display open, WINGs init | | `double.c` | 163 | Double-click speed test widget | | `WPrefs.h` | 175 | Shared header | | `TexturePanel.h` | 56 | Texture panel header | | `editmenu.h` | 113 | Menu editor header | --- ## File Classification ### Fully Portable (zero Xlib calls, zero meaningful X11 types) These files use only WINGs widget APIs and WMPropList for defaults manipulation: | File | LOC | Purpose | |---|---|---| | `FontSimple.c` | 751 | Font configuration | | `WindowHandling.c` | 612 | Window placement/behavior | | `Icons.c` | 485 | Icon preferences | | `Configurations.c` | 445 | Misc configuration | | `Expert.c` | 363 | Expert toggles | | `Focus.c` | 362 | Focus mode | | `Preferences.c` | 359 | Size/position display | | `Docks.c` | 335 | Dock behavior | | `Workspace.c` | 240 | Workspace naming | | `MenuPreferences.c` | 234 | Menu behavior | | `Themes.c` | 221 | Theme management | | `KeyboardSettings.c` | 175 | Keyboard repeat/delay | | **Total** | **4582** | **29% of WPrefs.app** | Note: several of these files reference `Display *` or `Window` in variable declarations (obtained via `WMScreenDisplay()`) but only pass them to WINGs functions — they never call Xlib directly. The X11 types flow through transitively from WINGs. ### X11-Dependent Files | File | LOC | Xlib calls | What's leaking | |---|---|---|---| | **`Appearance.c`** | 2356 | **67** | Texture preview rendering: `XCreatePixmap`, `XCopyArea` (×20), `XDrawLine` (×15), `XDrawRectangle` (×6), `XFillRectangle` (×4), `XFillPolygon` (×2), `XFreePixmap` (×6), `XCreateGC`/`XFreeGC`, `XParseColor` | | **`editmenu.c`** | 1361 | **37** | Drag-and-drop menu editing: `XGrabPointer`/`XUngrabPointer`, `XTranslateCoordinates` (×4), `XRecolorCursor` (×4), `XQueryTree`, `XQueryPointer`, `XGetWindowAttributes`, `XGetGeometry`, `XMoveWindow`, `XClearWindow`, `XFlush`, `XChangeProperty`, `XSetWMNormalHints`, `XAllocSizeHints`, `XSetErrorHandler` | | **`Menu.c`** | 1825 | **24** | Menu editor: `XGrabKeyboard`/`XUngrabKeyboard`, `XDrawLine` (×7), `XSetForeground` (×2), `XFillRectangle`, `XCreateGC`/`XFreeGC` — mostly drawing crosshair markers and key capture | | **`TexturePanel.c`** | 1549 | **14** | Texture editor: `XFillRectangle` (×3), `XCopyArea` (×2), `XFreePixmap`, `XParseColor`, `XCreateSimpleWindow`, `XMapRaised`, `XFlush`, `XOpenDisplay`, `XColor` | | **`xmodifier.c`** | 311 | **12** | Modifier key detection: `XGetModifierMapping`, `XFreeModifiermap`, `XKeysymToKeycode` — entirely X11 | | **`KeyboardShortcuts.c`** | 695 | **12** | Shortcut capture: `XGrabKeyboard`/`XUngrabKeyboard`, `XKeysymToKeycode`, `XKeysymToString`, `XAllowEvents`, `XGetModifierMapping`, `XFreeModifiermap`, `XConvertCase`, `XFillRectangle` | | **`HotCornerShortcuts.c`** | 465 | **11** | Hot corner icon rendering: `XCreatePixmap` (×5), `XCopyArea` (×5), `XFreePixmap` (×5), `XCreateGC`/`XFreeGC` — icon quadrant assembly | | **`WPrefs.c`** | 927 | **7** | WM command: `XInternAtom`, `XSendEvent`, `XFlush` (×2) — sends `_WINDOWMAKER_COMMAND` to reload | | **`MouseSettings.c`** | 798 | **6** | Mouse config: `XChangePointerControl`, `XGetPointerControl`, `XGetModifierMapping`, `XFreeModifiermap`, `XKeysymToString` | | **`main.c`** | 180 | **4** | Startup: `XSupportsLocale`, `XSetLocaleModifiers`, `XOpenDisplay`, `XDisplayName` | | **`double.c`** | 163 | **2** | Double-click widget: `XFillRectangle`, `XClearWindow` | | **`Paths.c`** | 328 | **1** | List drawing: `XFillRectangle` (in custom list cell renderer) | | **Total** | **8958** | **197** | | --- ## 1. Compile-Time `#ifdef` Branches ### Backend/Feature Guards | Guard | File | Sites | What it guards | |---|---|---|---| | `XKB_MODELOCK` | `Expert.c:87`, `KeyboardShortcuts.c:166` | 2 | XKB mode lock toggle option, extra keybinding | | `HAVE_XCONVERTCASE` | `KeyboardShortcuts.c:171` | 1 | Whether to use system `XConvertCase` or local implementation | ### Portability Guards | Guard | File | Sites | What it guards | |---|---|---|---| | `HAVE_STDNORETURN` | `WPrefs.c:27`, `main.c:33` | 2 | C11 `_Noreturn` | | `I18N` | `main.c:131` | 1 | Gettext initialization | | `FC_WEIGHT_NORMAL` | `FontSimple.c:28` | 1 | Fontconfig constant fallback | | `DEBUG` | `Expert.c:286` | 1 | Debug panel option | **Total: 8 `#ifdef` sites.** Remarkably few for a 15k LOC application. --- ## 2. Runtime Backend Dispatch **None.** No vtable calls, no `is_wayland` checks, no `_x11_raw` access, no `dpy == NULL` guards. WPrefs.app is a pure WINGs client — it gets its X11 dependency entirely through WINGs APIs and direct Xlib calls. --- ## 3. X11 Types in Shared Headers ### `WPrefs.h` ```c int ModifierFromKey(Display *dpy, const char *key); // line 144 ``` One function prototype with `Display *`. The rest of the header is WINGs types (`WMScreen *`, `WMWindow *`, etc.). --- ## 4. Direct Xlib Calls — By Category ### Drawing / Pixmap Manipulation (120 calls — 61%) The dominant category. WPrefs renders texture previews, menu editor decorations, and icon composites directly via Xlib: | Operation | Count | Files | |---|---|---| | `XCopyArea` | 27 | `Appearance.c` (20), `HotCornerShortcuts.c` (5), `TexturePanel.c` (2) | | `XDrawLine` | 22 | `Appearance.c` (15), `Menu.c` (7) | | `XFillRectangle` | 13 | `Appearance.c` (4), `Menu.c` (1), `TexturePanel.c` (3), `Paths.c` (1), `double.c` (1), `KeyboardShortcuts.c` (1), `HotCornerShortcuts.c` (1), `editmenu.c` (1) | | `XCreatePixmap` | 8 | `Appearance.c` (3), `HotCornerShortcuts.c` (5) | | `XFreePixmap` | 8 | `Appearance.c` (4), `HotCornerShortcuts.c` (3), `TexturePanel.c` (1) | | `XDrawRectangle` | 6 | `Appearance.c` | | `XCreateGC` / `XFreeGC` | 6 | `Appearance.c` (4), `Menu.c` (2) | | `XFillPolygon` / `XDrawLines` | 4 | `Appearance.c` | | `XSetForeground` | 2 | `Menu.c` | **These should all route through WINGs' `W_RenderBackend` vtable** but don't. ### Keyboard / Input (24 calls — 12%) | Operation | Count | Files | |---|---|---| | `XGrabKeyboard` / `XUngrabKeyboard` | 4 | `KeyboardShortcuts.c`, `Menu.c` | | `XKeysymToKeycode` / `XKeysymToString` | 5 | `KeyboardShortcuts.c`, `MouseSettings.c` | | `XGetModifierMapping` / `XFreeModifiermap` | 6 | `KeyboardShortcuts.c`, `MouseSettings.c`, `xmodifier.c` | | `XConvertCase` | 1 | `KeyboardShortcuts.c` | | `XAllowEvents` | 1 | `KeyboardShortcuts.c` | ### Window / Pointer Manipulation (22 calls — 11%) | Operation | Count | Files | |---|---|---| | `XGrabPointer` / `XUngrabPointer` | 4 | `editmenu.c` | | `XTranslateCoordinates` | 5 | `editmenu.c` | | `XRecolorCursor` | 4 | `editmenu.c` | | `XQueryTree` / `XQueryPointer` | 2 | `editmenu.c` | | `XGetWindowAttributes` / `XGetGeometry` | 2 | `editmenu.c` | | `XMoveWindow` / `XClearWindow` | 2 | `editmenu.c`, `double.c` | | `XChangePointerControl` / `XGetPointerControl` | 2 | `MouseSettings.c` | ### WM Communication (7 calls — 4%) | Operation | Count | Files | |---|---|---| | `XInternAtom` | 1 | `WPrefs.c` | | `XSendEvent` | 1 | `WPrefs.c` | | `XFlush` | 3 | `WPrefs.c` (2), `TexturePanel.c` (1) | | `XChangeProperty` / `XSetWMNormalHints` | 2 | `editmenu.c` | ### Color Parsing (3 calls — 2%) | Operation | Count | Files | |---|---|---| | `XParseColor` | 2 | `Appearance.c`, `TexturePanel.c` | | `XColor` type | 2 | `Appearance.c`, `TexturePanel.c` | ### Display Connection (4 calls — 2%) | Operation | Count | Files | |---|---|---| | `XOpenDisplay` | 2 | `main.c`, `TexturePanel.c` | | `XSupportsLocale` / `XSetLocaleModifiers` | 2 | `main.c` | --- ## 5. Summary: Heat Map ``` Fully X11 Portable Leaking ────────── ──────── FontSimple.c ██████████ WindowHandling.c ██████████ Icons.c ██████████ Configurations.c ██████████ Expert.c ██████████ Focus.c ██████████ Preferences.c ██████████ Docks.c ██████████ Workspace.c ██████████ MenuPreferences.c ██████████ Themes.c ██████████ KeyboardSettings.c ██████████ Paths.c █████████░ (1 XFillRectangle) double.c ████████░░ (2 calls) WPrefs.c ███████░░░ (7 calls - WM reload command) main.c ███████░░░ (4 calls - display open) MouseSettings.c ██████░░░░ (6 calls - pointer control) HotCornerShortcuts.c █████░░░░░ (11 calls - icon pixmap assembly) KeyboardShortcuts.c █████░░░░░ (12 calls - key grab/detect) TexturePanel.c ████░░░░░░ (14 calls - texture preview) Menu.c ███░░░░░░░ (24 calls - menu editor drawing) editmenu.c ██░░░░░░░░ (37 calls - DnD menu editing) xmodifier.c ░░░░░░░░░░ ██████████ (12 calls - entirely X11) Appearance.c ░░░░░░░░░░ ██████████ (67 calls - texture preview) ``` **By the numbers:** | Category | Files | LOC | Xlib calls | % of WPrefs.app | |---|---|---|---|---| | Fully portable | 12 | 4582 | 0 | 29% | | Minor X11 leakage (≤7 calls) | 5 | 1876 | 20 | 12% | | Moderate X11 leakage (8–37 calls) | 5 | 3834 | 86 | 25% | | Heavy X11 dependency (>37 calls) | 2 | 3717 | 91 | 24% | | Entirely X11 (xmodifier.c) | 1 | 311 | 12 | 2% | **The three biggest problems for Wayland parity:** 1. **`Appearance.c`** (67 Xlib calls) — all texture preview rendering. Uses `XCopyArea`, `XDrawLine`, `XDrawRectangle`, `XFillPolygon` directly on pixmaps. Should use WINGs' `W_RenderBackend` instead. 2. **`editmenu.c`** (37 Xlib calls) — the drag-and-drop menu editor. Pointer grabs, coordinate translation, window tree queries, cursor recoloring. These are interaction-model operations that need backend abstraction. 3. **Keyboard/modifier detection** (`KeyboardShortcuts.c` + `xmodifier.c` = 24 Xlib calls) — `XGrabKeyboard`, `XGetModifierMapping`, `XKeysymToKeycode`. On Wayland, keyboard handling uses `xkbcommon` directly rather than X11 modifier mapping.