From: Andrew.Solodovnikov on
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!
From: Ivan Brugiolo [MSFT] on
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(a)gmail.com> wrote in message
news:0ba1dc78-9819-4697-a589-3e4d17454502(a)m3g2000hsc.googlegroups.com...
> 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!

From: Andrew.Solodovnikov on
> 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 athttp://www.microsoft.com/info/cpyright.htm

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).
From: Ivan Brugiolo [MSFT] on
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(a)gmail.com> wrote in message
news:80fa5043-00b5-4616-857e-c18290fbe29e(a)d1g2000hsg.googlegroups.com...
> 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
> athttp://www.microsoft.com/info/cpyright.htm

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).

From: Andrew.Solodovnikov on
Ivan, thanks for answer again!

> 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.

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?

> `!gdikdx.dpdev -DR` should give you the configuration of the MDEV in that
> case.

I'll try and report results. Thanks!