📄 bkldrvmain.cpp
字号:
{
pBKLinfo->dwBattTimeout = (*(DWORD *)bData );
}
//Backlight on AC timeout
dwType=REG_DWORD;
cbData = MAX_PATH;
retCode = RegQueryValueEx(hKey, TEXT("ACTimeout"), NULL, &dwType, (LPBYTE) bData, (LPDWORD)&cbData);
if (retCode == ERROR_SUCCESS)
{
pBKLinfo->dwACTimeout = (*(DWORD *)bData );
}
}
goto exit;
exit:
if(hKey)
{
RegCloseKey(hKey);
}
DEBUGMSG(ZONE_BACKLIGHT,(TEXT("-BacklightReadMDDReg\r\n")));
}
/*
Ask power manager to set the BKL power state.
PM will not ask BKL to change states again until
called with PwrDeviceUnspecified
*/
void BKL_SetDevicePower(BKL_MDD_INFO *pBKLinfo, CEDEVICE_POWER_STATE bklPowerState)
{
SetDevicePower(pBKLinfo->szName, POWER_NAME, bklPowerState);
return;
}
// Update the backlight reg settings or power status
// Set power requirment for backlight to D4 (off) if 'Tap On' setting unchecked
// and unspecified if 'Tap On' setting just checked. Similarly if 'Turn Off Backlight' timeout option
// has just been selected/deselected:
void UpdateBacklight(BKL_MDD_INFO *pBKLinfo, DWORD dwReason)
{
BOOL fTapOnPrev, fTapOnNew;
DWORD dwTimeoutPrev, dwTimeoutNew;
BOOL fSetPowerOff = FALSE;
BOOL fReleasePwrOff = FALSE;
fTapOnPrev = IsTapOn(pBKLinfo);
dwTimeoutPrev = GetTimeout(pBKLinfo);
switch(dwReason)
{
case BKL_EVENT_REG:
// Have registry keys changed?
BacklightUpdateMDDRegSettings(pBKLinfo);
break;
case BKL_EVENT_POWER_MSG:
// AC Status changed?
UpdateACStatus(pBKLinfo);
break;
};
dwTimeoutNew = GetTimeout(pBKLinfo);
fTapOnNew = IsTapOn(pBKLinfo);
// 'Tap On' settings just unchecked or 'Turn off backlight' timer option just selected:
fSetPowerOff = ( ((dwTimeoutPrev != TURNOFFIMMEDIATELY) && (dwTimeoutNew == TURNOFFIMMEDIATELY)) \
|| ((fTapOnPrev && !fTapOnNew)));
// 'Tap On' setting just checked or 'Turn off backlight' timer option just deselected:
fReleasePwrOff = (((dwTimeoutPrev == TURNOFFIMMEDIATELY) && (dwTimeoutNew != TURNOFFIMMEDIATELY) ) \
|| (!fTapOnPrev && fTapOnNew));
if(fSetPowerOff)
{
BKL_SetDevicePower(pBKLinfo, D4);
}
else if (fReleasePwrOff)
{
BKL_SetDevicePower(pBKLinfo, PwrDeviceUnspecified);
}
}
/*
Monitors changes in reg keys 'BacklightOnTap' and 'ACBacklightOnTap'
and changes in power status (AC->DC / DC->AC)
*/
DWORD fnBackLightThread(PVOID pvArgument)
{
DWORD dwResult;
MSGQUEUEOPTIONS msgopts;
HANDLE hPwrNotification = NULL;
HANDLE hPowerNotificationMsgs = NULL;
HKEY hKey = NULL;
HANDLE WaitEvents[BKL_NUM_EVENTS];
HANDLE hEventRegistryChange = NULL;
DWORD dwSize;
DWORD dwFlags;
HANDLE hDisplayNotifications = NULL;
HANDLE hDisplayNotificationMsgs = NULL;
GUID idInterface;
BKL_MDD_INFO *pBKLinfo = NULL;
DEBUGMSG(ZONE_BACKLIGHT,(TEXT("+fnBackLightRegThread\r\n")));
// Verify context
if(! pvArgument)
{
RETAILMSG(ZONE_ERROR, (L"ERROR: BacklightThread: "
L"Incorrect context paramer\r\n" ));
return FALSE;
}
pBKLinfo = (BKL_MDD_INFO*) pvArgument;
// create msg queue for power status change notification (AC->Battery and vice versa)
memset(&msgopts, 0, sizeof(msgopts));
msgopts.dwSize = sizeof(msgopts);
msgopts.dwFlags = 0;
msgopts.dwMaxMessages = 0; // no max number of messages
msgopts.cbMaxMessage = sizeof(POWER_BROADCAST); // max size of each msg
msgopts.bReadAccess = TRUE;
hPowerNotificationMsgs = CreateMsgQueue(NULL, &msgopts);
if (!hPowerNotificationMsgs)
{
RETAILMSG(ZONE_ERROR, (TEXT("BKL: Create message queue failed\r\n")));
goto exit;
}
// request notification of power status changes:
hPwrNotification = RequestPowerNotifications(hPowerNotificationMsgs, PBT_POWERSTATUSCHANGE);
if (!hPwrNotification)
{
RETAILMSG(ZONE_ERROR, (TEXT("BKL: register power notification failed\r\n")));
goto exit;
}
// create msg queue for display device interface notifications:
msgopts.cbMaxMessage = PNP_QUEUE_SIZE;
hDisplayNotificationMsgs = CreateMsgQueue(NULL, &msgopts);
if (!hDisplayNotificationMsgs)
{
RETAILMSG(ZONE_ERROR, (TEXT("BKL: Create message queue failed\r\n")));
goto exit;
}
if(!ConvertStringToGuid(PMCLASS_DISPLAY, &idInterface))
{
RETAILMSG(ZONE_ERROR, (TEXT("can't convert PMCLASS_DISPLAY string to GUID\r\n")));
goto exit;
}
// get display driver name (required to keep display driver on with SetPowerRequirement):
if(!(hDisplayNotifications = RequestDeviceNotifications(&idInterface, hDisplayNotificationMsgs, TRUE)))
{
RETAILMSG(ZONE_ERROR, (TEXT("RequestDeviceNotifications failed\r\n")));
goto exit;
}
dwResult = RegOpenKeyEx(HKEY_CURRENT_USER, BACKLIGHT_REGKEY, 0, KEY_NOTIFY, &hKey);
if(ERROR_SUCCESS != dwResult)
{
goto exit;
}
// Request notification of backlight registry changes:
hEventRegistryChange = CeFindFirstRegChange(hKey, FALSE, REG_NOTIFY_CHANGE_LAST_SET);
if(INVALID_HANDLE_VALUE == hEventRegistryChange)
{
RETAILMSG(ZONE_ERROR, (TEXT("BKL: CeFindFirstRegChange failed\r\n")));
goto exit;
}
RegCloseKey(hKey);
hKey = NULL;
BacklightUpdateMDDRegSettings(pBKLinfo);
UpdateACStatus(pBKLinfo);
WaitEvents[BKL_EVENT_REG] = hEventRegistryChange;
WaitEvents[BKL_EVENT_POWER_MSG] = hPowerNotificationMsgs;
WaitEvents[BKL_EVENT_EXIT] = pBKLinfo->hExitEvent;
WaitEvents[BKL_EVENT_DISPLAY_MSG] = hDisplayNotificationMsgs;
pBKLinfo->fExit = FALSE;
while(!pBKLinfo->fExit)
{
dwResult = WaitForMultipleObjects(BKL_NUM_EVENTS, &WaitEvents[0], FALSE, INFINITE);
switch(dwResult)
{
case(WAIT_OBJECT_0 + BKL_EVENT_REG):
{
DEBUGMSG(ZONE_BACKLIGHT,(TEXT("Backlight mdd registry change\r\n")));
UpdateBacklight(pBKLinfo, BKL_EVENT_REG);
CeFindNextRegChange(hEventRegistryChange);
// Tell PDD that the backlight reg settings changed:
BacklightRegChanged();
}
break;
case (WAIT_OBJECT_0 + BKL_EVENT_POWER_MSG):
{
POWER_BROADCAST PwrMsgBuf;
DEBUGMSG(ZONE_BACKLIGHT,(TEXT("Power status change to/from AC\r\n")));
if (!ReadMsgQueue(hPowerNotificationMsgs, &PwrMsgBuf, sizeof(PwrMsgBuf), &dwSize, 0, &dwFlags))
{
DEBUGMSG(ZONE_BACKLIGHT,(TEXT("ReadMsgQueue failed\r\n")));
ASSERT(FALSE);
}
UpdateBacklight(pBKLinfo, BKL_EVENT_POWER_MSG);
// tell PDD that power source changed:
BacklightPwrSrcChanged(pBKLinfo->fOnAC);
}
break;
case (WAIT_OBJECT_0 + BKL_EVENT_DISPLAY_MSG):
{
union
{
UCHAR deviceBuf[PNP_QUEUE_SIZE];
DEVDETAIL devDetail;
} u;
DEBUGMSG(ZONE_BACKLIGHT,(TEXT("Display driver interface notification\r\n")));
if (!ReadMsgQueue(hDisplayNotificationMsgs, u.deviceBuf, PNP_QUEUE_SIZE, &dwSize, 0, &dwFlags))
{
DEBUGMSG(ZONE_BACKLIGHT,(TEXT("ReadMsgQueue failed\r\n")));
ASSERT(FALSE);
}
else if(dwSize >= sizeof(DEVDETAIL))
{
PDEVDETAIL pDevDetail = &u.devDetail;
if(( (pDevDetail->cbName + sizeof(TCHAR) < sizeof(pBKLinfo->szDisplayInterface) )
// Check overflow AND underflow
&& ( (int)(pDevDetail->cbName + sizeof(TCHAR)) > pDevDetail->cbName)
&& (int)(pDevDetail->cbName) >= 0) )
{
memcpy(pBKLinfo->szDisplayInterface, pDevDetail->szName, pDevDetail->cbName);
// make sure it's null terminated:
pBKLinfo->szDisplayInterface[pDevDetail->cbName] = '\0';
}
}
else
{
DEBUGMSG(ZONE_BACKLIGHT,(TEXT("insufficient buffer for device message\r\n")));
}
}
break;
case(WAIT_OBJECT_0 + BKL_EVENT_EXIT):
{
DEBUGMSG(ZONE_BACKLIGHT,(TEXT("Backlight exiting\r\n")));
}
break;
default:
{
ASSERT(FALSE);
}
}
}
exit:
if (hPwrNotification)
{
StopPowerNotifications(hPwrNotification);
}
if (hPowerNotificationMsgs)
{
CloseMsgQueue(hPowerNotificationMsgs);
}
if (hDisplayNotifications)
{
StopDeviceNotifications(hDisplayNotifications);
}
if (hDisplayNotificationMsgs)
{
CloseMsgQueue(hDisplayNotificationMsgs);
}
if(hEventRegistryChange)
{
CeFindCloseRegChange(hEventRegistryChange);
}
if(hKey)
{
RegCloseKey(hKey);
}
DEBUGMSG(ZONE_BACKLIGHT,(TEXT("-fnBackLightRegThread\r\n")));
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -