[CMAKE]
[reactos.git] / subsystems / win32 / win32k / ntuser / display.c
index c9159ea..f5770a7 100644 (file)
 #define NDEBUG
 #include <debug.h>
 
-PDEVOBJ *gpdevPrimary;
-
-const PWCHAR KEY_ROOT = L"";
-const PWCHAR KEY_VIDEO = L"\\Registry\\Machine\\HARDWARE\\DEVICEMAP\\VIDEO";
-
-NTSTATUS
-NTAPI
-UserEnumDisplayDevices(
-    PUNICODE_STRING pustrDevice,
-    DWORD iDevNum,
-    PDISPLAY_DEVICEW pdispdev,
-    DWORD dwFlags);
-
-VOID
-RegWriteSZ(HKEY hkey, PWSTR pwszValue, PWSTR pwszData)
-{
-    UNICODE_STRING ustrValue;
-    UNICODE_STRING ustrData;
-
-    RtlInitUnicodeString(&ustrValue, pwszValue);
-    RtlInitUnicodeString(&ustrData, pwszData);
-    ZwSetValueKey(hkey, &ustrValue, 0, REG_SZ, &ustrData, ustrData.Length + sizeof(WCHAR));
-}
-
-VOID
-RegWriteDWORD(HKEY hkey, PWSTR pwszValue, DWORD dwData)
-{
-    UNICODE_STRING ustrValue;
-
-    RtlInitUnicodeString(&ustrValue, pwszValue);
-    ZwSetValueKey(hkey, &ustrValue, 0, REG_DWORD, &dwData, sizeof(DWORD));
-}
+BOOL InitSysParams();
 
+BOOL gbBaseVideo = 0;
 
-BOOL
-RegReadDWORD(HKEY hkey, PWSTR pwszValue, PDWORD pdwData)
-{
-    NTSTATUS Status;
-    ULONG cbSize = sizeof(DWORD);
-    Status = RegQueryValue(hkey, pwszValue, REG_DWORD, pdwData, &cbSize);
-    return NT_SUCCESS(Status);
-}
+static const PWCHAR KEY_ROOT = L"";
+static const PWCHAR KEY_VIDEO = L"\\Registry\\Machine\\HARDWARE\\DEVICEMAP\\VIDEO";
 
 VOID
 RegWriteDisplaySettings(HKEY hkey, PDEVMODEW pdm)
@@ -103,96 +67,12 @@ RegReadDisplaySettings(HKEY hkey, PDEVMODEW pdm)
     READ(dmPosition.y, "Attach.RelativeY", DM_POSITION);
 }
 
-
-enum
-{
-    VF_USEVGA = 0x1,
-};
-
-BOOL
-InitDisplayDriver(
-    PUNICODE_STRING pustrRegPath,
-    FLONG flags)
-{
-//    PWSTR pwszDriverName;
-    RTL_QUERY_REGISTRY_TABLE QueryTable[2];
-    NTSTATUS Status;
-
-    /* Setup QueryTable for direct registry query */
-    RtlZeroMemory(QueryTable, sizeof(QueryTable));
-    QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED|RTL_QUERY_REGISTRY_DIRECT;
-
-
-    /* Check if vga mode is requested */
-    if (flags & VF_USEVGA)
-    {
-        DWORD dwVgaCompatible;
-
-        /*  */
-        QueryTable[0].Name = L"VgaCompatible";
-        QueryTable[0].EntryContext = &dwVgaCompatible;
-
-        /* Check if the driver is vga */
-        Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
-                                        pustrRegPath->Buffer,
-                                        QueryTable,
-                                        NULL,
-                                        NULL);
-
-        if (!dwVgaCompatible)
-        {
-            /* This driver is not a vga driver */
-            return FALSE;
-        }
-    }
-
-#if 0
-
-    /* Query the adapter's registry path */
-    swprintf(awcBuffer, L"\\Device\\Video%lu", iDevNum);
-    QueryTable[0].Name = pGraphicsDevice->szNtDeviceName;
-
-    /* Set string for the registry key */
-    ustrRegistryPath.Buffer = pdispdev->DeviceKey;
-    ustrRegistryPath.Length = 128;
-    ustrRegistryPath.MaximumLength = 128;
-    QueryTable[0].EntryContext = &ustrRegistryPath;
-
-    /* Query the registry */
-    Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP,
-                                    L"VIDEO",
-                                    QueryTable,
-                                    NULL,
-                                    NULL);
-
-    RegQueryValue(KEY_VIDEO, awcBuffer, REG_SZ, pdispdev->DeviceKey, 256);
-
-    {
-        HANDLE hmod;
-
-        hmod = EngLoadImage(pwszDriverName);
-
-        /* Jump to next name */
-        pwszDriverName += wcslen(pwszDriverName) + 1;
-    }
-    while (pwszDriverName < 0);
-#endif
-
-    return 0;
-}
-
-
-NTSTATUS
+PGRAPHICS_DEVICE
 NTAPI
-DisplayDriverQueryRoutine(
-    IN PWSTR ValueName,
-    IN ULONG ValueType,
-    IN PVOID ValueData,
-    IN ULONG ValueLength,
-    IN PVOID Context,
-    IN PVOID EntryContext)
+InitDisplayDriver(
+    IN PWSTR pwszDeviceName,
+    IN PWSTR pwszRegKey)
 {
-    PWSTR pwszRegKey = ValueData;
     PGRAPHICS_DEVICE pGraphicsDevice;
     UNICODE_STRING ustrDeviceName, ustrDisplayDrivers, ustrDescription;
     NTSTATUS Status;
@@ -201,32 +81,17 @@ DisplayDriverQueryRoutine(
     HKEY hkey;
     DEVMODEW dmDefault;
 
-    UNREFERENCED_PARAMETER(ValueLength);
-    UNREFERENCED_PARAMETER(Context);
-    UNREFERENCED_PARAMETER(EntryContext);
-
-    DPRINT1("DisplayDriverQueryRoutine(%S, %S);\n",
-            ValueName, pwszRegKey);
-
-    /* Check if we have a correct entry */
-    if (ValueType != REG_SZ || ValueName[0] != '\\')
-    {
-        /* Something else, just skip it */
-        return STATUS_SUCCESS;
-    }
+    DPRINT1("InitDisplayDriver(%S, %S);\n",
+            pwszDeviceName, pwszRegKey);
 
     /* Open the driver's registry key */
     Status = RegOpenKey(pwszRegKey, &hkey);
     if (!NT_SUCCESS(Status))
     {
-        DPRINT1("Failed to open registry key\n");
-        return STATUS_SUCCESS;
+        DPRINT1("Failed to open registry key: %ls\n", pwszRegKey);
+        return NULL;
     }
 
-// HACK: only use 1st adapter
-//if (ValueName[13] != '0')
-//    return STATUS_SUCCESS;
-
     /* Query the diplay drivers */
     cbSize = sizeof(awcBuffer) - 10;
     Status = RegQueryValue(hkey,
@@ -238,7 +103,7 @@ DisplayDriverQueryRoutine(
     {
         DPRINT1("Didn't find 'InstalledDisplayDrivers', status = 0x%lx\n", Status);
         ZwClose(hkey);
-        return STATUS_SUCCESS;
+        return NULL;
     }
 
     /* Initialize the UNICODE_STRING */
@@ -273,44 +138,134 @@ DisplayDriverQueryRoutine(
     ZwClose(hkey);
 
     /* Register the device with GDI */
-    RtlInitUnicodeString(&ustrDeviceName, ValueName);
+    RtlInitUnicodeString(&ustrDeviceName, pwszDeviceName);
     pGraphicsDevice = EngpRegisterGraphicsDevice(&ustrDeviceName,
                                                  &ustrDisplayDrivers,
                                                  &ustrDescription,
                                                  &dmDefault);
 
-    // FIXME: what to do with pGraphicsDevice?
-
-    return STATUS_SUCCESS;
+    return pGraphicsDevice;
 }
 
-BOOL InitSysParams();
-
-BOOL
-InitVideo(FLONG flags)
+NTSTATUS
+NTAPI
+InitVideo()
 {
-    RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+    ULONG iDevNum, iVGACompatible = -1, ulMaxObjectNumber = 0;
+    WCHAR awcDeviceName[20];
+    WCHAR awcBuffer[256];
     NTSTATUS Status;
+    PGRAPHICS_DEVICE pGraphicsDevice;
+    ULONG cbValue;
+    HKEY hkey;
+
+    DPRINT("----------------------------- InitVideo() -------------------------------\n");
+
+    /* Open the key for the boot command line */
+    Status = RegOpenKey(L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control", &hkey);
+    if (NT_SUCCESS(Status))
+    {
+        cbValue = 256;
+        Status = RegQueryValue(hkey, L"SystemStartOptions", REG_SZ, awcBuffer, &cbValue);
+        if (NT_SUCCESS(Status))
+        {
+            /* Check if VGA mode is requested. */
+            if (wcsstr(awcBuffer, L"/BASEVIDEO") != 0)
+            {
+                DPRINT1("VGA mode requested.\n");
+                gbBaseVideo = TRUE;
+            }
+        }
+
+        ZwClose(hkey);
+    }
 
-    DPRINT1("----------------------------- InitVideo() -------------------------------\n");
+    /* Open the key for the adapters */
+    Status = RegOpenKey(KEY_VIDEO, &hkey);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Could not open device registry key!\n");
+        return Status;
+    }
 
-    /* Setup QueryTable for registry query */
-    RtlZeroMemory(QueryTable, sizeof(QueryTable));
-    QueryTable[0].QueryRoutine = DisplayDriverQueryRoutine;
+    /* Read the name of the VGA adapter */
+    cbValue = 20;
+    Status = RegQueryValue(hkey, L"VgaCompatible", REG_SZ, awcDeviceName, &cbValue);
+    if (NT_SUCCESS(Status))
+    {
+        iVGACompatible = _wtoi(&awcDeviceName[13]);
+        DPRINT1("VGA adapter = %ld\n", iVGACompatible);
+    }
+
+    /* Get the maximum mumber of adapters */
+    if (!RegReadDWORD(hkey, L"MaxObjectNumber", &ulMaxObjectNumber))
+    {
+        DPRINT1("Could not read MaxObjectNumber, defaulting to 0.\n");
+    }
 
-    /* Query the registry */
-    Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP,
-                                    L"VIDEO",
-                                    QueryTable,
-                                    NULL,
-                                    NULL);
+    DPRINT("Found %ld devices\n", ulMaxObjectNumber);
+
+    /* Loop through all adapters */
+    for (iDevNum = 0; iDevNum <= ulMaxObjectNumber; iDevNum++)
+    {
+        /* Create the adapter's key name */
+        swprintf(awcDeviceName, L"\\Device\\Video%lu", iDevNum);
+
+        /* Read the reg key name */
+        cbValue = sizeof(awcBuffer);
+        Status = RegQueryValue(hkey, awcDeviceName, REG_SZ, awcBuffer, &cbValue);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("failed to query the registry path:0x%lx\n", Status);
+            continue;
+        }
+
+        /* Initialize the driver for this device */
+        pGraphicsDevice = InitDisplayDriver(awcDeviceName, awcBuffer);
+        if (!pGraphicsDevice) continue;
+
+        /* Check if this is the VGA adapter */
+        if (iDevNum == iVGACompatible)
+        {
+            /* Set the VGA device as primary */
+            gpVgaGraphicsDevice = pGraphicsDevice;
+            DPRINT1("gpVgaGraphicsDevice = %p\n", gpVgaGraphicsDevice);
+        }
+
+        /* Set the first one as primary device */
+        if (!gpPrimaryGraphicsDevice)
+            gpPrimaryGraphicsDevice = pGraphicsDevice;
+    }
+
+    /* Close the device map registry key */
+    ZwClose(hkey);
+
+    /* Check if we had any success */
+    if (!gpPrimaryGraphicsDevice)
+    {
+        DPRINT1("No usable display driver was found.\n");
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    if (gbBaseVideo)
+    {
+        if (gpVgaGraphicsDevice)
+        {
+            /* Set the VgaAdapter as primary */
+            gpPrimaryGraphicsDevice = gpVgaGraphicsDevice;
+            // FIXME: DEVMODE
+        }
+        else
+        {
+            DPRINT1("Could not find VGA compatible driver. Trying normal.\n");
+        }
+    }
 
     InitSysParams();
 
-    return 0;
+    return 1;
 }
 
-
 NTSTATUS
 NTAPI
 UserEnumDisplayDevices(
@@ -377,8 +332,8 @@ NtUserEnumDisplayDevices(
     DISPLAY_DEVICEW dispdev;
     NTSTATUS Status;
 
-    DPRINT1("Enter NtUserEnumDisplayDevices(%p, %ls, %ld)\n",
-            pustrDevice, pustrDevice ? pustrDevice->Buffer : 0, iDevNum);
+    DPRINT("Enter NtUserEnumDisplayDevices(%wZ, %ld)\n",
+           pustrDevice, iDevNum);
 
     // FIXME: HACK, desk.cpl passes broken crap
     if (pustrDevice && iDevNum != 0)
@@ -490,31 +445,32 @@ UserEnumDisplaySettings(
     PDEVMODEENTRY pdmentry;
     ULONG i, iFoundMode;
 
-    DPRINT1("Enter UserEnumDisplaySettings('%ls', %ld)\n",
+    DPRINT("Enter UserEnumDisplaySettings('%ls', %ld)\n",
             pustrDevice ? pustrDevice->Buffer : NULL, iModeNum);
 
     /* Ask gdi for the GRAPHICS_DEVICE */
     pGraphicsDevice = EngpFindGraphicsDevice(pustrDevice, 0, 0);
+
     if (!pGraphicsDevice)
     {
         /* No device found */
         DPRINT1("No device found!\n");
-        return FALSE;
+        return STATUS_UNSUCCESSFUL;
     }
 
-    if (iModeNum == 0)
-    {
-        DPRINT1("Should initialize modes somehow\n");
-        // Update DISPLAY_DEVICEs?
-    }
+    if (iModeNum >= pGraphicsDevice->cDevModes)
+        return STATUS_NO_MORE_ENTRIES;
 
     iFoundMode = 0;
     for (i = 0; i < pGraphicsDevice->cDevModes; i++)
     {
         pdmentry = &pGraphicsDevice->pDevModeList[i];
 
-//        if ((!(dwFlags & EDS_RAWMODE) && (pdmentry->dwFlags & 1)) || // FIXME!
-//            (dwFlags & EDS_RAWMODE))
+        /* FIXME: consider EDS_RAWMODE */
+#if 0
+        if ((!(dwFlags & EDS_RAWMODE) && (pdmentry->dwFlags & 1)) ||!
+            (dwFlags & EDS_RAWMODE))
+#endif
         {
             /* Is this the one we want? */
             if (iFoundMode == iModeNum)
@@ -596,7 +552,7 @@ NtUserEnumDisplaySettings(
     DEVMODEW dmReg, *pdm;
 
     DPRINT1("Enter NtUserEnumDisplaySettings(%ls, %ld)\n",
-            pustrDevice ? pustrDevice->Buffer:0, iModeNum);
+            pustrDevice ? pustrDevice->Buffer : 0, iModeNum);
 
     if (pustrDevice)
     {
@@ -728,8 +684,12 @@ UserChangeDisplaySettings(
     }
 
     /* Fixup values */
-    if((dm.dmFields & DM_BITSPERPEL) && (dm.dmBitsPerPel == 0))
+    if(dm.dmBitsPerPel == 0 || !(dm.dmFields & DM_BITSPERPEL))
+    {
         dm.dmBitsPerPel = ppdev->pdmwDev->dmBitsPerPel;
+        dm.dmFields |= DM_BITSPERPEL;
+    }
+
     if((dm.dmFields & DM_DISPLAYFREQUENCY) && (dm.dmDisplayFrequency == 0))
         dm.dmDisplayFrequency = ppdev->pdmwDev->dmDisplayFrequency;