Esempio n. 1
0
/* UserAttachMonitor
 *
 * Creates a new MONITOR and appends it to the list of monitors.
 *
 * Arguments
 *
 *   pGdiDevice     Pointer to the PDEVOBJ onto which the monitor was attached
 *   DisplayNumber  Display Number (starting with 0)
 *
 * Return value
 *   Returns a NTSTATUS
 */
NTSTATUS NTAPI
UserAttachMonitor(IN HDEV hDev)
{
    PMONITOR pMonitor;

    TRACE("Attaching monitor...\n");

    /* Create new monitor object */
    pMonitor = IntCreateMonitorObject();
    if (pMonitor == NULL)
    {
        TRACE("Couldnt create monitor object\n");
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    pMonitor->hDev = hDev;
    pMonitor->cWndStack = 0;

    if (gMonitorList == NULL)
    {
        TRACE("Primary monitor is beeing attached\n");
        pMonitor->IsPrimary = TRUE;
        gMonitorList = pMonitor;
    }
    else
    {
        PMONITOR pmonLast = gMonitorList;
        TRACE("Additional monitor is beeing attached\n");
        while (pmonLast->pMonitorNext != NULL)
            pmonLast = pmonLast->pMonitorNext;

        pmonLast->pMonitorNext = pMonitor;
    }

    UserUpdateMonitorSize(hDev);

    return STATUS_SUCCESS;
}
Esempio n. 2
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;
}