Author: cfinck
Date: Fri Aug 3 16:10:43 2007
New Revision: 28127
URL:
http://svn.reactos.org/svn/reactos?rev=28127&view=rev
Log:
Check if the same Monitor ID (= 10 bytes from the EDID, which can be used to uniquely
identify a monitor) appears two times and stop the enumeration in this case.
This is needed for some older monitors (1994-1999), which transmit the EDID data according
to the VBE/DDC Standard 1.0.
We assumed that the function for reading the EDID fails, when we input higher controller
unit numbers, but some older monitors don't care about the controller unit number and
always return valid EDID data.
More information is available at:
http://www.vesa.org/public/VBE/VBEDDC11.PDF
See issue #2239 for more details.
Modified:
trunk/reactos/drivers/video/videoprt/videoprt.c
Modified: trunk/reactos/drivers/video/videoprt/videoprt.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/video/videoprt/vid…
==============================================================================
--- trunk/reactos/drivers/video/videoprt/videoprt.c (original)
+++ trunk/reactos/drivers/video/videoprt/videoprt.c Fri Aug 3 16:10:43 2007
@@ -1100,6 +1100,8 @@
ULONG Status;
VIDEO_CHILD_ENUM_INFO ChildEnumInfo;
VIDEO_CHILD_TYPE ChildType;
+ BOOLEAN bHaveLastMonitorID = FALSE;
+ UCHAR LastMonitorID[10];
UCHAR ChildDescriptor[256];
ULONG ChildId;
ULONG Unused;
@@ -1131,7 +1133,37 @@
ChildDescriptor,
&ChildId,
&Unused);
- if (Status == VIDEO_ENUM_INVALID_DEVICE)
+ if (Status == VIDEO_ENUM_MORE_DEVICES)
+ {
+ if (ChildType == Monitor)
+ {
+ // Check if the EDID is valid
+ if (ChildDescriptor[0] == 0x00 &&
+ ChildDescriptor[1] == 0xFF &&
+ ChildDescriptor[2] == 0xFF &&
+ ChildDescriptor[3] == 0xFF &&
+ ChildDescriptor[4] == 0xFF &&
+ ChildDescriptor[5] == 0xFF &&
+ ChildDescriptor[6] == 0xFF &&
+ ChildDescriptor[7] == 0x00)
+ {
+ if (bHaveLastMonitorID)
+ {
+ // Compare the previous monitor ID with the current one, break the loop
if they are identical
+ if (RtlCompareMemory(LastMonitorID, &ChildDescriptor[8],
sizeof(LastMonitorID)) == sizeof(LastMonitorID))
+ {
+ DPRINT("Found identical Monitor ID two times, stopping
enumeration\n");
+ break;
+ }
+ }
+
+ // Copy 10 bytes from the EDID, which can be used to uniquely identify the
monitor
+ RtlCopyMemory(LastMonitorID, &ChildDescriptor[8],
sizeof(LastMonitorID));
+ bHaveLastMonitorID = TRUE;
+ }
+ }
+ }
+ else if (Status == VIDEO_ENUM_INVALID_DEVICE)
{
DPRINT("Child device %d is invalid!\n", ChildEnumInfo.ChildIndex);
continue;
@@ -1141,7 +1173,7 @@
DPRINT("End of child enumeration! (%d children enumerated)\n", i -
1);
break;
}
- else if (Status != VIDEO_ENUM_MORE_DEVICES)
+ else
{
DPRINT("HwGetVideoChildDescriptor returned unknown status code
0x%x!\n", Status);
break;