Hi.
I’m writing Mirror Display Driver.
And I want to ask about, how to get informed in driver when screen resolution is changing?
I thought that DrvAssertMode calls when resolution is changing, but as I have understood, that it doesn’t happens.
I need to catch this event, because I’m using mapped memory for surface and I need to reallocate with conformity of new settings.
Hi:
How about to write a user mode window program which hooks WM_DISPLAYCHANGE
message, you can get the resolution setting of primary display in that
mesage handler. And of course, you can pass the new resolutoin value to your
mirror display driver by DrvEscape or by ChangeDisplaySettingEx.
Lear
在郵件 news:xxxxx@ntdev ä¸æ’°å¯«…
> Hi.
> I’m writing Mirror Display Driver.
> And I want to ask about, how to get informed in driver when screen
> resolution is changing?
> I thought that DrvAssertMode calls when resolution is changing, but as I
> have understood, that it doesn’t happens.
> I need to catch this event, because I’m using mapped memory for surface
> and I need to reallocate with conformity of new settings.
>
>
It is theoretically possible, but
I think this method isn’t best, because it can rise unexpected bugs and I think if I use this method I need to ask user app for changes every second or more often and that isn’t good too.
I think there is another way to know about this event inside the driver, but I don’t know it.
Does anyone know different method?
> -----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: 13 July 2007 13:59
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Mirror driver - how to catch event when
screen resolution is changing?It is theoretically possible, but
I think this method isn’t best, because it can rise
unexpected bugs and I think if I use this method I need to
ask user app for changes every second or more often and that
isn’t good too.
I think there is another way to know about this event inside
the driver, but I don’t know it.
Does anyone know different method?
Listening for WM_DISPLAYCHANGE in your user mode application’s windows
message parsing loop shouldn’t be a drain on CPU reasorces. Then when
you do get that message you can call ChangeDisplaySettingEx on your
driver to change to a matching mode.
Unfortunately mirror drivers are not told about mode changes on the
primary screen - that would be too easy!
Good luck,
Tim Green
Development Engineer
DisplayLink (UK) Limited
Tim, thank you. This is the best way.
Emm. Tim, could you explain what params I need to pass to ChangeDisplaySettingsEx function.
I tried to use it but as I understood I pass wrong params and that why I don’t call DrvAssertMode function in the driver.
I have made this not working code
FillMemory(@devmode,sizeof(TDeviceMode),0);
devmode.dmSize= sizeof(TDisplayDeviceA);
devmode.dmDriverExtra= 0;
devmode.dmFields= DM_BITSPERPEL or
DM_PELSWIDTH or
DM_PELSHEIGHT;
ChangeDisplaySettingsEx(@deviceName[1],
devmode,
0,
0,
nil
);
xxxxx@gmail.com wrote:
Emm. Tim, could you explain what params I need to pass to ChangeDisplaySettingsEx function.
I tried to use it but as I understood I pass wrong params and that why I don’t call DrvAssertMode function in the driver.
I have made this not working code
FillMemory(@devmode,sizeof(TDeviceMode),0);
devmode.dmSize= sizeof(TDisplayDeviceA);
devmode.dmDriverExtra= 0;
devmode.dmFields= DM_BITSPERPEL or
DM_PELSWIDTH or
DM_PELSHEIGHT;
Did you actually set dmBitsPerPel, dmPelsWidth and dmPelsHeight? You
don’t show it here.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
Probably no, but this line(s)
devmode.dmFields= DM_BITSPERPEL or
DM_PELSWIDTH or
DM_PELSHEIGHT;
isn’t the same?
> FillMemory(@devmode,sizeof(TDeviceMode),0);
Yikes! Spot the difference:
void FillMemory(PVOID Destination, SIZE_T Length, BYTE Fill);
void *memset(void *s, int c, size_t n);
You are using FillMemory correctly, but does anybody know why Microsoft wanted to be perverse and create a new memory filling function with size and data swapped?
devmode.dmSize= sizeof(TDisplayDeviceA);
Why TDisplayDeviceA instead of TDeviceMode?
So, you’ve set all the fields to zero, and then set the size field and the flag field. Are you trying to disable your mirror driver (zero width and height)?
Tim Green.
DisplayLink Ltd.
xxxxx@gmail.com wrote:
Probably no, but this line(s)
> devmode.dmFields= DM_BITSPERPEL or
> DM_PELSWIDTH or
> DM_PELSHEIGHT;
>
isn’t the same?
No, of course not. That line tells the system which fields have good
data. Settings DM_BITSPERPIXEL means that the system should use the
value in devmode.dmBitsPixel. Without DM_BITSPERPIXEL, it won’t even
look there.
So, what you have done there is request a 0x0 display at 0 bits per
pixel. Is that what you wanted?
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
I’m using Delphi language, that why this code is differs from C++.
No I want just inform my driver and call DrvAssertMode function inside the driver to reallocate memory which my driver using for surface.
In my app I catch WM_DISPLAYCHANGE message.
So I need to fill devmode variable correctly and other params.
Could you tell me please, with what params I need to call ChangeDisplaySettingsEx function?
I tried but It’s not calling DrvAssertMode function.
xxxxx@gmail.com wrote:
I’m using Delphi language, that why this code is differs from C++.
His FillMemory comment applies to C as well as Delphi. However, his
comment is correct. You’re doing this:
FillMemory(@devmode,sizeof(TDeviceMode),0);
devmode.dmSize := sizeof(TDisplayDeviceA);
Why are you setting dmSize to sizeof(TDisplayDeviceA) instead of
sizeof(TDeviceMode)? Those are two different and unrelated structures.
GDI decides how to handle your structure by checking the length. If
your length doesn’t match what it knows, it won’t do anything with it.
No I want just inform my driver and call DrvAssertMode function inside the driver to reallocate memory which my driver using for surface.
In my app I catch WM_DISPLAYCHANGE message.
So I need to fill devmode variable correctly and other params.
Could you tell me please, with what params I need to call ChangeDisplaySettingsEx function?
I told you that in the first message. When you set DM_BITSPERPEL, you
need to set devmode.dmBitsPerPel to the depth you want. When you set
DM_PELSWIDTH, you need to set devmode.dmPelsWidth to the width you
want. when you set DM_PELSHEIGHT, you need to set devmode.dmPelsHeight
to the height you want.
If you just want to reuse the current settings in the registry, pass nil
for the devmode and set dwFlags to 0.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.
Ok. Tim you are right.
But it’s still not working because something wrong.
Could you say are this params are correct?
ChangeDisplaySettingsExN(@deviceName[1],
nil,
0,
0,
nil
);
Tim, Maybe I do something wrong in my code.
But If I just take not modified code samples from src\video\displays\mirror and compile them and then I install driver and run app from src\video\displays\mirror\app which have also in code
code = ChangeDisplaySettingsEx(deviceName,
&devmode,
NULL,
0,
NULL
);
I don’t see in DebugView that DrvAssertMode is call.
But in output I see
“Raw dynamic mode change on device mode: Change Successful”
I don’t get it, why DrvAssertMode isn’t calling?
Am I doing in the right direction?
Does every time DrvAssertMode function must get called when I call ChangeDisplaySettingsEx function?
Ok. I have achieved a call of DrvAssertMode.
I did this code (Delphi)
ChangeDisplaySettingsEx(@deviceName[1],
PDeviceMode(nil)^,
0,
CDS_RESET,
nil
);
But I don’t know how to do now.
I want to call DrvDisableSurface and then DrvEnableSurface to reallocate memory and as I can see I can’t call them from DrvAssertMode.
Tim, could you tell me please, which way I need to do?
On Sun, Jul 22, 2007 at 11:09:45AM -0400, xxxxx@gmail.com wrote:
Ok. I have achieved a call of DrvAssertMode.
I did this code (Delphi)
ChangeDisplaySettingsEx(@deviceName[1],
PDeviceMode(nil)^,
0,
CDS_RESET,
nil
);
But I don’t know how to do now.
I want to call DrvDisableSurface and then DrvEnableSurface to reallocate
memory and as I can see I can’t call them from DrvAssertMode.
No, of course not, those are routines that GDI calls. What is the point?
What are you actually trying to accomplish here? You should
only need to reallocate your surface when the surface size changes, and
in that case the operating system should call the right rountines for
you.
Tim Roberts, xxxxx@probo.com
Providenza & Boeklheide, Inc.
>What are you actually trying to accomplish here?
I want that if user change screen resolution, the driver not crush.
What do you mean “your surface”?
As I can see here I need to reallocate two memories:
- Mirror Driver surface memory
- Memory for changes
I know how to reallocate 2, but I can’t understand how can I reallocate 1.
When user changes his screen resolution, the screen becomes more bigger(or smaller) and in consequence of that I need to allocate more (or less) memory for my “mask of changes”(this memory where I store changes).
If user changes to less than existing resolution, that’s not a big problem but if user changes to bigger resolution, the mirror driver will crush because it will write to not allocated memory.
This problem I have been tried to solve.
Here what I do
I catch every WM_DISPLAYCHANGE event and then I call
ChangeDisplaySettingsEx(@deviceName[1],
PDeviceMode(nil)^,
0,
CDS_RESET,
nil
);
And then DrvAssertMode in the driver get called.
As I have understood I need to reallocate this memory here in DrvAssertMode or I need to do something else?
Sorry if I say something wrong.
It is very difficult to me to find a way in blind first time a correct way, could anyone can give me advice please.
Do I need to reallocate surface memory in DrvAssertMode routine?