UINT APIENTRY IntAnimatePalette(HPALETTE hPal, UINT StartIndex, UINT NumEntries, CONST PPALETTEENTRY PaletteColors) { UINT ret = 0; if( hPal != NtGdiGetStockObject(DEFAULT_PALETTE) ) { PPALETTE palPtr; UINT pal_entries; HDC hDC; PDC dc; PWND Wnd; const PALETTEENTRY *pptr = PaletteColors; palPtr = PALETTE_ShareLockPalette(hPal); if (!palPtr) return FALSE; pal_entries = palPtr->NumColors; if (StartIndex >= pal_entries) { PALETTE_ShareUnlockPalette(palPtr); return FALSE; } if (StartIndex+NumEntries > pal_entries) NumEntries = pal_entries - StartIndex; for (NumEntries += StartIndex; StartIndex < NumEntries; StartIndex++, pptr++) { /* According to MSDN, only animate PC_RESERVED colours */ if (palPtr->IndexedColors[StartIndex].peFlags & PC_RESERVED) { memcpy( &palPtr->IndexedColors[StartIndex], pptr, sizeof(PALETTEENTRY) ); ret++; PALETTE_ValidateFlags(&palPtr->IndexedColors[StartIndex], 1); } } PALETTE_ShareUnlockPalette(palPtr); /* Immediately apply the new palette if current window uses it */ Wnd = UserGetDesktopWindow(); hDC = UserGetWindowDC(Wnd); dc = DC_LockDc(hDC); if (NULL != dc) { if (dc->dclevel.hpal == hPal) { DC_UnlockDc(dc); IntGdiRealizePalette(hDC); } else DC_UnlockDc(dc); } UserReleaseDC(Wnd,hDC, FALSE); } return ret; }
UINT APIENTRY IntSetPaletteEntries( HPALETTE hpal, UINT Start, UINT Entries, CONST LPPALETTEENTRY pe) { PPALETTE palGDI; ULONG numEntries; if ((UINT)hpal & GDI_HANDLE_STOCK_MASK) { return 0; } palGDI = PALETTE_ShareLockPalette(hpal); if (!palGDI) return 0; numEntries = palGDI->NumColors; if (Start >= numEntries) { PALETTE_ShareUnlockPalette(palGDI); return 0; } if (numEntries < Start + Entries) { Entries = numEntries - Start; } memcpy(palGDI->IndexedColors + Start, pe, Entries * sizeof(PALETTEENTRY)); PALETTE_ShareUnlockPalette(palGDI); return Entries; }
VOID NTAPI EBRUSHOBJ_vCleanup(EBRUSHOBJ *pebo) { /* Check if there's a GDI realisation */ if (pebo->pengbrush) { /* Unlock the bitmap again */ SURFACE_ShareUnlockSurface(pebo->pengbrush); pebo->pengbrush = NULL; } /* Check if there's a driver's realisation */ if (pebo->BrushObject.pvRbrush) { /* Free allocated driver memory */ EngFreeMem(pebo->BrushObject.pvRbrush); pebo->BrushObject.pvRbrush = NULL; } if (pebo->psoMask != NULL) { SURFACE_ShareUnlockSurface(pebo->psoMask); pebo->psoMask = NULL; } /* Dereference the palettes */ PALETTE_ShareUnlockPalette(pebo->ppalSurf); PALETTE_ShareUnlockPalette(pebo->ppalDC); if (pebo->ppalDIB) PALETTE_ShareUnlockPalette(pebo->ppalDIB); }
/* * @implemented */ HPALETTE APIENTRY NtGdiCreatePaletteInternal ( IN LPLOGPALETTE pLogPal, IN UINT cEntries ) { PPALETTE PalGDI; HPALETTE NewPalette; pLogPal->palNumEntries = cEntries; NewPalette = PALETTE_AllocPalette( PAL_INDEXED, cEntries, (PULONG)pLogPal->palPalEntry, 0, 0, 0); if (NewPalette == NULL) { return NULL; } PalGDI = (PPALETTE) PALETTE_ShareLockPalette(NewPalette); if (PalGDI != NULL) { PALETTE_ValidateFlags(PalGDI->IndexedColors, PalGDI->NumColors); PALETTE_ShareUnlockPalette(PalGDI); } else { /* FIXME - Handle PalGDI == NULL!!!! */ DPRINT1("PalGDI is NULL\n"); } return NewPalette; }
HPALETTE FASTCALL GdiSelectPalette( HDC hDC, HPALETTE hpal, BOOL ForceBackground) { PDC pdc; HPALETTE oldPal = NULL; PPALETTE ppal; // FIXME: mark the palette as a [fore\back]ground pal pdc = DC_LockDc(hDC); if (!pdc) { return NULL; } /* Check if this is a valid palette handle */ ppal = PALETTE_ShareLockPalette(hpal); if (!ppal) { DC_UnlockDc(pdc); return NULL; } /* Is this a valid palette for this depth? */ if ((BitsPerFormat(pdc->dclevel.pSurface->SurfObj.iBitmapFormat) <= 8 && (ppal->flFlags & PAL_INDEXED)) || (BitsPerFormat(pdc->dclevel.pSurface->SurfObj.iBitmapFormat) > 8)) { /* Get old palette, set new one */ oldPal = pdc->dclevel.hpal; pdc->dclevel.hpal = hpal; DC_vSelectPalette(pdc, ppal); /* Mark the brushes invalid */ pdc->pdcattr->ulDirty_ |= DIRTY_FILL | DIRTY_LINE | DIRTY_BACKGROUND | DIRTY_TEXT; } if(pdc->dctype == DCTYPE_MEMORY) { // This didn't work anyway //IntGdiRealizePalette(hDC); } PALETTE_ShareUnlockPalette(ppal); DC_UnlockDc(pdc); return oldPal; }
BOOL FASTCALL UpdateDeviceGammaRamp( HDEV hPDev ) { BOOL Ret = FALSE; PPALETTE palGDI; PALOBJ *palPtr; PPDEVOBJ pGDev = (PPDEVOBJ) hPDev; if ((pGDev->devinfo.iDitherFormat == BMF_8BPP) || (pGDev->devinfo.iDitherFormat == BMF_16BPP) || (pGDev->devinfo.iDitherFormat == BMF_24BPP) || (pGDev->devinfo.iDitherFormat == BMF_32BPP)) { if (pGDev->DriverFunctions.IcmSetDeviceGammaRamp) return pGDev->DriverFunctions.IcmSetDeviceGammaRamp( pGDev->dhpdev, IGRF_RGB_256WORDS, pGDev->pvGammaRamp); if ( (pGDev->devinfo.iDitherFormat != BMF_8BPP) || !(pGDev->gdiinfo.flRaster & RC_PALETTE)) return FALSE; if (!(pGDev->flFlags & PDEV_GAMMARAMP_TABLE)) return FALSE; palGDI = PALETTE_ShareLockPalette(pGDev->devinfo.hpalDefault); if(!palGDI) return FALSE; palPtr = (PALOBJ*) palGDI; if (pGDev->flFlags & PDEV_GAMMARAMP_TABLE) palGDI->flFlags |= PAL_GAMMACORRECTION; else palGDI->flFlags &= ~PAL_GAMMACORRECTION; if (!(pGDev->flFlags & PDEV_DRIVER_PUNTED_CALL)) // No punting, we hook { // BMF_8BPP only! // PALOBJ_cGetColors check mode flags and update Gamma Correction. // Set the HDEV to pal and go. palGDI->hPDev = hPDev; Ret = pGDev->DriverFunctions.SetPalette(pGDev->dhpdev, palPtr, 0, 0, palGDI->NumColors); } PALETTE_ShareUnlockPalette(palGDI); return Ret; } else return FALSE; }
UINT APIENTRY IntGetPaletteEntries( HPALETTE hpal, UINT StartIndex, UINT Entries, LPPALETTEENTRY pe) { PPALETTE palGDI; UINT numEntries; palGDI = (PPALETTE) PALETTE_ShareLockPalette(hpal); if (NULL == palGDI) { return 0; } numEntries = palGDI->NumColors; if (NULL != pe) { if (numEntries < StartIndex + Entries) { Entries = numEntries - StartIndex; } if (numEntries <= StartIndex) { PALETTE_ShareUnlockPalette(palGDI); return 0; } memcpy(pe, palGDI->IndexedColors + StartIndex, Entries * sizeof(PALETTEENTRY)); } else { Entries = numEntries; } PALETTE_ShareUnlockPalette(palGDI); return Entries; }
VOID NTAPI SURFACE_vCleanup(PVOID ObjectBody) { PSURFACE psurf = (PSURFACE)ObjectBody; PVOID pvBits = psurf->SurfObj.pvBits; /* Check if the surface has bits */ if (pvBits) { /* Only bitmaps can have bits */ ASSERT(psurf->SurfObj.iType == STYPE_BITMAP); /* Check if it is a DIB section */ if (psurf->hDIBSection) { /* Unmap the section view */ EngUnmapSectionView(pvBits, psurf->dwOffset, psurf->hSecure); } else if (psurf->SurfObj.fjBitmap & BMF_USERMEM) { /* Bitmap was allocated from usermode memory */ EngFreeUserMem(pvBits); } else if (psurf->SurfObj.fjBitmap & BMF_KMSECTION) { /* Bitmap was allocated from a kernel section */ if (!EngFreeSectionMem(NULL, pvBits)) { DPRINT1("EngFreeSectionMem failed for %p!\n", pvBits); // Should we BugCheck here? ASSERT(FALSE); } } else if (psurf->SurfObj.fjBitmap & BMF_POOLALLOC) { /* Free a pool allocation */ EngFreeMem(pvBits); } } /* Free palette */ if(psurf->ppal) { PALETTE_ShareUnlockPalette(psurf->ppal); } }
UINT APIENTRY NtGdiGetNearestPaletteIndex( HPALETTE hpal, COLORREF crColor) { PPALETTE ppal = PALETTE_ShareLockPalette(hpal); UINT index = 0; if (ppal) { if (ppal->flFlags & PAL_INDEXED) { /* Return closest match for the given RGB color */ index = PALETTE_ulGetNearestPaletteIndex(ppal, crColor); } // else SetLastError ? PALETTE_ShareUnlockPalette(ppal); } return index; }
BOOL APIENTRY EngAssociateSurface( _In_ HSURF hsurf, _In_ HDEV hdev, _In_ FLONG flHooks) { SURFOBJ *pso; PSURFACE psurf; PDEVOBJ* ppdev; PPALETTE ppal; ppdev = (PDEVOBJ*)hdev; /* Lock the surface */ psurf = SURFACE_ShareLockSurface(hsurf); if (!psurf) { return FALSE; } pso = &psurf->SurfObj; /* Associate the hdev */ pso->hdev = hdev; pso->dhpdev = ppdev->dhpdev; /* Hook up specified functions */ psurf->flags &= ~HOOK_FLAGS; psurf->flags |= (flHooks & HOOK_FLAGS); /* Assign the PDEV's palette */ ppal = PALETTE_ShareLockPalette(ppdev->devinfo.hpalDefault); SURFACE_vSetPalette(psurf, ppal); PALETTE_ShareUnlockPalette(ppal); SURFACE_ShareUnlockSurface(psurf); return TRUE; }
/* * @implemented */ ULONG APIENTRY EngSetPointerShape( _In_ SURFOBJ *pso, _In_opt_ SURFOBJ *psoMask, _In_opt_ SURFOBJ *psoColor, _In_opt_ XLATEOBJ *pxlo, _In_ LONG xHot, _In_ LONG yHot, _In_ LONG x, _In_ LONG y, _In_ RECTL *prcl, _In_ FLONG fl) { PDEVOBJ *ppdev; GDIPOINTER *pgp; LONG lDelta = 0; HBITMAP hbmSave = NULL, hbmColor = NULL, hbmMask = NULL; PSURFACE psurfSave = NULL, psurfColor = NULL, psurfMask = NULL; RECTL rectl; SIZEL sizel = {0, 0}; ASSERT(pso); ppdev = GDIDEV(pso); pgp = &ppdev->Pointer; /* Handle the case where we have no XLATEOBJ */ if (pxlo == NULL) pxlo = &gexloTrivial.xlo; /* Do we have any bitmap at all? */ if (psoColor || psoMask) { /* Get the size of the new pointer */ if (psoColor) { sizel.cx = psoColor->sizlBitmap.cx; sizel.cy = psoColor->sizlBitmap.cy; } else// if (psoMask) { sizel.cx = psoMask->sizlBitmap.cx; sizel.cy = psoMask->sizlBitmap.cy / 2; } rectl.left = 0; rectl.top = 0; rectl.right = sizel.cx; rectl.bottom = sizel.cy; /* Calculate lDelta for our surfaces. */ lDelta = WIDTH_BYTES_ALIGN32(sizel.cx, BitsPerFormat(pso->iBitmapFormat)); /* Create a bitmap for saving the pixels under the cursor. */ hbmSave = EngCreateBitmap(sizel, lDelta, pso->iBitmapFormat, BMF_TOPDOWN | BMF_NOZEROINIT, NULL); psurfSave = SURFACE_ShareLockSurface(hbmSave); if (!psurfSave) goto failure; } if (psoColor) { if (fl & SPS_ALPHA) { /* Always store the alpha cursor in RGB. */ EXLATEOBJ exloSrcRGB; PEXLATEOBJ pexlo; pexlo = CONTAINING_RECORD(pxlo, EXLATEOBJ, xlo); EXLATEOBJ_vInitialize(&exloSrcRGB, pexlo->ppalSrc, &gpalRGB, 0, 0, 0); hbmColor = EngCreateBitmap(psoColor->sizlBitmap, WIDTH_BYTES_ALIGN32(sizel.cx, 32), BMF_32BPP, BMF_TOPDOWN | BMF_NOZEROINIT, NULL); psurfColor = SURFACE_ShareLockSurface(hbmColor); if (!psurfColor) goto failure; /* Now copy the given bitmap. */ rectl.bottom = psoColor->sizlBitmap.cy; IntEngCopyBits(&psurfColor->SurfObj, psoColor, NULL, &exloSrcRGB.xlo, &rectl, (POINTL*)&rectl); EXLATEOBJ_vCleanup(&exloSrcRGB); } else { /* Color bitmap must have the same format as the dest surface */ if (psoColor->iBitmapFormat != pso->iBitmapFormat) { DPRINT1("Screen surface and cursor color bitmap format don't match!.\n"); goto failure; } /* Create a bitmap to copy the color bitmap to */ hbmColor = EngCreateBitmap(psoColor->sizlBitmap, lDelta, pso->iBitmapFormat, BMF_TOPDOWN | BMF_NOZEROINIT, NULL); psurfColor = SURFACE_ShareLockSurface(hbmColor); if (!psurfColor) goto failure; /* Now copy the given bitmap. */ rectl.bottom = psoColor->sizlBitmap.cy; IntEngCopyBits(&psurfColor->SurfObj, psoColor, NULL, pxlo, &rectl, (POINTL*)&rectl); } } /* Create a mask surface */ if (psoMask) { EXLATEOBJ exlo; PPALETTE ppal; lDelta = WIDTH_BYTES_ALIGN32(sizel.cx, BitsPerFormat(pso->iBitmapFormat)); /* Create a bitmap for the mask */ hbmMask = EngCreateBitmap(psoMask->sizlBitmap, lDelta, pso->iBitmapFormat, BMF_TOPDOWN | BMF_NOZEROINIT, NULL); psurfMask = SURFACE_ShareLockSurface(hbmMask); if (!psurfMask) goto failure; /* Initialize an EXLATEOBJ */ ppal = PALETTE_ShareLockPalette(ppdev->devinfo.hpalDefault); EXLATEOBJ_vInitialize(&exlo, gppalMono, ppal, 0, RGB(0xff,0xff,0xff), RGB(0,0,0)); /* Copy the mask bitmap */ rectl.bottom = psoMask->sizlBitmap.cy; IntEngCopyBits(&psurfMask->SurfObj, psoMask, NULL, &exlo.xlo, &rectl, (POINTL*)&rectl); /* Cleanup */ EXLATEOBJ_vCleanup(&exlo); if (ppal) PALETTE_ShareUnlockPalette(ppal); } /* Hide mouse pointer */ IntHideMousePointer(ppdev, pso); /* Free old color bitmap */ if (pgp->psurfColor) { EngDeleteSurface(pgp->psurfColor->BaseObject.hHmgr); SURFACE_ShareUnlockSurface(pgp->psurfColor); pgp->psurfColor = NULL; } /* Free old mask bitmap */ if (pgp->psurfMask) { EngDeleteSurface(pgp->psurfMask->BaseObject.hHmgr); SURFACE_ShareUnlockSurface(pgp->psurfMask); pgp->psurfMask = NULL; } /* Free old save bitmap */ if (pgp->psurfSave) { EngDeleteSurface(pgp->psurfSave->BaseObject.hHmgr); SURFACE_ShareUnlockSurface(pgp->psurfSave); pgp->psurfSave = NULL; } /* See if we are being asked to hide the pointer. */ if (psoMask == NULL && psoColor == NULL) { /* We're done */ return SPS_ACCEPT_NOEXCLUDE; } /* Now set the new cursor */ pgp->psurfColor = psurfColor; pgp->psurfMask = psurfMask; pgp->psurfSave = psurfSave; pgp->HotSpot.x = xHot; pgp->HotSpot.y = yHot; pgp->Size = sizel; pgp->flags = fl; if (x != -1) { ppdev->ptlPointer.x = x; ppdev->ptlPointer.y = y; IntShowMousePointer(ppdev, pso); if (prcl != NULL) { prcl->left = x - pgp->HotSpot.x; prcl->top = y - pgp->HotSpot.x; prcl->right = prcl->left + pgp->Size.cx; prcl->bottom = prcl->top + pgp->Size.cy; } } else if (prcl != NULL) { prcl->left = prcl->top = prcl->right = prcl->bottom = -1; } return SPS_ACCEPT_NOEXCLUDE; failure: /* Cleanup surfaces */ if (hbmMask) EngDeleteSurface((HSURF)hbmMask); if (psurfMask) SURFACE_ShareUnlockSurface(psurfMask); if (hbmColor) EngDeleteSurface((HSURF)hbmColor); if (psurfColor) SURFACE_ShareUnlockSurface(psurfColor); if (hbmSave) EngDeleteSurface((HSURF)hbmSave); if (psurfSave) SURFACE_ShareUnlockSurface(psurfSave); return SPS_ERROR; }
UINT APIENTRY IntGetSystemPaletteEntries(HDC hDC, UINT StartIndex, UINT Entries, LPPALETTEENTRY pe) { PPALETTE palGDI = NULL; PDC dc = NULL; UINT EntriesSize = 0; UINT Ret = 0; if (Entries == 0) { EngSetLastError(ERROR_INVALID_PARAMETER); return 0; } if (pe != NULL) { EntriesSize = Entries * sizeof(pe[0]); if (Entries != EntriesSize / sizeof(pe[0])) { /* Integer overflow! */ EngSetLastError(ERROR_INVALID_PARAMETER); return 0; } } if (!(dc = DC_LockDc(hDC))) { EngSetLastError(ERROR_INVALID_HANDLE); return 0; } palGDI = PALETTE_ShareLockPalette(dc->dclevel.hpal); if (palGDI != NULL) { if (pe != NULL) { if (StartIndex >= palGDI->NumColors) Entries = 0; else if (Entries > palGDI->NumColors - StartIndex) Entries = palGDI->NumColors - StartIndex; memcpy(pe, palGDI->IndexedColors + StartIndex, Entries * sizeof(pe[0])); Ret = Entries; } else { Ret = dc->ppdev->gdiinfo.ulNumPalReg; } } if (palGDI != NULL) PALETTE_ShareUnlockPalette(palGDI); if (dc != NULL) DC_UnlockDc(dc); return Ret; }
HPALETTE APIENTRY NtGdiCreateHalftonePalette(HDC hDC) { int i, r, g, b; PALETTEENTRY PalEntries[256]; PPALETTE ppal; PDC pdc; HPALETTE hpal = NULL; pdc = DC_LockDc(hDC); if (!pdc) { EngSetLastError(ERROR_INVALID_HANDLE); return NULL; } RtlZeroMemory(PalEntries, sizeof(PalEntries)); /* First and last ten entries are default ones */ for (i = 0; i < 10; i++) { PalEntries[i].peRed = g_sysPalTemplate[i].peRed; PalEntries[i].peGreen = g_sysPalTemplate[i].peGreen; PalEntries[i].peBlue = g_sysPalTemplate[i].peBlue; PalEntries[246 + i].peRed = g_sysPalTemplate[10 + i].peRed; PalEntries[246 + i].peGreen = g_sysPalTemplate[10 + i].peGreen; PalEntries[246 + i].peBlue = g_sysPalTemplate[10 + i].peBlue; } ppal = PALETTE_ShareLockPalette(pdc->dclevel.hpal); if (ppal && (ppal->flFlags & PAL_INDEXED)) { /* FIXME: optimize the palette for the current palette */ UNIMPLEMENTED } else { for (r = 0; r < 6; r++) { for (g = 0; g < 6; g++) { for (b = 0; b < 6; b++) { i = r + g*6 + b*36 + 10; PalEntries[i].peRed = r * 51; PalEntries[i].peGreen = g * 51; PalEntries[i].peBlue = b * 51; } } } for (i = 216; i < 246; i++) { int v = (i - 216) << 3; PalEntries[i].peRed = v; PalEntries[i].peGreen = v; PalEntries[i].peBlue = v; } } if (ppal) PALETTE_ShareUnlockPalette(ppal); DC_UnlockDc(pdc); ppal = PALETTE_AllocPalWithHandle(PAL_INDEXED, 256, PalEntries, 0, 0, 0); if (ppal) { hpal = ppal->BaseObject.hHmgr; PALETTE_UnlockPalette(ppal); } return hpal; }
BOOL APIENTRY EngModifySurface( _In_ HSURF hsurf, _In_ HDEV hdev, _In_ FLONG flHooks, _In_ FLONG flSurface, _In_ DHSURF dhsurf, _In_ PVOID pvScan0, _In_ LONG lDelta, _Reserved_ PVOID pvReserved) { SURFOBJ *pso; PSURFACE psurf; PDEVOBJ* ppdev; PPALETTE ppal; /* Lock the surface */ psurf = SURFACE_ShareLockSurface(hsurf); if (psurf == NULL) { DPRINT1("Failed to reference surface %p\n", hsurf); return FALSE; } ppdev = (PDEVOBJ*)hdev; pso = &psurf->SurfObj; pso->dhsurf = dhsurf; /* Associate the hdev */ pso->hdev = hdev; pso->dhpdev = ppdev->dhpdev; /* Hook up specified functions */ psurf->flags &= ~HOOK_FLAGS; psurf->flags |= (flHooks & HOOK_FLAGS); /* Assign the PDEV's palette */ ppal = PALETTE_ShareLockPalette(ppdev->devinfo.hpalDefault); SURFACE_vSetPalette(psurf, ppal); PALETTE_ShareUnlockPalette(ppal); /* Update surface flags */ if (flSurface & MS_NOTSYSTEMMEMORY) pso->fjBitmap |= BMF_NOTSYSMEM; else pso->fjBitmap &= ~BMF_NOTSYSMEM; if (flSurface & MS_SHAREDACCESS) psurf->flags |= SHAREACCESS_SURFACE; else psurf->flags &= ~SHAREACCESS_SURFACE; /* Check if the caller passed bitmap bits */ if ((pvScan0 != NULL) && (lDelta != 0)) { /* Update the fields */ pso->pvScan0 = pvScan0; pso->lDelta = lDelta; /* This is a bitmap now! */ pso->iType = STYPE_BITMAP; /* Check memory layout */ if (lDelta > 0) { /* Topdown is the normal way */ pso->cjBits = lDelta * pso->sizlBitmap.cy; pso->pvBits = pso->pvScan0; pso->fjBitmap |= BMF_TOPDOWN; } else { /* Inversed bitmap (bottom up) */ pso->cjBits = (-lDelta) * pso->sizlBitmap.cy; pso->pvBits = (PCHAR)pso->pvScan0 - pso->cjBits - lDelta; pso->fjBitmap &= ~BMF_TOPDOWN; } } else { /* Set bits to NULL */ pso->pvBits = NULL; pso->pvScan0 = NULL; pso->lDelta = 0; /* Set appropriate surface type */ if (pso->iType != STYPE_DEVICE) pso->iType = STYPE_DEVBITMAP; } SURFACE_ShareUnlockSurface(psurf); return TRUE; }
VOID NTAPI PDEVOBJ_vRelease(PPDEVOBJ ppdev) { /* Lock loader */ EngAcquireSemaphore(ghsemPDEV); /* Decrease reference count */ --ppdev->cPdevRefs; ASSERT(ppdev->cPdevRefs >= 0) ; /* Check if references are left */ if (ppdev->cPdevRefs == 0) { /* Do we have a surface? */ if(ppdev->pSurface) { /* Release the surface and let the driver free it */ SURFACE_ShareUnlockSurface(ppdev->pSurface); ppdev->pfn.DisableSurface(ppdev->dhpdev); } /* Do we have a palette? */ if(ppdev->ppalSurf) { PALETTE_ShareUnlockPalette(ppdev->ppalSurf); } /* Disable PDEV */ ppdev->pfn.DisablePDEV(ppdev->dhpdev); /* Remove it from list */ if( ppdev == gppdevList ) gppdevList = ppdev->ppdevNext ; else { PPDEVOBJ ppdevCurrent = gppdevList; BOOL found = FALSE ; while (!found && ppdevCurrent->ppdevNext) { if (ppdevCurrent->ppdevNext == ppdev) found = TRUE; else ppdevCurrent = ppdevCurrent->ppdevNext ; } if(found) ppdevCurrent->ppdevNext = ppdev->ppdevNext; } /* Is this the primary one ? */ if (ppdev == gppdevPrimary) gppdevPrimary = NULL; /* Free it */ ExFreePoolWithTag(ppdev, GDITAG_PDEV ); } /* Unlock loader */ EngReleaseSemaphore(ghsemPDEV); }