GDI bindings for software (CPU) presentation #1

Open
opened 2026-10-18 04:10:04 +02:00 by dxtr · 0 comments
Owner

Context

cl-win32 binds user32 and kernel32 only — it has nothing from gdi32. A new optional cl-windowing subsystem, cl-windowing/software, presents a CPU-drawn framebuffer to a window without any GPU API (OpenGL/Vulkan/DirectX), for text editors and other applications that are not graphically intensive. Its Win32 backend blits a top-down 32-bit DIB to the window with GDI, so it needs a small GDI surface added here.

(The design uses GDI because, on modern Windows under WDDM, it is the supported, GPU-API-free way to get a CPU buffer onto a window. DirectDraw is deprecated DirectX emulated over D3D; "WDDM" is a driver model, not an app API. So GDI is the right backing.)

What to add

Idiomatic cl-win32 style: Lisp values, conditions on failure, with- macros for resources, no foreign pointers in the public API except documented escape hatches (the DIB pixel pointer is one).

  • Device contexts: get-dc / release-dc (window DC), begin-paint / end-paint (for WM_PAINT), create-compatible-dc, delete-dc, and with- macros for each.
  • DIB sections: create-dib-section (32 bpp, BI_RGB, negative height = top-down), returning an HBITMAP and the pixel-memory pointer; select-object; delete-object.
  • Blits: bit-blt and stretch-di-bits (and/or set-di-bits-to-device) with SRCCOPY; the BITMAPINFO / BITMAPINFOHEADER structures and the BI_RGB, DIB_RGB_COLORS constants.
  • Readback (for tests): get-di-bits.

These are general-purpose GDI, useful beyond this subsystem, and belong in cl-win32 alongside its user32 wrappers.

Notes

  • Thread rule: the DIB and its memory DC are created/resized/destroyed on the window's owning thread. Whether a cross-thread BitBlt to a window DC is reliable is to be confirmed by a test; if not, the consumer hands the blit to that thread.
  • Pixel format consumed: a top-down 32-bit DIB is byte-identical to the subsystem's canonical #xAARRGGBB pixel on little-endian (bytes B,G,R,X), so no conversion is needed.

Tests

A Parachute test that creates a DIB section, blits a known pattern to a memory/window DC, reads it back with get-di-bits, and checks the pixels.

Spec

Full design in gdi.org in the engine workspace, section "cl-win32: GDI bindings". Consumer: the cl-windowing/software subsystem (tracked in dxtr/cl-windowing).

## Context `cl-win32` binds **user32** and **kernel32** only — it has nothing from **gdi32**. A new optional cl-windowing subsystem, `cl-windowing/software`, presents a CPU-drawn framebuffer to a window without any GPU API (OpenGL/Vulkan/DirectX), for text editors and other applications that are not graphically intensive. Its **Win32 backend** blits a top-down 32-bit DIB to the window with GDI, so it needs a small GDI surface added here. (The design uses GDI because, on modern Windows under WDDM, it is the supported, GPU-API-free way to get a CPU buffer onto a window. DirectDraw is deprecated DirectX emulated over D3D; "WDDM" is a driver model, not an app API. So GDI is the right backing.) ## What to add Idiomatic `cl-win32` style: Lisp values, conditions on failure, `with-` macros for resources, no foreign pointers in the public API except documented escape hatches (the DIB pixel pointer is one). - **Device contexts**: `get-dc` / `release-dc` (window DC), `begin-paint` / `end-paint` (for `WM_PAINT`), `create-compatible-dc`, `delete-dc`, and `with-` macros for each. - **DIB sections**: `create-dib-section` (32 bpp, `BI_RGB`, **negative height** = top-down), returning an `HBITMAP` and the pixel-memory pointer; `select-object`; `delete-object`. - **Blits**: `bit-blt` and `stretch-di-bits` (and/or `set-di-bits-to-device`) with `SRCCOPY`; the `BITMAPINFO` / `BITMAPINFOHEADER` structures and the `BI_RGB`, `DIB_RGB_COLORS` constants. - **Readback** (for tests): `get-di-bits`. These are general-purpose GDI, useful beyond this subsystem, and belong in `cl-win32` alongside its user32 wrappers. ## Notes - **Thread rule**: the DIB and its memory DC are created/resized/destroyed on the window's owning thread. Whether a cross-thread `BitBlt` to a window DC is reliable is to be confirmed by a test; if not, the consumer hands the blit to that thread. - Pixel format consumed: a top-down 32-bit DIB is byte-identical to the subsystem's canonical `#xAARRGGBB` pixel on little-endian (bytes B,G,R,X), so no conversion is needed. ## Tests A Parachute test that creates a DIB section, blits a known pattern to a memory/window DC, reads it back with `get-di-bits`, and checks the pixels. ## Spec Full design in `gdi.org` in the engine workspace, section "cl-win32: GDI bindings". Consumer: the `cl-windowing/software` subsystem (tracked in `dxtr/cl-windowing`).
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
dxtr/cl-win32#1
No description provided.