📄 dalgco.c
字号:
if ( ( (ulDisplayType & HW_DISPLAY_TYPE_CRT)
&&(lpCache->ulFlags & DALMODE_CRT_DTREGISTRYEXIST))
||( (ulDisplayType & HW_DISPLAY_TYPE_DFP)
&&(lpCache->ulFlags & DALMODE_DFP_DTREGISTRYEXIST)))
{
return i;
}
}
}
}
return MAX_CACHEDDTM;
}
/****************************Private*Routine*******************************\
*
* BOOL bGetDetailedTimingFromRegistry()
*
* Retrieves detailed timing for the specified mode from the registry. The
* detailed timing is stored under separate key for different display type.
*
\**************************************************************************/
BOOL bGetDetailedTimingFromRegistry(
LPHW_DAL_EXTENSION lpHDE,
ULONG ulDisplayType,
LPDEVMODE_INFO lpMI,
LPDAL_CRTC_TIMING lpTimingInfo)
{
ULONG i;
ULONG ulCacheIndex;
ULONG ulHasRead;
ULONG ulRegExist;
LPDAL_MODEINFO lpDALModeInfo;
DALASSERT((NULL != lpHDE), "bGetDetailedTimingFromRegistry - invalide DAL handle!");
DALASSERT((NULL != lpMI), "bGetDetailedTimingFromRegistry - invalid mode handle!");
DALASSERT((NULL != lpTimingInfo), "bGetDetailedTimingFromRegistry - invalid timing info pointer!");
if (ulDisplayType & HW_DISPLAY_TYPE_CRT)
{
ulHasRead = DALMODE_CRT_DTHASREADFROMREGISTRY;
ulRegExist = DALMODE_CRT_DTREGISTRYEXIST;
}
else if (ulDisplayType & HW_DISPLAY_TYPE_DFP)
{
ulHasRead = DALMODE_DFP_DTHASREADFROMREGISTRY;
ulRegExist = DALMODE_DFP_DTREGISTRYEXIST;
}
else
{
// this function only supports CRT and DFP currently
return FALSE;
}
if (!(bSearchModeTable(lpHDE, (LPDEVMODE_INFO)lpMI, (LPULONG)&i)))
{
// can't happen at this point - something funny is happenning here
return FALSE;
}
lpDALModeInfo = &lpHDE->lpaModes[i];
if ((ulHasRead & lpDALModeInfo->ulFlags) && !(ulRegExist & lpDALModeInfo->ulFlags))
{
// Queried registry before and did not find anything
return FALSE;
}
lpDALModeInfo->ulFlags |= ulHasRead;
lpDALModeInfo->ulFlags &= ~ulRegExist;
// search for the cache anyway. The detailed timing might be queried before for
// different color depth.
ulCacheIndex = bGetDetailedTimingIndexFromCache(lpHDE, ulDisplayType, lpMI);
//DALASSERT((0 <= ulCacheIndex), "bGetDetailedTimingFromRegistry - invalid cache index!");
if (ulCacheIndex < MAX_CACHEDDTM)
{
MOVEMEMORY(lpTimingInfo,
&lpHDE->aCachedDetailedTimings[ulCacheIndex].sDisplayDetailedTiming,
sizeof(DAL_CRTC_TIMING));
lpDALModeInfo->ulFlags |= ulRegExist;
return TRUE;
}
if(bGetDisplayPerModeDTFromRegistry(lpHDE,
ulDisplayType,
(LPDEVMODE_INFO)lpMI,
(LPDAL_CRTC_TIMING)lpTimingInfo))
{
LPREGDETAILEDTIMINGINFO lpCache;
if (!(DALRULE1_READDETAILEDTIMINGPERMODE & lpHDE->ulDalRule1))
{
i = lpHDE->ulCachedDTIndex;
lpCache = &lpHDE->aCachedDetailedTimings[i];
lpCache->ulFlags |= ulRegExist;
lpCache->usPelsWidth = (USHORT)lpMI->ulPelsWidth;
lpCache->usPelsHeight = (USHORT)lpMI->ulPelsHeight;
lpCache->usDisplayFrequency = (USHORT)lpMI->ulDisplayFrequency;
MOVEMEMORY(&lpCache->sDisplayDetailedTiming,
lpTimingInfo,
sizeof(DAL_CRTC_TIMING)); //Save to cache
lpDALModeInfo->ulFlags |= ulRegExist;
lpHDE->ulCachedDTIndex = (i + 1) % MAX_CACHEDDTM;
return TRUE;
}
}
return FALSE;
}
/****************************Private*Routine*******************************\
*
* VOID vControllerSetMode()
*
* Performs all pre-mode, set mode, and adjustment, and post mode calls to
* the controller and displays involved in the set mode call.
*
* Notes: Function assumes the caller has already validate the mode
* so the CRT and Displays used for the mode will all be supported.
*
\**************************************************************************/
VOID vControllerSetMode(
LPHW_DAL_EXTENSION lpHDE,
LPDEVMODE_INFO lpMI,
LPDEVGCO lpController,
ULONG ulDisplays,
ULONG ulDisplayOffset,
ULONG ulDisplayPitch)
{
LPDEVGCO lpOtherController;
LPDEVGDO lpDisplay;
LPDEVCLUT16 lpaGamma16;
DEVCLUT aGamma[256];
LPDEVCLUT lpaGamma;
ULONG ulDisplayTypes;
ULONG ulActiveDisplayCount;
ULONG i;
ULONG ulIndex;
FIXEDPOINT sBandwidth;
//DEVMODE_INFO sPanelNativeMode;
DEVMODE_INFO sModeInfo;
EVENTINFO sEventInfo;
DAL_CRTC_TIMING sTiming;
ULONG ulDriverID;
LPDRIVERDATA lpDriverData;
ULONG ulGCOEventId = GCO_EVENT_DISABLEEXTDESKTOPMODE;
// ensure the DAL does not attempt to set a bad mode to a GCO's controller,
// this has happened before, so this code should catch failures
// The mode parameter can be zero if there is no display connected to it (i.e. to reset controller).
DALASSERT(((0 != lpMI->ulPelsWidth) || (0 == ulDisplays)), "vControllerSetMode - bogus mode width!");
DALASSERT(((0 != lpMI->ulPelsHeight) || (0 == ulDisplays)), "vControllerSetMode - bogus mode height!");
DALASSERT(((0 != lpMI->ulBitsPerPixel) || (0 == ulDisplays)), "vControllerSetMode - bogus mode bpp!");
DALASSERT(((0 != lpMI->ulDisplayFrequency) || (0 == ulDisplays)), "vControllerSetMode - bogus mode refresh!");
ZEROMEMORY(&sTiming, sizeof(DAL_CRTC_TIMING));
// only call DDL when GCO_CALLDDLPPMODECHANGE is set. This flag is set when
// vControllerSetMode is called from DALSetMode or DALCWDDE_ControllerSetConfig.
if (lpController->ulFlags & GCO_CALLDDLPPMODECHANGE)
{
// call PreModeChange
vFillModeChangeInfo(lpHDE, lpMI, lpController, ulDisplays, &sEventInfo);
sEventInfo.ulEvent = DAL_EVENT_CONTROLLERPREMODECHANGE;
DDLEventNotification(lpHDE->hDDL, &sEventInfo);
}
//Reset the state Change flag
lpController->ulStateChangeFlags =0;
// Search through all the drivers to see which one owns this controller
lpaGamma16 = NULL; // in case no driver data is enabled
ulDriverID = 0; // ditto
for (i = 0; i < MAX_NUMBER_CONTROLLERS; i++)
{
lpDriverData = (LPDRIVERDATA) &lpHDE->aDriverData[i];
if (lpDriverData->ulFlags & DRIVERDATA_ENABLED)
{
if (lpHDE->aControllerMap[i] & VECTORFROMINDEX(lpController->ulController))
{
ulDriverID = i;
if (lpDriverData->ulFlags & DRIVERDATA_USEGAMEGAMMA)
{
lpaGamma16 = lpDriverData->aGameGamma16;
} else
{
lpaGamma16 = lpDriverData->aGamma16;
}
if((lpDriverData->ulFlags & DRIVERDATA_DDEXCLUSIVEMODE) ||
(lpHDE->ulFlags & HDAL_INTERNALMODECHANGE))
{
lpMI->ulModeFlags |= DEVMODEFLAG_DDEXCLUSIVEMODE;
}
else
{
lpMI->ulModeFlags &= ~DEVMODEFLAG_DDEXCLUSIVEMODE;
}
break;
}
}
}
// find the pointer to the DAL's data structures for this controller
// from it's index.
if (lpController->lpHWED->ulFunctionHooks & GCO_HOOK_MODE_CHANGES)
{
// controller hooked the pre-mode, post mode callbacks, so
// inform the controller that it's mode is about to change
(*lpController->lpHWED->pfnPreModeChange)(lpController->hGCO,
lpMI,
lpController->ulController);
}
ulDisplayTypes = 0;
ulActiveDisplayCount = 0;
for (i = 0; i < lpHDE->ulDisplaysCount; i++)
{
// this display will be used for this mode.
lpDisplay = (LPDEVGDO) &lpHDE->aDisplays[i];
if (ulDisplays & VECTORFROMINDEX(i))
{
// get the count of displays on this controller;
ulActiveDisplayCount++;
// catch all displays which are participating in the mode call.
if (lpDisplay->lpHWED->ulFunctionHooks & GDO_HOOK_MODE_CHANGES)
{
// display hooked notification of mode, changes, so notify
// the display that the mode is changing.
(*lpDisplay->lpHWED->pfnPreModeChange)(lpDisplay->hGDO, lpMI);
}
// for each display to be programmed in this mode, the DAL need
// ensure the display is in a valid state for switching into the
// new mode.
if ((lpDisplay->ulController != lpController->ulController) &&
(lpDisplay->ulController != GDO_WITHOUT_CONTROLLER))
{
// since this display will change controllers are part of the mode
// being SET, the display need be turned off, and it's state be
// programmed into a standard one.
vSetBlanking(lpHDE, lpDisplay, lpDisplay->ulController, TRUE);
// turn off the display on the controller it is being removed from
lpOtherController = (LPDEVGCO)
&lpHDE->aControllers[lpDisplay->ulController];
lpDisplay->ulController = GDO_WITHOUT_CONTROLLER;
lpOtherController->ulDisplays &= ~(VECTORFROMINDEX(i));
if (lpOtherController->ulDisplays == 0)
{
// no displays remain active on this controller
// I'm not completely sure this is the right thing to do, but
// until someone proves it wrong .... it's done! Basically taking
// all displays away from the controller has the side effect of
// turning it off, and taking it away from the display driver.
vControllerResetMode(lpHDE, lpOtherController);
}
// because this display changed controllers, DAL will need requery
// it's per mode adjustment from the registry after the
// next set mode call, so flag the display to do this. [sah]
lpDisplay->ulFlags |= GDO_QUERYPERMODEADJUSTMENTS;
}
// or in each the types of displays connected to the controller
// to inform the controller of the displays connected, hence
// effecting how the clocks are programmed for the mode.
ulDisplayTypes |= lpDisplay->lpHWED->ulDisplayType;
vSetBlanking(lpHDE, lpDisplay, lpController->ulController, TRUE);
} else if (lpController->ulDisplays & VECTORFROMINDEX(i))
{
// this display was active on the controller, but it is not longer
// participaning on any controller hence release it's ownership.
lpDisplay->ulController = (ULONG)GDO_WITHOUT_CONTROLLER;
lpController->ulDisplays &= ~(VECTORFROMINDEX(i));
// since the display is not participating in any mode blank it.
vSetBlanking(lpHDE, lpDisplay, lpController->ulController, TRUE);
// since the display is not participating in any mode turn it off.
vSetDisplayOff(lpHDE, (LPDEVGDO) lpDisplay);
}
}
if ((lpController->ulFlags & GCO_EXPANSION) &&
(ulDisplayTypes & HW_DISPLAY_TYPES_DIGITAL_MASK))
{
// if the controller has expansion enabled, specify this in the display
// types flag to the GCO on SetMode function call only if an LCD
// is connected
ulDisplayTypes |= HW_DISPLAY_EXPANSION;
}
// Zero initialize the per GCO display detailed timing information
ZEROMEMORY((LPVOID)lpController->sDisplayTimingInfo,
(sizeof(DAL_DISPLAY_TIMING_INFO)*MAX_NUMBER_DISPLAYS));
for (i = 0; i < lpHDE->ulDisplaysCount; i++)
{
if (ulDisplays & VECTORFROMINDEX(i))
{
// this display will be used for this mode.
lpDisplay = (LPDEVGDO) &lpHDE->aDisplays[i];
// This is a generic function that will report to GCO
// some Display related information required to set mode.
// For now it will be used to report wether DFP_EXPANSION
// bit has to be set in a GCO set mode function
// can do
lpDisplay->ulFlags &= ~GDO_PM_LOWREFRESHRATE_SET ; //Reset the PM flag.
lpDisplay->ulCurrentRefreshRate = lpDisplay->ulDefaultRefreshRate;
ulDisplayTypes |= ulDisplaySetModeOptions(lpHDE, lpMI, lpDisplay);
lpController->sDisplayTimingInfo[i].ulDisplayID = i;
bDisplayGetExtDetailedTiming(lpHDE, lpDisplay, lpMI, (LPDAL_DISPLAY_TIMING_INFO)&lpController->sDisplayTimingInfo[i], FALSE);
}
}
lpController->ulDisplayTypes = ulDisplayTypes;
if (ulDisplays != 0)
{
if (lpHDE->bPowerPlaySupported)
{
ULONG ulReturnAction;
// Get the current power state, BIOS or 2D might change it on resume.
if (lpController->lpHWED->ulFunctionHooks2 & GCO_HOOK2_POWERPLAY)
{
(*lpController->lpHWED->pfnGetPowerState)(lpController->hGCO,
(LPULONG)&lpHDE->ulCurrentPowerState,
(LPULONG)&lpHDE->ulNumberOfPowerStates,
(LPDAL_ADAPTERPOWERSTATES)&lpHDE->sAdapterPowerStates);
}
MOVEMEMORY((LPDEVMODE_INFO)&sModeInfo,
(LPDEVMODE_INFO)lpMI,
sizeof(DEVMODE_INFO));
ulSetPowerState(lpHDE,
lpHDE->ulRequestedPowerState,
ulDisplayTypes,
sModeInfo,
(!(lpController->ulController == DAL_PRIMARY_CONTROLLER)),
(ulActiveDisplayCount > 1),
FALSE,
(LPULONG)&ulReturnAction);
}
// store the last mode the controller was in
MOVEMEMORY((LPDEVMO
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -