I was expecting monitor rects to be correct (as in matching the virtual mode), but maybe I missed something. There's some DPI conversion in the NtUserGetMonitorInfo which I'm not completely sure it is doing.
Here is an attempt to summarize my current understanding:
* physical dpi: The "real" dpi of the adapter, currently assumed to match `system_dpi` since we don't have per-adapter dpi reporting. * virtual dpi: The dpi of the adapter after a virtual mode change (matches physical dpi if there is no virtual mode change) * adapter dpi: Previously reported physical dpi (= `system_dpi` ), now virtual dpi. * monitor dpi: At the moment returns the respective adapter dpi (so now also returning virtual dpi)
The drivers (through `UpdateDisplayDevices`) report monitor rect information in physical dpi.
Your proposal has uncovered a few pre-existing inconsistencies in how monitor rects are treated. Some functions assume that the monitor rects are expressed in `system_dpi` (the get_*_rect helper functions in sysparams.c) whereas others assume they are expressed in their respective adapter dpi. That was OK before because all those dpi values were the same.
The change proposed in my virtual-desktop branch transform the monitor rects to account for the virtual mode change. This involves mapping from physical dpi to virtual dpi, but the transformation is done relative to the adapter origin coordinates. This means that the functions that assumed the rects are in adapter dpi now work, but the functions that make different assumptions now need fixing.
Regarding (2)... Or maybe instead of changing system_dpi which _will_ be seen by every application, decide that Wine virtualized monitor dpi will always be relative to 96dpi at 640x480, the minimum supported resolution, and let driver adjust their scaling
Right, so we can play with the monitor dpi value reported to applications (i.e., dissociate from the real "virtual dpi") in various ways. I am not sure I understand how the 96dpi at 640x480 approach would work, though, can you explain that a bit more?
I was thinking that one way would be for the `get_monitor_dpi` sysparam.c function to return `max(96, real_monitor_dpi)` (so that's the value all public APIs will get), but then allow the driver to somehow know (or figure out) the `real_monitor_dpi` value and apply the residual scaling as required.