⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dalgco.c

📁 此代码为WCE5.0下显示器的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        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 + -