[WIN32K]
[reactos.git] / subsystems / win32 / win32k / ntuser / display.c
index 89b926a..7616abe 100644 (file)
@@ -6,7 +6,7 @@
  * PROGRAMER:        Timo Kreuzer (timo.kreuzer@reactos.org)
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #include <intrin.h>
 
@@ -91,8 +91,8 @@ RegReadDisplaySettings(HKEY hkey, PDEVMODEW pdm)
 
     /* Read all present settings */
     READ(dmBitsPerPel, "DefaultSettings.BitsPerPel", DM_BITSPERPEL);
-    READ(dmPelsWidth, "DefaultSettings.XResolution", DM_YRESOLUTION); // DM_XRESOLUTION?
-    READ(dmPelsHeight, "DefaultSettings.YResolution", DM_YRESOLUTION);
+    READ(dmPelsWidth, "DefaultSettings.XResolution", DM_PELSWIDTH);
+    READ(dmPelsHeight, "DefaultSettings.YResolution", DM_PELSHEIGHT);
     READ(dmDisplayFlags, "DefaultSettings.Flags", DM_DISPLAYFLAGS);
     READ(dmDisplayFrequency, "DefaultSettings.VRefresh", DM_DISPLAYFREQUENCY);
     READ(dmPanningWidth, "DefaultSettings.XPanning", DM_PANNINGWIDTH);
@@ -569,8 +569,15 @@ UserEnumRegistryDisplaySettings(
     IN PUNICODE_STRING pustrDevice,
     OUT LPDEVMODEW pdm)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    HKEY hkey;
+    NTSTATUS Status = UserOpenDisplaySettingsKey(&hkey, pustrDevice, 0);
+    if(NT_SUCCESS(Status))
+    {
+        RegReadDisplaySettings(hkey, pdm);
+        ZwClose(hkey);
+        return STATUS_SUCCESS;
+    }
+    return Status ;
 }
 
 
@@ -648,11 +655,8 @@ NtUserEnumDisplaySettings(
             cbExtra = lpDevMode->dmDriverExtra;
 
             ProbeForWrite(lpDevMode, cbSize + cbExtra, 1);
-            lpDevMode->dmPelsWidth = pdm->dmPelsWidth;
-            lpDevMode->dmPelsHeight = pdm->dmPelsHeight;
-            lpDevMode->dmBitsPerPel = pdm->dmBitsPerPel;
-            lpDevMode->dmDisplayFrequency = pdm->dmDisplayFrequency;
-            lpDevMode->dmDisplayFlags = pdm->dmDisplayFlags;
+            /* Output what we got */
+            RtlCopyMemory(lpDevMode, pdm, min(cbSize, pdm->dmSize));
 
             /* output private/extra driver data */
             if (cbExtra > 0 && pdm->dmDriverExtra > 0)
@@ -674,6 +678,7 @@ NtUserEnumDisplaySettings(
 
 BOOL APIENTRY UserClipCursor(RECTL *prcl);
 VOID APIENTRY UserRedrawDesktop();
+HCURSOR FASTCALL UserSetCursor(PCURICON_OBJECT NewCursor, BOOL ForceChange);
 
 LONG
 APIENTRY
@@ -684,7 +689,7 @@ UserChangeDisplaySettings(
    DWORD flags,
    LPVOID lParam)
 {
-    DEVMODEW dmReg;
+    DEVMODEW dm;
     LONG lResult = DISP_CHANGE_SUCCESSFUL;
     HKEY hkey;
     NTSTATUS Status;
@@ -695,13 +700,23 @@ UserChangeDisplaySettings(
     if (!pdm)
     {
         /* Get the registry settings */
-        Status = UserEnumRegistryDisplaySettings(pustrDevice, &dmReg);
+        Status = UserEnumRegistryDisplaySettings(pustrDevice, &dm);
         if (!NT_SUCCESS(Status))
         {
             DPRINT1("Could not load registry settings\n");
             return DISP_CHANGE_BADPARAM;
         }
-        pdm = &dmReg;
+    }
+    else if (pdm->dmSize < FIELD_OFFSET(DEVMODEW, dmFields))
+        return DISP_CHANGE_FAILED;
+    else
+        dm = *pdm;
+
+    /* Check params */
+    if ((dm.dmFields & (DM_PELSWIDTH | DM_PELSHEIGHT)) != (DM_PELSWIDTH | DM_PELSHEIGHT))
+    {
+        DPRINT1("devmode doesn't specify the resolution.\n");
+        return DISP_CHANGE_BADMODE;
     }
 
     /* Get the PDEV */
@@ -712,14 +727,26 @@ UserChangeDisplaySettings(
         return DISP_CHANGE_BADPARAM;
     }
 
+    /* Fixup values */
+    if((dm.dmFields & DM_BITSPERPEL) && (dm.dmBitsPerPel == 0))
+        dm.dmBitsPerPel = ppdev->pdmwDev->dmBitsPerPel;
+    if((dm.dmFields & DM_DISPLAYFREQUENCY) && (dm.dmDisplayFrequency == 0))
+        dm.dmDisplayFrequency = ppdev->pdmwDev->dmDisplayFrequency;
+
     /* Look for the requested DEVMODE */
-    pdm = PDEVOBJ_pdmMatchDevMode(ppdev, pdm);
+    pdm = PDEVOBJ_pdmMatchDevMode(ppdev, &dm);
     if (!pdm)
     {
         DPRINT1("Could not find a matching DEVMODE\n");
         lResult = DISP_CHANGE_BADMODE;
         goto leave;
     }
+    else if (flags & CDS_TEST)
+    {
+        /* It's possible, go ahead! */
+        lResult = DISP_CHANGE_SUCCESSFUL;
+        goto leave;
+    }
 
     /* Shall we update the registry? */
     if (flags & CDS_UPDATEREGISTRY)
@@ -753,7 +780,17 @@ UserChangeDisplaySettings(
     {
         ULONG ulResult;
 
-        if (!PDEVOBJ_bSwitchMode(ppdev, pdm))
+        /* Remove mouse pointer */
+        UserSetCursor(NULL, TRUE);
+
+        /* Do the mode switch */
+        ulResult = PDEVOBJ_bSwitchMode(ppdev, pdm);
+
+        /* Restore mouse pointer, no hooks called */
+        UserSetCursorPos(gpsi->ptCursor.x, gpsi->ptCursor.y, FALSE);
+
+        /* Check for failure */
+        if (!ulResult)
         {
             DPRINT1("failed to set mode\n");
             lResult = (lResult == DISP_CHANGE_NOTUPDATED) ?
@@ -765,24 +802,24 @@ UserChangeDisplaySettings(
         /* Update the system metrics */
         InitMetrics();
 
+        //IntvGetDeviceCaps(&PrimarySurface, &GdiHandleTable->DevCaps);
+
         /* Remove all cursor clipping */
         UserClipCursor(NULL);
 
-        //IntvGetDeviceCaps(&PrimarySurface, &GdiHandleTable->DevCaps);
-
         pdesk = IntGetActiveDesktop();
-        IntHideDesktop(pdesk);
+        //IntHideDesktop(pdesk);
 
         /* Send WM_DISPLAYCHANGE to all toplevel windows */
         co_IntSendMessageTimeout(HWND_BROADCAST,
                                  WM_DISPLAYCHANGE,
                                  (WPARAM)ppdev->gdiinfo.cBitsPixel,
-                                 (LPARAM)(ppdev->gdiinfo.ulHorzRes + (ppdev->gdiinfo.ulHorzRes << 16)),
+                                 (LPARAM)(ppdev->gdiinfo.ulHorzRes + (ppdev->gdiinfo.ulVertRes << 16)),
                                  SMTO_NORMAL,
                                  100,
                                  &ulResult);
 
-        co_IntShowDesktop(pdesk, ppdev->gdiinfo.ulHorzRes, ppdev->gdiinfo.ulVertRes);
+        //co_IntShowDesktop(pdesk, ppdev->gdiinfo.ulHorzRes, ppdev->gdiinfo.ulVertRes);
 
         UserRedrawDesktop();
     }