How Mirror Display Driver will know about Resolution Change?

I have written a Mirror Display Dirver for a Remote Desktop Access applicatoin. It works ok but when I change the resolution of machin and driver is already loaded then I gets the display of previous resolution only in Mirror driver (while the actual machine resolution has been changed.) Ex. suppose at the time of loading mirror driver machine was at 800x600x32 so mirror driver was working with this resolution. Now I have changed the resolution to 1024x768x32 but mirror driver has surface for 800x600x32. So it draws only on 800x600x32.

What I will have to do for this? What a mirror driver suppose to do on resolution change?

SachinS

I am not know how to writing a disply mirror driver.
But ,windows will send a IRP when user change the display resolution.
So.Write the display mirror driver as a filter of the phiscal display dirver may be do its work.

Good luck.

Hi, thanks for your quick reply.

I still want to know Which IRP i need to process? And if I use that filter driver and process the IRP then How my display driver will be able to create the surface for new resolution?

SachinS

xxxxx@yahoo.com wrote:

I am not know how to writing a disply mirror driver.

Then may I politely suggest that it is not helpful for you to reply?

But ,windows will send a IRP when user change the display resolution.
So.Write the display mirror driver as a filter of the phiscal display dirver may be do its work.

This is wrong. Mirror drivers are GDI drivers; they do not communicate
via IRPs. Further, display drivers are not WDM, and cannot be filtered.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

xxxxx@yahoo.co.in wrote:

I have written a Mirror Display Dirver for a Remote Desktop Access applicatoin. It works ok but when I change the resolution of machin and driver is already loaded then I gets the display of previous resolution only in Mirror driver (while the actual machine resolution has been changed.) Ex. suppose at the time of loading mirror driver machine was at 800x600x32 so mirror driver was working with this resolution. Now I have changed the resolution to 1024x768x32 but mirror driver has surface for 800x600x32. So it draws only on 800x600x32.

What I will have to do for this? What a mirror driver suppose to do on resolution change?

You should see a DisableSurface call for the old size, and an
EnableSurface call for the new size. Are you handling those routines?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Yes, I have implemented both DrvDisableSurface and DrvEnableSurface. But on resolution Change only DrvNotify is getting called with DN_DEVICE_ORIGIN, nothing else.
What should I do to make DrvDisableSurface and DrvEnableSurface to get called when resolution gets changed?

Thanks,
SachinS

I think I did something wrong in intializing GDIINFO and DEVINFO. Can anyone suggest me what to be to make it correct in following:
BOOL bInitPDEV(
PPDEV ppdev,
DEVMODEW *pDevMode,
GDIINFO *pGdiInfo,
DEVINFO *pDevInfo)
{
ULONG cModes;
PVIDEO_MODE_INFORMATION pVideoBuffer, pVideoModeSelected, pVideoTemp;
VIDEO_COLOR_CAPABILITIES colorCapabilities;
ULONG ulTemp;
BOOL bSelectDefault;
ULONG cbModeSize;
ULONG red, green, blue;
INT i;

//
// Fill in the GDIINFO data structure with the information returned from
// the kernel driver.
//

ppdev->ulMode = 0;
ppdev->cxScreen = pDevMode->dmPelsWidth;
ppdev->cyScreen = pDevMode->dmPelsHeight;
ppdev->ulBitCount = pDevMode->dmBitsPerPel;
ppdev->lDeltaScreen = ((ppdev->cxScreen * (pDevMode->dmBitsPerPel / 8)) + 3);
ppdev->lDeltaScreen -= ppdev->lDeltaScreen % 4;

if(ppdev->ulBitCount == 16)
{
//5-5-5
//ppdev->flRed = 0x7C00;
//ppdev->flGreen = 0x03E0;
//ppdev->flBlue = 0x001F;
//5-6-5
ppdev->flRed = 0xF800;
ppdev->flGreen = 0x07E0;
ppdev->flBlue = 0x001F;
}
else
{
ppdev->flRed = 0x00FF0000;
ppdev->flGreen = 0x000FF00;
ppdev->flBlue = 0x00000FF;
}

pGdiInfo->ulVersion = DDI_DRIVER_VERSION_NT5_01_SP1;
pGdiInfo->ulTechnology = DT_RASDISPLAY;
pGdiInfo->ulHorzSize = 0;
pGdiInfo->ulVertSize = 0;

pGdiInfo->ulHorzRes = ppdev->cxScreen;
pGdiInfo->ulVertRes = ppdev->cyScreen;
pGdiInfo->ulPanningHorzRes = 0;
pGdiInfo->ulPanningVertRes = 0;
pGdiInfo->cBitsPixel = pDevMode->dmBitsPerPel;
pGdiInfo->cPlanes = 1;
pGdiInfo->ulVRefresh = pDevMode->dmDisplayFrequency; // not used
pGdiInfo->ulBltAlignment = 1; // We don’t have accelerated screen-
// to-screen blts, and any
// window alignment is okay

pGdiInfo->ulLogPixelsX = 96;
pGdiInfo->ulLogPixelsY = 96;

pGdiInfo->flTextCaps = TC_RA_ABLE;

pGdiInfo->flRaster = 0; // flRaster is reserved by DDI

pGdiInfo->ulDACRed = 8;
pGdiInfo->ulDACGreen = 8;
pGdiInfo->ulDACBlue = 8;

pGdiInfo->ulAspectX = 0x24; // One-to-one aspect ratio
pGdiInfo->ulAspectY = 0x24;
pGdiInfo->ulAspectXY = 0x33;

pGdiInfo->xStyleStep = 1; // A style unit is 3 pels
pGdiInfo->yStyleStep = 1;
pGdiInfo->denStyleStep = 3;

pGdiInfo->ptlPhysOffset.x = 0;
pGdiInfo->ptlPhysOffset.y = 0;
pGdiInfo->szlPhysSize.cx = 0;
pGdiInfo->szlPhysSize.cy = 0;

// RGB and CMY color info.

pGdiInfo->ciDevice.Red.x = 6700;
pGdiInfo->ciDevice.Red.y = 3300;
pGdiInfo->ciDevice.Red.Y = 0;
pGdiInfo->ciDevice.Green.x = 2100;
pGdiInfo->ciDevice.Green.y = 7100;
pGdiInfo->ciDevice.Green.Y = 0;
pGdiInfo->ciDevice.Blue.x = 1400;
pGdiInfo->ciDevice.Blue.y = 800;
pGdiInfo->ciDevice.Blue.Y = 0;
pGdiInfo->ciDevice.AlignmentWhite.x = 3127;
pGdiInfo->ciDevice.AlignmentWhite.y = 3290;
pGdiInfo->ciDevice.AlignmentWhite.Y = 0;

pGdiInfo->ciDevice.RedGamma = 20000;
pGdiInfo->ciDevice.GreenGamma = 20000;
pGdiInfo->ciDevice.BlueGamma = 20000;

pGdiInfo->ciDevice.Cyan.x = 0;
pGdiInfo->ciDevice.Cyan.y = 0;
pGdiInfo->ciDevice.Cyan.Y = 0;
pGdiInfo->ciDevice.Magenta.x = 0;
pGdiInfo->ciDevice.Magenta.y = 0;
pGdiInfo->ciDevice.Magenta.Y = 0;
pGdiInfo->ciDevice.Yellow.x = 0;
pGdiInfo->ciDevice.Yellow.y = 0;
pGdiInfo->ciDevice.Yellow.Y = 0;

// No dye correction for raster displays.

pGdiInfo->ciDevice.MagentaInCyanDye = 0;
pGdiInfo->ciDevice.YellowInCyanDye = 0;
pGdiInfo->ciDevice.CyanInMagentaDye = 0;
pGdiInfo->ciDevice.YellowInMagentaDye = 0;
pGdiInfo->ciDevice.CyanInYellowDye = 0;
pGdiInfo->ciDevice.MagentaInYellowDye = 0;

pGdiInfo->ulDevicePelsDPI = 0; // For printers only
pGdiInfo->ulPrimaryOrder = PRIMARY_ORDER_CBA;

// Note: this should be modified later to take into account the size
// of the display and the resolution.

pGdiInfo->ulHTPatternSize = HT_PATSIZE_4x4_M;

pGdiInfo->flHTFlags = HT_FLAG_ADDITIVE_PRIMS;

// Fill in the basic devinfo structure

*pDevInfo = gDevInfoFrameBuffer;

// Fill in the rest of the devinfo and GdiInfo structures.
#if (NTDDI_VERSION >= NTDDI_VISTA)
pDevInfo->flGraphicsCaps2 |= GCAPS2_INCLUDEAPIBITMAPS | GCAPS2_EXCLUDELAYERED | GCAPS2_ALPHACURSOR;
#endif

if (ppdev->ulBitCount == 8)
{
// It is Palette Managed.

pGdiInfo->ulNumColors = 20;
pGdiInfo->ulNumPalReg = 1 << ppdev->ulBitCount;

pDevInfo->flGraphicsCaps |= (GCAPS_PALMANAGED | GCAPS_COLOR_DITHER );

pGdiInfo->ulHTOutputFormat = HT_FORMAT_8BPP;
pDevInfo->iDitherFormat = BMF_8BPP;

// Assuming palette is orthogonal - all colors are same size.

ppdev->cPaletteShift = 8 - pGdiInfo->ulDACRed;
}
else
{
pGdiInfo->ulNumColors = (ULONG) (-1);
pGdiInfo->ulNumPalReg = 0;

if (ppdev->ulBitCount == 16)
{
pGdiInfo->ulHTOutputFormat = HT_FORMAT_16BPP;
pDevInfo->iDitherFormat = BMF_16BPP;
}
else if (ppdev->ulBitCount == 24)
{
pGdiInfo->ulHTOutputFormat = HT_FORMAT_24BPP;
pDevInfo->iDitherFormat = BMF_24BPP;
}
else
{
pGdiInfo->ulHTOutputFormat = HT_FORMAT_32BPP;
pDevInfo->iDitherFormat = BMF_32BPP;
}
}

pDevInfo->flGraphicsCaps |= (GCAPS_WINDINGFILL | GCAPS_GEOMETRICWIDE);

// create remaining palette entries, simple loop to create uniformly
// distributed color values.

red = 0, green = 0, blue = 0;

for (i = NUMPALRESERVED; i < NUMPALCOLORS; i++) {
palColors[i][0] = red;
palColors[i][1] = green;
palColors[i][2] = blue;
palColors[i][3] = 0;

if (!(red += 32))
if (!(green += 32))
blue += 64;
}

if (ppdev->ulBitCount == 8)
{
pDevInfo->hpalDefault = ppdev->hpalDefault =

EngCreatePalette(PAL_INDEXED,
NUMPALCOLORS, // cColors
(ULONG*)&palColors[0], // pulColors
0,
0,
0); // flRed, flGreen, flBlue [not used]
}
else
{
pDevInfo->hpalDefault = ppdev->hpalDefault =
EngCreatePalette(PAL_BITFIELDS, 0, NULL,
ppdev->flRed, ppdev->flGreen, ppdev->flBlue);
}

return(TRUE);
}

For driver loading I am doing like:
FillMemory(&devmode, sizeof(DEVMODE), 0);
devmode.dmSize = sizeof(DEVMODE);
devmode.dmDriverExtra = 0;
devmode.dmSpecVersion = DM_SPECVERSION;

// EZMirror Version number ex. 0x01020009 for 01.02.0009
devmode.dmDriverVersion = EZMIRROR_VER_MAJOR;
devmode.dmDriverVersion = devmode.dmDriverVersion << 4;
devmode.dmDriverVersion |= EZMIRROR_VER_MINOR;
devmode.dmDriverVersion = devmode.dmDriverVersion << 4;
devmode.dmDriverVersion |= BUILD_NUMBER;

devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_POSITION ;

devmode.dmDisplayOrientation = 0;
devmode.dmDisplayFixedOutput = 0;

_tcscpy((TCHAR*)&devmode.dmDeviceName[0], EZMIRROR_DRIVER_NAME);

if (gEZMirrorDeviceName)
{
delete gEZMirrorDeviceName;
gEZMirrorDeviceName = NULL;
}
gEZMirrorDeviceName = new TCHAR[_tcslen(&dispDevice.DeviceName[0])+1];
memset(gEZMirrorDeviceName,0,_tcslen(&dispDevice.DeviceName[0])+1);
_tcscpy(gEZMirrorDeviceName, &dispDevice.DeviceName[0]);

if(ToLoad == Load)
{
devmode.dmPelsWidth = cxPrimary;
devmode.dmPelsHeight = cyPrimary;
devmode.dmBitsPerPel = bitsPerPel;
devmode.dmPosition = position;
devmode.dmLogPixels = LogPixels;
devmode.dmPelsWidth = PelsWidth;
devmode.dmPelsHeight = PelsHeight;
devmode.dmDisplayFlags = DisplayFlags;
devmode.dmDisplayFrequency = DisplayFrequency;
devmode.dmICMMethod = ICMMethod;
devmode.dmICMIntent = ICMIntent;
devmode.dmMediaType = MediaType;
devmode.dmDitherType = DitherType;
}
else
{
devmode.dmPelsWidth = 0;
devmode.dmPelsHeight = 0;
devmode.dmBitsPerPel = 0;
devmode.dmPosition.x = 0;
devmode.dmPosition.y = 0;
devmode.dmLogPixels = 0;
devmode.dmPelsWidth = 0;
devmode.dmPelsHeight = 0;
devmode.dmDisplayFlags = 0;
devmode.dmDisplayFrequency = 0;
devmode.dmICMMethod = 0;
devmode.dmICMIntent = 0;
devmode.dmMediaType = 0;
devmode.dmDitherType = 0;
}
// Update the mirror device’s registry data with the devmode. Dont do a mode change.
INT code = ChangeDisplaySettingsEx(gEZMirrorDeviceName, &devmode, NULL, (CDS_UPDATEREGISTRY | CDS_NORESET), NULL);

// Now do the real mode change to take mirror driver changes into effect.
code = ChangeDisplaySettingsEx(NULL, NULL, NULL, 0, NULL);

Please let me know what is wrong? How to make it correct?

I used:
case WM_DISPLAYCHANGE:
{
WORD cxScreen = LOWORD(lParam);
WORD cyScreen = HIWORD(lParam);
WPARAM format = wParam;
// Add hook to re-initialize the mirror driver’s surface
if(IsEZMirrorLoaded())
{
LoadDriver(hwnd, LoadMirrorDriver); }
}
break;

and implemented DrvResetPDEV(). By this way now on resolution change my driver and application is working fine. Is this the correct way? Is there any other way? How can I make it perfectly OK?

NOTE: LoadDriver’s code is given in my previous reply.