HDC NTAPI GreOpenDCW( PUNICODE_STRING pustrDevice, DEVMODEW *pdmInit, PUNICODE_STRING pustrLogAddr, ULONG iType, BOOL bDisplay, HANDLE hspool, VOID *pDriverInfo2, VOID *pUMdhpdev) { PPDEVOBJ ppdev; PDC pdc; HDC hdc; DPRINT("GreOpenDCW(%S, iType=%lu)\n", pustrDevice ? pustrDevice->Buffer : NULL, iType); /* Get a PDEVOBJ for the device */ ppdev = EngpGetPDEV(pustrDevice); if (!ppdev) { DPRINT1("Didn't find a suitable PDEV\n"); return NULL; } DPRINT("GreOpenDCW - ppdev = %p\n", ppdev); pdc = DC_AllocDcWithHandle(); if (!pdc) { DPRINT1("Could not Allocate a DC\n"); PDEVOBJ_vRelease(ppdev); return NULL; } hdc = pdc->BaseObject.hHmgr; /* Lock ppdev and initialize the new DC */ DC_vInitDc(pdc, iType, ppdev); /* FIXME: HACK! */ DC_InitHack(pdc); DC_bAllocDcAttr(pdc); DC_UnlockDc(pdc); DPRINT("Returning hdc = %p\n", hdc); return hdc; }
BOOL NTAPI DC_Cleanup(PVOID ObjectBody) { PDC pdc = (PDC)ObjectBody; /* Free DC_ATTR */ DC_vFreeDcAttr(pdc); /* Delete saved DCs */ DC_vRestoreDC(pdc, 1); /* Deselect dc objects */ DC_vSelectSurface(pdc, NULL); DC_vSelectFillBrush(pdc, NULL); DC_vSelectLineBrush(pdc, NULL); DC_vSelectPalette(pdc, NULL); /* Cleanup the dc brushes */ EBRUSHOBJ_vCleanup(&pdc->eboFill); EBRUSHOBJ_vCleanup(&pdc->eboLine); EBRUSHOBJ_vCleanup(&pdc->eboText); EBRUSHOBJ_vCleanup(&pdc->eboBackground); /* Release font */ LFONT_ShareUnlockFont(pdc->dclevel.plfnt); /* Free regions */ if (pdc->rosdc.hClipRgn && GreIsHandleValid(pdc->rosdc.hClipRgn)) GreDeleteObject(pdc->rosdc.hClipRgn); if (pdc->prgnVis) { REGION_Delete(pdc->prgnVis); } if (pdc->rosdc.hGCClipRgn && GreIsHandleValid(pdc->rosdc.hGCClipRgn)) { GreDeleteObject(pdc->rosdc.hGCClipRgn); } if (NULL != pdc->rosdc.CombinedClip) IntEngDeleteClipRegion(pdc->rosdc.CombinedClip); PATH_Delete(pdc->dclevel.hPath); if(pdc->dclevel.pSurface) SURFACE_ShareUnlockSurface(pdc->dclevel.pSurface); PDEVOBJ_vRelease(pdc->ppdev) ; return TRUE; }
VOID NTAPI DC_vCleanup(PVOID ObjectBody) { PDC pdc = (PDC)ObjectBody; /* Free DC_ATTR */ DC_vFreeDcAttr(pdc); /* Delete saved DCs */ DC_vRestoreDC(pdc, 1); /* Deselect dc objects */ DC_vSelectSurface(pdc, NULL); DC_vSelectFillBrush(pdc, NULL); DC_vSelectLineBrush(pdc, NULL); DC_vSelectPalette(pdc, NULL); /* Cleanup the dc brushes */ EBRUSHOBJ_vCleanup(&pdc->eboFill); EBRUSHOBJ_vCleanup(&pdc->eboLine); EBRUSHOBJ_vCleanup(&pdc->eboText); EBRUSHOBJ_vCleanup(&pdc->eboBackground); /* Release font */ LFONT_ShareUnlockFont(pdc->dclevel.plfnt); /* Free regions */ if (pdc->dclevel.prgnClip) REGION_Delete(pdc->dclevel.prgnClip); if (pdc->dclevel.prgnMeta) REGION_Delete(pdc->dclevel.prgnMeta); if (pdc->prgnVis) REGION_Delete(pdc->prgnVis); if (pdc->prgnRao) REGION_Delete(pdc->prgnRao); if (pdc->prgnAPI) REGION_Delete(pdc->prgnAPI); /* Free CLIPOBJ resources */ IntEngFreeClipResources(&pdc->co); PATH_Delete(pdc->dclevel.hPath); if(pdc->dclevel.pSurface) SURFACE_ShareUnlockSurface(pdc->dclevel.pSurface); PDEVOBJ_vRelease(pdc->ppdev) ; }
NTSTATUS NTAPI UserEnumCurrentDisplaySettings( PUNICODE_STRING pustrDevice, PDEVMODEW *ppdm) { PPDEVOBJ ppdev; /* Get the PDEV for the device */ ppdev = EngpGetPDEV(pustrDevice); if (!ppdev) { /* No device found */ ERR("No PDEV found!\n"); return STATUS_UNSUCCESSFUL; } *ppdm = ppdev->pdmwDev; PDEVOBJ_vRelease(ppdev); return STATUS_SUCCESS; }
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; }
BOOL NTAPI PDEVOBJ_bSwitchMode( PPDEVOBJ ppdev, PDEVMODEW pdm) { UNICODE_STRING ustrDevice; PPDEVOBJ ppdevTmp; PSURFACE pSurface; BOOL retval = FALSE; /* Lock the PDEV */ EngAcquireSemaphore(ppdev->hsemDevLock); /* And everything else */ EngAcquireSemaphore(ghsemPDEV); DPRINT1("PDEVOBJ_bSwitchMode, ppdev = %p, pSurface = %p\n", ppdev, ppdev->pSurface); // Lookup the GraphicsDevice + select DEVMODE // pdm = PDEVOBJ_pdmMatchDevMode(ppdev, pdm); /* 1. Temporarily disable the current PDEV */ if (!ppdev->pfn.AssertMode(ppdev->dhpdev, FALSE)) { DPRINT1("DrvAssertMode failed\n"); goto leave; } /* 2. Create new PDEV */ RtlInitUnicodeString(&ustrDevice, ppdev->pGraphicsDevice->szWinDeviceName); ppdevTmp = EngpCreatePDEV(&ustrDevice, pdm); if (!ppdevTmp) { DPRINT1("Failed to create a new PDEV\n"); goto leave; } /* 3. Create a new surface */ pSurface = PDEVOBJ_pSurface(ppdevTmp); if (!pSurface) { DPRINT1("DrvEnableSurface failed\n"); goto leave; } /* 4. Get DirectDraw information */ /* 5. Enable DirectDraw Not traced */ /* 6. Copy old PDEV state to new PDEV instance */ /* 7. Switch the PDEVs */ PDEVOBJ_vSwitchPdev(ppdev, ppdevTmp); /* 8. Disable DirectDraw */ PDEVOBJ_vRelease(ppdevTmp); /* Update primary display capabilities */ if(ppdev == gppdevPrimary) { PDEVOBJ_vGetDeviceCaps(ppdev, &GdiHandleTable->DevCaps); } /* Success! */ retval = TRUE; leave: /* Unlock PDEV */ EngReleaseSemaphore(ppdev->hsemDevLock); EngReleaseSemaphore(ghsemPDEV); DPRINT1("leave, ppdev = %p, pSurface = %p\n", ppdev, ppdev->pSurface); return retval; }