Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

733 lines
22 KiB

/*******************************Module*Header*******************************\
* Module Name:
*
* icmobj.cxx
*
* Abstract
*
* This module contains object support for COLORTRANSFORM objects and ICM
* Objects
*
* Author:
*
* Feb.23.1997 -by- Hideyuki Nagase [hideyukn]
*
* Copyright (c) 1997-1999 Microsoft Corporation
\**************************************************************************/
#include "precomp.hxx"
/******************************Public*Routine******************************\
* COLORTRANSFORMOBJ::hCreate()
*
* History:
*
* Write it:
* 23-Feb-1997 -by- Hideyuki Nagase [hideyukn]
\**************************************************************************/
HANDLE
COLORTRANSFORMOBJ::hCreate(
XDCOBJ& dco,
LOGCOLORSPACEW *pLogColorSpaceW,
PVOID pvSource,
ULONG cjSource,
PVOID pvDestination,
ULONG cjDestination,
PVOID pvTarget,
ULONG cjTarget
)
{
HANDLE hObject = NULL;
PCOLORTRANSFORM pNewCXform = NULL;
ICMAPI(("COLORTRANSFORM::hCreate()\n"));
HDEV hdev = dco.hdev();
//
// This object should not have any existing realization.
//
ASSERTGDI(_pColorTransform == NULL,"COLORTRANSFORMOBJ::hCreate() object is exist\n");
PDEVOBJ po(hdev);
if (po.bValid())
{
//
// Allocate ColorTransform object.
//
pNewCXform = (PCOLORTRANSFORM) ALLOCOBJ(sizeof(COLORTRANSFORM),ICMCXF_TYPE, FALSE);
if (pNewCXform)
{
//
// Register COLORTRANSFORM handle.
//
hObject = (HCOLORSPACE)HmgInsertObject(
pNewCXform,
HMGR_ALLOC_ALT_LOCK,
ICMCXF_TYPE);
if (hObject)
{
HANDLE hDeviceColorTransform = NULL;
//
// Set new object to this COLORTRANSFORMNOBJ
//
_pColorTransform = pNewCXform;
//
// Lock device
//
DEVLOCKOBJ devLock(po);
//
// Create driver's transform.
//
if (PPFNVALID(po,IcmCreateColorTransform))
{
//
// Call device driver to obtain handle of device driver.
//
hDeviceColorTransform = (*PPFNDRV(po, IcmCreateColorTransform)) (
po.dhpdev(),
pLogColorSpaceW,
pvSource, cjSource,
pvDestination, cjDestination,
pvTarget, cjTarget,
0 /* dwReserved */);
}
else
{
WARNING("CreateColorTransform called on device that does not support call\n");
SAVE_ERROR_CODE(ERROR_INVALID_PARAMETER);
}
if (hDeviceColorTransform)
{
ICMMSG(("CreateColorTransform(): Succeed to get handle from driver\n"));
//
// Set the handle to COLORTRANSFORM object.
//
vSetDeviceColorTransform(hDeviceColorTransform);
//
// Insert this pColorTransform to this DC.
//
dco.bAddColorTransform(hObject);
}
else
{
ICMMSG(("CreateColorTransform(): Fail to get handle from driver\n"));
//
// Mark this object does not have driver's realization.
//
vSetDeviceColorTransform(NULL);
//
// We are fail to get driver's handle, delete this.
//
bDelete(dco);
//
// Invalidate hObject and pColorTransform.
// (these are deleted in above bDelete())
//
hObject = NULL;
pNewCXform = NULL;
}
}
}
else
{
SAVE_ERROR_CODE(ERROR_NOT_ENOUGH_MEMORY);
}
if ((hObject == NULL) && (pNewCXform != NULL))
{
FREEOBJ(pNewCXform,ICMCXF_TYPE);
}
}
return (hObject);
}
/******************************Public*Routine******************************\
* COLORTRANSFORMOBJ::bDelete()
*
* History:
*
* Write it:
* 23-Feb-1997 -by- Hideyuki Nagase [hideyukn]
\**************************************************************************/
BOOL
COLORTRANSFORMOBJ::bDelete(XDCOBJ& dco,BOOL bProcessCleanup)
{
BOOL bRet = FALSE;
PCOLORTRANSFORM pDeleteXCForm;
ICMAPI(("COLORTRANSFORM::bDelete()\n"));
if (bValid())
{
BOOL bCanBeRemoved;
//
// Get colortransform object handle.
//
HANDLE hObject = _pColorTransform->hColorTransform();
//
// Unlock it. (this was locked in constructor).
//
DEC_SHARE_REF_CNT(_pColorTransform);
//
// Remote from object table.
//
bCanBeRemoved = (BOOL)(ULONG_PTR)HmgRemoveObject((HOBJ)(hObject),0,0,TRUE,ICMCXF_TYPE);
if (bCanBeRemoved)
{
HANDLE hDeviceColorTransform;
//
// Yes, we can remove object from object table, try to delete driver's realization.
//
ICMMSG(("DeleteColorTransform(): Succeed to remove object from table\n"));
//
// Get device driver's handle.
//
hDeviceColorTransform = hGetDeviceColorTransform();
if (hDeviceColorTransform)
{
//
// Initialize PDEV object with owner.
//
PDEVOBJ po(dco.hdev());
if (po.bValid())
{
if (po.bUMPD() && bProcessCleanup)
{
ICMMSG(("DeleteColorTransform():Will not callout to user mode since UMPD.\n"));
//
// Overwrite driver transform as NULL.
//
vSetDeviceColorTransform(NULL);
}
else
{
DEVLOCKOBJ devLock(po);
//
// Delete driver's realization.
//
if (PPFNVALID(po,IcmDeleteColorTransform))
{
//
// Call device driver to free driver's handle
//
if ((*PPFNDRV(po, IcmDeleteColorTransform))(
po.dhpdev(),
hDeviceColorTransform))
{
ICMMSG(("DeleteColorTransform():Succeed to IcmDeleteColorTransform()\n"));
//
// This object does not have driver realization anymore.
//
vSetDeviceColorTransform(NULL);
}
else
{
WARNING("DeleteColorTransform():Fail to IcmDeleteColorTransform()\n");
}
}
else
{
WARNING("DeleteColorTransform called on device that does not support call\n");
SAVE_ERROR_CODE(ERROR_INVALID_PARAMETER);
}
}
}
}
else
{
ICMMSG(("DeleteColorTransform(): There is no driver handle\n"));
}
//
// We could delete object allocation if there is no driver's realization.
//
if (hGetDeviceColorTransform() == NULL)
{
//
// Remove this pColorTransform from DC.
//
dco.bRemoveColorTransform(hObject);
//
// Free it.
//
FREEOBJ(_pColorTransform,ICMCXF_TYPE);
//
// Invalidate pointer.
//
_pColorTransform = NULL;
//
// Yes, everything fine!
//
bRet = TRUE;
}
}
else
{
ICMMSG(("DeleteColorTransform(): Fail to remove object from table\n"));
}
//
// If we could not remove this object from object table, or could not
// delete object (including driver's realization)
//
if ((!bCanBeRemoved) || (!bRet))
{
//
// can not delete now. somebody will using...
//
WARNING("COLORTRANSFORMOBJ::vDelete(): Fail to Delete object, lazy deletion may happen\n");
//
// Back reference counter (deconstuctor will decrement this).
//
INC_SHARE_REF_CNT(_pColorTransform);
//
// Anyway, we will delete later at cleanup.
//
bRet = TRUE;
}
}
return (bRet);
}
/******************************Public*Routine******************************\
* XDCOBJ::bAddColorTransform()
*
* History:
*
* Write it:
* 27-Feb-1997 -by- Hideyuki Nagase [hideyukn]
\**************************************************************************/
BOOL XDCOBJ::bAddColorTransform(HANDLE hCXform)
{
CXFLIST *pCXFListThis;
//
// Allocate new cell of CXFLIST
//
pCXFListThis = (CXFLIST *) PALLOCMEM(sizeof(CXFLIST),'ddaG');
if (pCXFListThis)
{
//
// Fill up CXFLIST structure
//
pCXFListThis->hCXform = hCXform;
pCXFListThis->pNext = pdc->pCXFList;
//
// Insert this into top of list.
//
pdc->pCXFList = pCXFListThis;
return (TRUE);
}
else
{
ICMMSG(("XDCOBJ::bAddColorTransform() Failed\n"));
return (FALSE);
}
}
/******************************Public*Routine******************************\
* XDCOBJ::bRemoveColorTransform()
*
* History:
*
* Write it:
* 27-Feb-1997 -by- Hideyuki Nagase [hideyukn]
\**************************************************************************/
BOOL XDCOBJ::bRemoveColorTransform(HANDLE hCXform)
{
if (pdc->pCXFList)
{
PCXFLIST pPrev, pThis;
pPrev = pThis = pdc->pCXFList;
while (pThis)
{
if (pThis->hCXform == hCXform)
{
//
// This is the cell, we need to remove.
//
if (pPrev == pThis)
{
//
// We are going to remove first cell. then need to
// update root.
//
pdc->pCXFList = pThis->pNext;
}
else
{
//
// Remove this from list.
//
pPrev->pNext = pThis->pNext;
}
//
// Invalidate root.
//
VFREEMEM(pThis);
return (TRUE);
}
//
// Move to next cell
//
pPrev = pThis;
pThis = pThis->pNext;
}
}
else
{
ICMMSG(("bRemoveColorTransform():There is no colortransform()\n"));
}
return (FALSE);
}
/******************************Public*Routine******************************\
* XDCOBJ::vCleanupColorTransform()
*
* History:
*
* Write it:
* 27-Feb-1997 -by- Hideyuki Nagase [hideyukn]
\**************************************************************************/
VOID XDCOBJ::vCleanupColorTransform(BOOL bProcessCleanup)
{
if (pdc->pCXFList)
{
PCXFLIST pLast, pThis;
pThis = pdc->pCXFList;
while (pThis)
{
COLORTRANSFORMOBJ CXformObj(pThis->hCXform);
pLast = pThis;
if (CXformObj.bValid())
{
//
// Delete this color transform
//
if (CXformObj.bDelete(*this,bProcessCleanup))
{
ICMMSG(("vCleanupColorTransform():Delete colortransform in this DC\n"));
}
else
{
ICMMSG(("vCleanupColorTransform():Fail to delete colortransform in this DC\n"));
}
}
//
// we don't need to walk through the list, because above COLORTRANSFORMOBJ.bDelete()
// will re-chain this list, then we just pick up the cell on the top of list everytime.
//
pThis = pdc->pCXFList;
//
// But if still new pThis is eqaul to pLast, this means we might fail to
// delete object or un-chain list, then just un-chain this forcely.
//
if (pThis == pLast)
{
//
// Skip pThis.
//
pThis = pThis->pNext;
//
// Update root too,
//
pdc->pCXFList = pThis;
}
}
}
else
{
// ICMMSG(("vCleanupColorTransform():There is no color transform in this DC\n"));
}
}
/******************************Public*Routine******************************\
* XEPALOBJ::CorrectColors()
*
* History:
*
* Write it:
* 29-Apr-1997 -by- Hideyuki Nagase [hideyukn]
\**************************************************************************/
VOID XEPALOBJ::CorrectColors(PPALETTEENTRY ppalentry, ULONG cEntries)
{
ICMMSG(("XEPALOBJ::CorrectColors\n"));
PDEVOBJ po(hdevOwner());
if (po.bValid())
{
if (po.bHasGammaRampTable())
{
ICMMSG(("XEPALOBJ::CorrectColors(): Do Gamma Correction\n"));
ICMMSG(("XEPALOBJ::CorrectColors(): GammaRamp Owner HDEV = %x\n",po.hdev()));
PGAMMARAMP_ARRAY pGammaRampArray = (PGAMMARAMP_ARRAY)(po.pvGammaRampTable());
for (ULONG i = 0; i < cEntries; i++)
{
//
// Adjust colors based on GammaRamp table.
//
ppalentry->peRed = (pGammaRampArray->Red[ppalentry->peRed]) >> 8;
ppalentry->peGreen = (pGammaRampArray->Green[ppalentry->peGreen]) >> 8;
ppalentry->peBlue = (pGammaRampArray->Blue[ppalentry->peBlue]) >> 8;
//
// next palette entry
//
ppalentry++;
}
}
else
{
ICMMSG(("XEPALOBJ::CorrectColors(): PDEV does not have Gamma Table\n"));
}
}
else
{
ICMMSG(("XEPALOBJ::CorrectColors(): PDEV is invalid\n"));
}
}
/******************************Public*Routine******************************\
* UpdateGammaRampOnDevice()
*
* History:
*
* Write it:
* 29-Apr-1997 -by- Hideyuki Nagase [hideyukn]
\**************************************************************************/
BOOL UpdateGammaRampOnDevice(HDEV hdev,BOOL bForceUpdate)
{
BOOL bRet = FALSE;
ICMMSG(("UpdateGammaRampOnDevice()\n"));
PDEVOBJ po(hdev);
if (po.bValid())
{
ICMMSG(("UpdateGammaRampOnDevice():Set GammaRamp to HDEV = %x\n",po.hdev()));
if ((po.iDitherFormat() == BMF_8BPP) ||
(po.iDitherFormat() == BMF_16BPP) ||
(po.iDitherFormat() == BMF_24BPP) ||
(po.iDitherFormat() == BMF_32BPP))
{
//
// Driver might provide the entry point.
//
if ((PPFNVALID(po, IcmSetDeviceGammaRamp)) &&
(po.flGraphicsCaps2() & GCAPS2_CHANGEGAMMARAMP))
{
//
// PDEV should have GammaRampTable
//
if (po.bHasGammaRampTable())
{
ICMMSG(("UpdateGammaRampOnDevice():Call SetDeviceGammaRamp()\n"));
//
// Call device driver to set new GammaRamp.
//
bRet = (*PPFNDRV(po, IcmSetDeviceGammaRamp))(po.dhpdev(),
IGRF_RGB_256WORDS,
po.pvGammaRampTable());
}
}
else
{
//
// if the drive does not support, we will simulate it only for 8bpp case.
//
if ((po.iDitherFormat() == BMF_8BPP) && (po.bIsPalManaged()))
{
ICMMSG(("UpdateGammaRampOnDevice(): Call SetPalette()\n"));
//
// Check:
// 1) Are we going to reset pallete forcely ? (ex. back to default GammaRamp)
// 2) Or, Adjust Palette based on GammaRamp in PDEV.
//
if (bForceUpdate || po.bHasGammaRampTable())
{
//
// Get palette on device surface.
//
XEPALOBJ palSurf(po.ppalSurf());
ASSERTGDI(palSurf.bIsIndexed(),"UpdateGammaRampOnDevice(): Palette is not indexed\n");
//
// Mark this palette need to Gamma correction
// (if this is not default GammaRamp, default GammaRamp case
// PDEV does not have table.)
//
palSurf.bNeedGammaCorrection(po.bHasGammaRampTable());
//
// And put owner of PDEV which has GammaRamp table.
// (if they already has some value in there, we will
// overwrite it, but actually it should be same or
// uninitialized.)
//
palSurf.hdevOwner(po.hdev());
ICMMSG(("UpdateGammaRampOnDevice():Set GammaRamp to HDEV = %x\n",po.hdev()));
//
// Update palettes based on new GammaRamp.
//
// (Color will be adjusted in PALOBJ_cGetColors())
//
GreAcquireSemaphoreEx(po.hsemDevLock(), SEMORDER_DEVLOCK, NULL);
GreEnterMonitoredSection(po.ppdev, WD_DEVLOCK);
{
SEMOBJ so(po.hsemPointer());
if (!po.bDisabled())
{
ASSERTGDI(PPFNVALID(po,SetPalette),"ERROR palette is not managed");
bRet = (*PPFNDRV(po, SetPalette))(po.dhpdev(),
(PALOBJ *) &palSurf,
0, 0, palSurf.cEntries());
}
}
GreExitMonitoredSection(po.ppdev, WD_DEVLOCK);
GreReleaseSemaphoreEx(po.hsemDevLock());
}
}
else
{
ICMMSG(("UpdateGammaRampOnDevice():Driver doesn't have DrvSetDeviceGammaRamp()\n"));
}
}
}
else
{
//
// Can not set GammaRamp for 1/4 bpp surface
//
ICMMSG(("UpdateGammaRampOnDevice():GammaRamp does not support on 1/4 bpp\n"));
}
if (!bRet)
{
ICMMSG(("UpdateGammaRampOnDevice(): device driver returns error\n"));
}
}
else
{
ICMMSG(("UpdateGammaRampOnDevice(): HDEV is invalid\n"));
}
return (bRet);
}
/******************************Public*Routine******************************\
* GetColorManagementCaps()
*
* History:
*
* Write it:
* 24-Feb-1998 -by- Hideyuki Nagase [hideyukn]
\**************************************************************************/
ULONG GetColorManagementCaps(PDEVOBJ& po)
{
ULONG fl = CM_NONE;
PDEVINFO pDevInfo = po.pdevinfoNotDynamic();
//
// Check CM_GAMMA_RAMP - it will be enabled when
//
// 0) Only for display device.
// 1) DitherFormat is 8bpp. (GDI simulate regardless driver capabilities)
// 2) Driver can do it.
//
if (po.bDisplayPDEV())
{
if ((pDevInfo->iDitherFormat == BMF_8BPP) ||
(po.flGraphicsCaps2NotDynamic() & GCAPS2_CHANGEGAMMARAMP))
{
fl |= CM_GAMMA_RAMP;
}
}
//
// Check CM_CMYK_COLOR when driver can understand.
//
if (po.flGraphicsCapsNotDynamic() & GCAPS_CMYKCOLOR)
{
fl |= CM_CMYK_COLOR;
}
//
// Check CM_DEVICE_ICM when driver can do.
//
if (po.flGraphicsCapsNotDynamic() & GCAPS_ICM)
{
fl |= CM_DEVICE_ICM;
}
return fl;
}