How Windows 95 Tiled and Stretched Desktop Wallpapers

Windows 95 handled desktop wallpapers by combining registry configuration values with native Graphics Device Interface (GDI) rendering functions applied directly to the root desktop window. Depending on whether a user chose to center, tile, or stretch an image, the operating system decoded the source bitmap file and used standard GDI operations—principally raster blits and hardware-efficient blitting loops—to map pixel data directly to the screen resolution.

Desktop Configuration and Image Restrictions

Windows 95 natively supported only uncompressed Windows Bitmap (.bmp) and Device-Independent Bitmap (.dib) files for desktop backgrounds. Wallpaper settings were stored under the registry key HKEY_CURRENT_USER\Control Panel\Desktop using two primary string values:

  • Wallpaper: The absolute file path to the .bmp file.
  • TileWallpaper: Set to "1" for tiling or "0" for centering.

Standard out-of-the-box Windows 95 did not natively include a stretching option in its display properties. Wallpaper stretching was introduced via the Microsoft Plus! for Windows 95 add-on pack (and later integrated via the Internet Explorer 4.0 Windows Desktop Update), which added the WallpaperStyle registry string ("2" for stretched, "0" for centered/tiled).

The Desktop Window Event Cycle

The desktop surface in Windows 95 is managed as a special window handled by USER32.DLL (associated with the desktop window class). When the background needed to be drawn—such as during startup, resolution changes, or after minimizing full-screen windows—the system dispatched a WM_ERASEBKGND message to the desktop window procedure.

The operating system allocated a device context (DC) for the entire screen, queried the color depth and resolution via GetDeviceCaps, and loaded the bitmap into memory. If the bitmap was a Device-Independent Bitmap (DIB), it was converted to a Device-Dependent Bitmap (DDB) matching the current display driver's color palette (such as 16-color, 256-color indexed, or 16-bit/24-bit true color) to optimize blitting speed.

How Tiling Was Processed

When TileWallpaper was set to "1", Windows 95 mapped the image across the entire visible workspace starting from the top-left coordinate (0, 0).

  1. Coordinate Mapping: The system retrieved the source bitmap's width and height, alongside the current display resolution (such as 640×480 or 800×600).
  2. Blitting Loop: Windows utilized a dual-axis loop executing BitBlt (Bit Block Transfer). The outer loop incremented vertical screen coordinates (\(Y\)) by the image height, while the inner loop incremented horizontal coordinates (\(X\)) by the image width.
  3. Pattern Optimization: For smaller bitmaps (such as 8×8 or 16×16 texture patterns), the system optimized rendering by creating a pattern brush via CreatePatternBrush or CreateDIBPatternBrushPt and painting the desktop area using PatBlt, avoiding repeated manual blit calls.

Any overflow past the right and bottom edges of the screen was clipped automatically by the GDI subsystem's viewport clipping boundaries.

How Centering Was Processed

When TileWallpaper was set to "0" and stretching was disabled, the image was centered on the screen:

  1. Offset Calculations: The engine determined origin offsets using the formulas:
    • \(X = \frac{\text{Screen Width} - \text{Bitmap Width}}{2}\)
    • \(Y = \frac{\text{Screen Height} - \text{Bitmap Height}}{2}\)
  2. Border Filling: If the image was smaller than the display area, the surrounding desktop space was filled with the solid background color defined by the user's theme (COLOR_BACKGROUND / COLOR_DESKTOP) using FillRect or ExtTextOut.
  3. Drawing: The bitmap was rendered at coordinate \((X, Y)\) using BitBlt. If the bitmap was larger than the screen resolution, negative coordinates were generated, effectively clipping the outer borders of the image while preserving the visual center.

How Stretching Was Processed

With Microsoft Plus! installed, setting WallpaperStyle to "2" triggered stretching routines:

  1. Target Rect Determination: The destination rectangle was set explicitly to \((0, 0, \text{Screen Width}, \text{Screen Height})\).
  2. GDI Scaling: Rendering was executed using GDI’s StretchBlt (or StretchDIBits directly from file memory).
  3. Scaling Algorithm: Because consumer hardware in 1995 (predominantly 486 and early Pentium processors) lacked dedicated 2D scaling hardware or excess CPU cycles, Windows set the stretching mode to COLORONCOLOR (also known as STRETCH_DELETESCANS). This algorithm performed simple nearest-neighbor scaling, dropping rows and columns when downscaling or duplicating them when upscaling. No bilinear filtering or anti-aliasing was used, producing the characteristic pixelated appearance of stretched images on the operating system.