How Windows Mobile 6.5 Scaled QVGA Apps to WVGA

When high-resolution WVGA (800x480) devices emerged, thousands of legacy Windows Mobile applications were hardcoded for standard QVGA (320x240) screens. Windows Mobile 6.5 relied on a built-in resolution abstraction layer inside the Graphics, Windowing, and Event Subsystem (GWE) to run these older applications without breaking layouts. This layer intercepted graphical device interface (GDI) calls, dynamically scaled coordinates for touch input, and utilized software- or hardware-accelerated pixel interpolation to upscale legacy interfaces seamlessly to the larger physical display.

The HI_RES_AWARE Manifest Flag

The operating system determined whether an executable required virtualization by inspecting its binary resources. Native WVGA-compatible applications contained a custom resource marked HI_RES_AWARE (defined as resource type CEUX).

If an application lacked this flag, the Windows Mobile loader flagged the process as legacy (running at a virtual 96 DPI). The OS then routed the application through the resolution abstraction layer rather than granting it direct access to native screen metrics.

Input Coordinate Virtualization

Legacy applications expected touch events within the bounds of 0,0 to 319,239. The abstraction layer intercepted hardware touch inputs generated by the touch digitizer driver at the native 800x480 resolution.

Before dispatching standard window messages—such as WM_LBUTTONDOWN, WM_MOUSEMOVE, and WM_LBUTTONUP—the GWE translated the physical screen coordinates down to the virtual 320x240 space. This ensured that hitboxes, button controls, and custom UI elements aligned precisely with user interactions without requiring developers to alter their internal hit-testing logic.

GDI Call Interception and Thunking

When a legacy process requested drawing metrics, the abstraction layer returned spoofed system metrics. API calls such as GetSystemMetrics(SM_CXSCREEN) and GetSystemMetrics(SM_CYSCREEN) reported 320 and 240 respectively, rather than 800 and 480.

For rendering, the system utilized a thunking layer that intercepted GDI drawing primitives (such as lines, rectangles, and text calls):

  • Coordinate Upscaling: Standard primitive coordinates were multiplied before rasterization occurred.
  • Font Scaling: The font engine mapped legacy font sizes to larger point sizes to ensure system text remained legible at higher pixel densities.
  • Off-Screen Buffering: Bitmaps drawn using Device Contexts (DCs) were redirected to virtualized memory buffers before being composited.

Resolving the Aspect Ratio Mismatch

Scaling from QVGA (4:3 aspect ratio) to WVGA (5:3 aspect ratio) introduced an uneven scaling factor:

  • Vertical axis: 240 pixels to 480 pixels represents an exact 2x integer scale.
  • Horizontal axis: 320 pixels to 800 pixels represents a 2.5x fractional scale.

To resolve this, the abstraction layer implemented one of two vendor-configured strategies:

  1. Pillarboxing: The 320-pixel width was integer-scaled by 2x to 640 pixels, centered on the screen, leaving 80-pixel black borders on either side.
  2. Non-Uniform Scaling / Stretch-to-Fit: The horizontal buffer was scaled by 2.5x using nearest-neighbor or bilinear filtering to fill the full 800 pixels. While this produced a slight horizontal stretch on UI controls and circular graphics, it eliminated dead space on the display.

Framebuffer Blitting

Once the virtualized 320x240 frame was composed, the abstraction layer performed a stretching blit operation (StretchBlt) directly to the physical display buffer. On devices featuring contemporary Qualcomm or Marvell processors, this stretch operation was offloaded to dedicated 2D hardware blitters to prevent the double-buffering and pixel interpolation overhead from degrading system responsiveness.