Esempio n. 1
0
LONG
APIENTRY
UserChangeDisplaySettings(
   PUNICODE_STRING pustrDevice,
   LPDEVMODEW pdm,
   HWND hwnd,
   DWORD flags,
   LPVOID lParam)
{
    DEVMODEW dm;
    LONG lResult = DISP_CHANGE_SUCCESSFUL;
    HKEY hkey;
    NTSTATUS Status;
    PPDEVOBJ ppdev;
    //PDESKTOP pdesk;

    /* If no DEVMODE is given, use registry settings */
    if (!pdm)
    {
        /* Get the registry settings */
        Status = UserEnumRegistryDisplaySettings(pustrDevice, &dm);
        if (!NT_SUCCESS(Status))
        {
            ERR("Could not load registry settings\n");
            return DISP_CHANGE_BADPARAM;
        }
    }
    else if (pdm->dmSize < FIELD_OFFSET(DEVMODEW, dmFields))
        return DISP_CHANGE_BADMODE; /* This is what winXP SP3 returns */
    else
        dm = *pdm;

    /* Check params */
    if ((dm.dmFields & (DM_PELSWIDTH | DM_PELSHEIGHT)) != (DM_PELSWIDTH | DM_PELSHEIGHT))
    {
        ERR("Devmode doesn't specify the resolution.\n");
        return DISP_CHANGE_BADMODE;
    }

    /* Get the PDEV */
    ppdev = EngpGetPDEV(pustrDevice);
    if (!ppdev)
    {
        ERR("Failed to get PDEV\n");
        return DISP_CHANGE_BADPARAM;
    }

    /* Fixup values */
    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;

    /* Look for the requested DEVMODE */
    pdm = PDEVOBJ_pdmMatchDevMode(ppdev, &dm);
    if (!pdm)
    {
        ERR("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)
    {
        /* Open the local or global settings key */
        Status = UserOpenDisplaySettingsKey(&hkey, pustrDevice, flags & CDS_GLOBAL);
        if (NT_SUCCESS(Status))
        {
            /* Store the settings */
            RegWriteDisplaySettings(hkey, pdm);

            /* Close the registry key */
            ZwClose(hkey);
        }
        else
        {
            ERR("Could not open registry key\n");
            lResult = DISP_CHANGE_NOTUPDATED;
        }
    }

    /* Check if DEVMODE matches the current mode */
    if (pdm == ppdev->pdmwDev && !(flags & CDS_RESET))
    {
        ERR("DEVMODE matches, nothing to do\n");
        goto leave;
    }

    /* Shall we apply the settings? */
    if (!(flags & CDS_NORESET))
    {
        ULONG ulResult;
        PVOID pvOldCursor;

        /* Remove mouse pointer */
        pvOldCursor = UserSetCursor(NULL, TRUE);

        /* Do the mode switch */
        ulResult = PDEVOBJ_bSwitchMode(ppdev, pdm);

        /* Restore mouse pointer, no hooks called */
        UserSetCursor(pvOldCursor, TRUE);

        /* Check for failure */
        if (!ulResult)
        {
            ERR("Failed to set mode\n");
            lResult = (lResult == DISP_CHANGE_NOTUPDATED) ?
                DISP_CHANGE_FAILED : DISP_CHANGE_RESTART;

            goto leave;
        }

        /* Update the system metrics */
        InitMetrics();

        //IntvGetDeviceCaps(&PrimarySurface, &GdiHandleTable->DevCaps);

        /* Set new size of the monitor */
        UserUpdateMonitorSize((HDEV)ppdev);

        /* Remove all cursor clipping */
        UserClipCursor(NULL);

        //pdesk = IntGetActiveDesktop();
        //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.ulVertRes << 16)),
                                 SMTO_NORMAL,
                                 100,
                                 &ulResult);

        //co_IntShowDesktop(pdesk, ppdev->gdiinfo.ulHorzRes, ppdev->gdiinfo.ulVertRes);

        UserRedrawDesktop();
    }

leave:
    /* Release the PDEV */
    PDEVOBJ_vRelease(ppdev);

    return lResult;
}
Esempio n. 2
0
static
PPDEVOBJ
EngpCreatePDEV(
    PUNICODE_STRING pustrDeviceName,
    PDEVMODEW pdm)
{
    PGRAPHICS_DEVICE pGraphicsDevice;
    PPDEVOBJ ppdev;

    /* Try to find the GRAPHICS_DEVICE */
    if (pustrDeviceName)
    {
        pGraphicsDevice = EngpFindGraphicsDevice(pustrDeviceName, 0, 0);
        if (!pGraphicsDevice)
        {
            DPRINT1("No GRAPHICS_DEVICE found for %ls!\n",
                    pustrDeviceName ? pustrDeviceName->Buffer : 0);
            return NULL;
        }
    }
    else
    {
        pGraphicsDevice = gpPrimaryGraphicsDevice;
    }

    /* Allocate a new PDEVOBJ */
    ppdev = PDEVOBJ_AllocPDEV();
    if (!ppdev)
    {
        DPRINT1("failed to allocate a PDEV\n");
        return NULL;
    }

    /* If no DEVMODEW is given, ... */
    if (!pdm)
    {
        /* ... use the device's default one */
        pdm = pGraphicsDevice->pDevModeList[pGraphicsDevice->iDefaultMode].pdm;
        DPRINT("Using iDefaultMode = %ld\n", pGraphicsDevice->iDefaultMode);
    }

    /* Try to get a diplay driver */
    ppdev->pldev = EngLoadImageEx(pdm->dmDeviceName, LDEV_DEVICE_DISPLAY);
    if (!ppdev->pldev)
    {
        DPRINT1("Could not load display driver '%ls'\n",
                pGraphicsDevice->pDiplayDrivers);
        ExFreePoolWithTag(ppdev, GDITAG_PDEV);
        return NULL;
    }

    /* Copy the function table */
    ppdev->pfn = ppdev->pldev->pfn;

    /* Set MovePointer function */
    ppdev->pfnMovePointer = ppdev->pfn.MovePointer;
    if (!ppdev->pfnMovePointer)
        ppdev->pfnMovePointer = EngMovePointer;

    ppdev->pGraphicsDevice = pGraphicsDevice;
    ppdev->hsemDevLock = EngCreateSemaphore();
    // Should we change the ative mode of pGraphicsDevice ?
    ppdev->pdmwDev = PDEVOBJ_pdmMatchDevMode(ppdev, pdm) ;

    /* FIXME! */
    ppdev->flFlags = PDEV_DISPLAY;

    /* HACK: Don't use the pointer */
    ppdev->Pointer.Exclude.right = -1;

    /* Call the driver to enable the PDEV */
    if (!PDEVOBJ_bEnablePDEV(ppdev, pdm, NULL))
    {
        DPRINT1("Failed to enable PDEV!\n");
        ASSERT(FALSE);
    }

    /* FIXME: this must be done in a better way */
    pGraphicsDevice->StateFlags |= DISPLAY_DEVICE_ATTACHED_TO_DESKTOP;

    /* Tell the driver that the PDEV is ready */
    PDEVOBJ_vCompletePDEV(ppdev);

    /* Return the PDEV */
    return ppdev;
}