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; }
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; }