1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
//! A Denise panel in a Win32 child window.
//!
//! The oldest of the reasons this project exists. CoreCanvas shipped inside
//! Windows applications that were not going to be rewritten — MFC, WinForms, VB6
//! through the ActiveX shim — and the thing they all need is a control they can
//! put in a dialog next to the ones they already have.
//!
//! So: [`DeniseControl`] registers a window class and creates a child `HWND`. The
//! host owns the window, the message loop and the parent; Denise owns the pixels
//! inside one rectangle and nothing else.
//!
//! # What is different from the bare-metal backends
//!
//! - **The host owns the message loop.** There is no `run` function here. Windows
//! decides when to paint and Denise answers, which is the opposite of the DRM
//! backend where Denise decides and the display follows.
//! - **Damage is real bandwidth.** `BitBlt` moves only the rectangles it is given,
//! unlike a DRM page flip where the whole buffer goes regardless. The tree's
//! damage is worth passing on rather than rounding up to the client area.
//! - **The pixel format already matches.** A 32-bit `BI_RGB` DIB section is
//! `0xAARRGGBB` in a little-endian `DWORD`, which is exactly what the rasteriser
//! writes. No conversion pass anywhere.
//! - **There is already a cursor.** Windows draws one, so the composited sprite
//! stays off: `Ui::show_cursor(false)`, which since M5 is a decision that sticks
//! rather than one the next mouse move overrides.
//!
//! # No console window
//!
//! A Rust binary defaults to the **console** subsystem, so Windows allocates a
//! console and it sits behind the app looking like a mistake. The `.exe` that
//! hosts the control — not this library — decides that, with a crate-level
//! attribute:
//!
//! ```ignore
//! #![windows_subsystem = "windows"]
//! ```
//!
//! The cost is that `stdout` and `stderr` go nowhere, including panic messages
//! and anything printed before a window exists. So the usual form keeps the
//! console while developing and drops it for the build that ships:
//!
//! ```ignore
//! #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
//! ```
//!
//! It is ignored on non-Windows targets, so it needs no `cfg(windows)` of its
//! own. A host that wants both — no console, and somewhere for diagnostics to go
//! — should log to a file or `OutputDebugString` rather than to a stream nothing
//! is reading.
//!
//! # Testing
//!
//! [`keymap`] is platform-independent and its tests run everywhere. That is not
//! tidiness: it is a table of a hundred numbers, it is the part that breaks, and
//! discovering that on a CI runner rather than locally is a slow way to discover
//! it — which is exactly what happened the first time. Only the window and the
//! DIB section are gated to Windows, the same split `denise-drm` and
//! `denise-evdev` make.
//!
//! # Status
//!
//! Run on real hardware — Windows 11 ARM64, where Tab reaches the control and
//! AltGr and the dead keys compose — and built and tested by CI on every push.
//! Still unverified: focus behaviour inside a real *dialog*, and DPI changes.
//! For the latter, the toolkit's answer exists and is documented in
//! `docs/design.md`: the host rebuilds with `theme.scaled(factor)` (or
//! `denise_ui_new_scaled` over the C ABI) when `WM_DPICHANGED` arrives — what
//! is missing is a host that has actually done it.
// `keymap` is deliberately outside the gate: it is a table of a hundred numbers
// mapping `u16` to `KeyCode`, which is exactly the sort of thing that goes wrong
// and exactly the sort of thing that should not need a Windows machine to test.
// Only the window and the DIB section are platform code. The same split
// `denise-drm` and `denise-evdev` make, for the same reason.
pub use key_code;
pub use ;
pub use DibSurface;
/// Failures from this backend.
/// Compiles the examples in this crate's README, so they cannot drift from the API
/// they claim to demonstrate. Never built except under `cargo test --doc`.
;