1339 lines
66 KiB
Markdown
1339 lines
66 KiB
Markdown
# Backend-Specific Branches Remaining in `src/` Policy Code
|
||
|
||
> **Status (2026-05-28, final):** This document was written during the initial
|
||
> abstraction analysis and has been superseded by ROADMAP.md. All X11 isolation
|
||
> work described below has been completed:
|
||
>
|
||
> - `wmspec.c` and `xdnd.c` moved to `src/backend/x11/` — done
|
||
> - `_x11_raw` references eliminated from `src/` policy code — done
|
||
> - **WINGs widget library**: All 412+ direct Xlib calls isolated to `_x11.c`
|
||
> backend files with Wayland stubs in `wstubs_no_x11.c` — done
|
||
>
|
||
> The counts below are **historical** and reflect the state before the refactoring.
|
||
> See ROADMAP.md for the current state.
|
||
|
||
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 <X11/Xlib.h>` 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 <X11/Xlib.h>` (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 | `<sys/select.h>` 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 | `<sys/select.h>` |
|
||
| `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.
|