- Mirror display driver in the multimon configuration (negative origin)
- Posted by Andrew.Solodovnikov@gmail.com on July 1st, 2008
I'm trying to enable support of the multimonitor configurations for my
mirror driver. I had modified mirror driver loading code to bind it to
the properly initialized DEVMODE (dmPosition etc), so mirror driver
binds to the entire virtual screen.
Firstly, i had configured my test system with dual monitor in this
way:
|0,0----------------1024,0--------------|
| M1 (primary) | M2 |
| | |
|0,768------------1024,768-----------|
In this configuration all works fine - all gdi calls correctly
mirrored to the mirror driver back buffer.
Next, i tried to move M2 just before M1, so virtual display origin in
X becomes negative:
|(-1024,0)--------0,0------------------|
| M2 | M1 (primary) |
| | |
|(-1024,768)----0,768---------------|
At this point most of the mirrored gdi calls draws in the back surface
incorrectly - as if there is no negative origin, how i can feel it.
I tried to debug this - parameters to the DrvBitBlt/DrvCopyBits seems
to be quite correct (all back surf coordinates mapped to the (0,0)
origin). And more - blits from the back surf to the back surf (for
example, when moving window) are not performed correctly. But some gdi
calls, that can't use back surface as source (f.e., DrvTextOut) are
performed quite well.
Mirror driver is very simple:
1. DrvEnableSurface: EngCreateDeviceSurface, EngAssociateSurface.
2. DrvEscape(start): EngCreateBitmap, EngAssociateSurface,
EngLockSurface.
3. All hooked DrvXxx calls back to the EngXxx, replacing surface,
created at the step 1 by surface, created at the step 2.
As I understand XPDM, there is no sense to the mirror driver on his
origin - gdi should map coordinates by itself. Or there is a necessity
of the "magical steps" to get this working all together?
Thanks!
- Posted by Ivan Brugiolo [MSFT] on July 1st, 2008
What did you pass to DEVMOD::dmPosition in ChangeDisplaySettingsEx ?
--
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
<Andrew.Solodovnikov@gmail.com> wrote in message
news:0ba1dc78-9819-4697-a589-3e4d17454502@m3g2000hsc.googlegroups.com...
- Posted by Andrew.Solodovnikov@gmail.com on July 1st, 2008
Ivan, thanks for reply.
I use some kind of a variation of this code to fill DEVMODE:
DEVMODE devMode;
ZeroMemory(&devMode, sizeof(DEVMODE));
devMode.dmSize = sizeof(DEVMODE);
BOOL bResult = EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS,
&devMode);
if (bResult)
{
devMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT |
DM_POSITION;
devMode.dmPosition.x = ::GetSystemMetrics(SM_XVIRTUALSCREEN);
devMode.dmPosition.y = ::GetSystemMetrics(SM_YVIRTUALSCREEN);
devMode.dmPelsWidth = ::GetSystemMetrics(SM_CXVIRTUALSCREEN);
devMode.dmPelsHeight = ::GetSystemMetrics(SM_CYVIRTUALSCREEN);
In the DrvEnablePDEV devmode seems to be correct (as i can understand
correctness, o'coz).
- Posted by Ivan Brugiolo [MSFT] on July 1st, 2008
It would be intersting to debug DrvEnablePDEV and DrvEnableSurface.
On average, a mirror driver in multimon works by selecting an attach
rectangle
that covers the entire virtual screen.
`!gdikdx.dpdev -DR` should give you the configuration of the MDEV in that
case.
--
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of any included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
<Andrew.Solodovnikov@gmail.com> wrote in message
news:80fa5043-00b5-4616-857e-c18290fbe29e@d1g2000hsg.googlegroups.com...
Ivan, thanks for reply.
I use some kind of a variation of this code to fill DEVMODE:
DEVMODE devMode;
ZeroMemory(&devMode, sizeof(DEVMODE));
devMode.dmSize = sizeof(DEVMODE);
BOOL bResult = EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS,
&devMode);
if (bResult)
{
devMode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT |
DM_POSITION;
devMode.dmPosition.x = ::GetSystemMetrics(SM_XVIRTUALSCREEN);
devMode.dmPosition.y = ::GetSystemMetrics(SM_YVIRTUALSCREEN);
devMode.dmPelsWidth = ::GetSystemMetrics(SM_CXVIRTUALSCREEN);
devMode.dmPelsHeight = ::GetSystemMetrics(SM_CYVIRTUALSCREEN);
In the DrvEnablePDEV devmode seems to be correct (as i can understand
correctness, o'coz).
- Posted by Andrew.Solodovnikov@gmail.com on July 1st, 2008
Ivan, thanks for answer again!
Yes, I think so, but practical results are very strange. Btw, target
OS - Windows XP SP3. Maybe, it is not correct to replace "virtual"
screen surface (obtained in step 1) with back buffer surface, created
at step 2...
I feel, that DrvXxx callbacks are not working correctly when dst and
src are pointed to the same (created in step 1) surface. May be, there
is a more correct way to punch gdi calls back to the surface created
in step 2, than just replacing src and dst in appropriate cases?
I'll try and report results. Thanks!
- Posted by Andrew.Solodovnikov@gmail.com on July 1st, 2008
I'm trying to debug driver, but can't find gdikdx.dll for windows xp
sp3. As I understand, there is no public version of this extension. If
so, maybe, you have other thoughts what I can check?
I try to log update region - seems it is correct. And again, for
example, for DrvCopyBits, it seems that buggy blts only for back_surf
to back_surf operations... Really strange.