📄 bkldrvmain.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//
//------------------------------------------------------------------------------
//
// File: bkldrvmain.c
//
// Backlight driver source code
//
#include <windows.h>
#include <windev.h>
#include <pnp.h>
#include <pm.h>
#include <strsafe.h>
#include "BKLi.h"
#include "BKLPDD.h"
DBGPARAM dpCurSettings = {
TEXT("backlight"), {
TEXT("Backlight"), TEXT("Function"), TEXT("Misc"), TEXT(""),
TEXT(""), TEXT(""), TEXT(""), TEXT(""),
TEXT(""), TEXT(""), TEXT(""), TEXT(""),
TEXT(""), TEXT(""), TEXT("Warning"), TEXT("Error"),
},
0xC001
};
#define BACKLIGHT_REGKEY TEXT("ControlPanel\\Backlight")
#define BKL_EVENT_REG 0 // registry change
#define BKL_EVENT_POWER_MSG 1 // power status change
#define BKL_EVENT_EXIT 2 // we're exiting
#define BKL_EVENT_DISPLAY_MSG 3 // display device notification
#define BKL_NUM_EVENTS 4
#define TURNOFFIMMEDIATELY -1
// device notification queue parameters
#define PNP_QUEUE_ENTRIES 1 // assumes we have only 1 display driver interface being advertised
//"The notifications sent to hMsgQ are a sequence of DEVDETAIL structures
//with extra TCHAR types appended to account for the instance names":
#define PNP_QUEUE_SIZE (PNP_QUEUE_ENTRIES * (sizeof(DEVDETAIL) + (MAX_NAMELEN * sizeof(TCHAR))))
static const UCHAR DeviceStateMasks[5]={
DX_MASK(D0),
DX_MASK(D1),
DX_MASK(D2),
DX_MASK(D3),
DX_MASK(D4),
};
BOOL ConvertStringToGuid(LPCTSTR GuidString, GUID *Guid )
{
// ConvertStringToGuid
// this routine converts a string into a GUID and returns TRUE if the
// conversion was successful.
// Local variables.
UINT Data4[8];
int Count;
BOOL Ok = FALSE;
LPWSTR GuidFormat = L"{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}";
DEBUGCHK(Guid != NULL && GuidString != NULL);
__try
{
if (_stscanf(GuidString, GuidFormat, &Guid->Data1,
&Guid->Data2, &Guid->Data3, &Data4[0], &Data4[1], &Data4[2], &Data4[3],
&Data4[4], &Data4[5], &Data4[6], &Data4[7]) == 11) {
for (Count = 0; Count < (sizeof(Data4) / sizeof(Data4[0])); Count++) {
Guid->Data4[Count] = (UCHAR) Data4[Count];
}
}
Ok = TRUE;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
RETAILMSG(ZONE_ERROR, (TEXT("exception in convertstringtoguid\r\n")));
}
return Ok;
}
void UpdateACStatus(BKL_MDD_INFO *pBKLinfo)
{
SYSTEM_POWER_STATUS_EX2 SysPower;
static fFirstTime = TRUE;
// make sure that GWES APIs ready before calling:
if (WAIT_OBJECT_0 != WaitForAPIReady(SH_GDI, INFINITE))
{
RETAILMSG(ZONE_ERROR, (TEXT("Backlight driver: WaitForAPIReady failed.\r\n")));
return;
}
if (pBKLinfo->pfnGetSystemPowerStatusEx2)
{
if ((*pBKLinfo->pfnGetSystemPowerStatusEx2)(&SysPower, sizeof(SysPower), FALSE))
{
if (SysPower.ACLineStatus & AC_LINE_ONLINE)
{
pBKLinfo->fOnAC = TRUE;
}
else
{
pBKLinfo->fOnAC = FALSE;
}
}
else
{
RETAILMSG(ZONE_ERROR, (TEXT("GetSystemPowerStstusEx2 failed with error 0x%x.\r\n"), GetLastError()));
}
}
else
{
// There are no battery APIs so assume that we are always on AC power.
pBKLinfo->fOnAC = TRUE;
}
return;
}
/*
A driver that is issued a request to enter a power state not supported by its device
enters the next available power state supported.
For example, if the Power Manager requests that it enter D2 and does not support D2,
the device can enter D3 or D4 instead.
If a device is requested to enter D3 and cannot wake up the system then
it should enter D4 and power off rather than staying in standby
All drivers must support at least D0
Note: since the default PDA power manager will never ask a driver to go to a state
that the driver has reported it supports, most of this code will never be called.
The code could be made more efficient (no branching) if deemed necessary
*/
BOOL GetBestSupportedState(BKL_MDD_INFO *pBKLinfo, CEDEVICE_POWER_STATE ReqDx, CEDEVICE_POWER_STATE* SetDx)
{
BOOL fRet = TRUE; // assume there's a suitable state we can go to
switch(ReqDx)
{
case D0:
*SetDx = D0;
break;
case D1:
if(pBKLinfo->ucSupportedStatesMask & DeviceStateMasks[D1])
{
*SetDx = D1;
}
else if(pBKLinfo->ucSupportedStatesMask & DeviceStateMasks[D2])
{
*SetDx = D2;
}
else if(pBKLinfo->ucSupportedStatesMask & DeviceStateMasks[D3])
{
*SetDx = D3;
}
else if(pBKLinfo->ucSupportedStatesMask & DeviceStateMasks[D4])
{
*SetDx = D4;
}
else
{
fRet = FALSE;
}
break;
case D2:
if(pBKLinfo->ucSupportedStatesMask & DeviceStateMasks[D2])
{
*SetDx = D2;
}
else if(pBKLinfo->ucSupportedStatesMask & DeviceStateMasks[D3])
{
*SetDx = D3;
}
else if(pBKLinfo->ucSupportedStatesMask & DeviceStateMasks[D4])
{
*SetDx = D4;
}
else
{
fRet = FALSE;
}
break;
case D3:
if(pBKLinfo->ucSupportedStatesMask & DeviceStateMasks[D3])
{
*SetDx = D3;
}
else if(pBKLinfo->ucSupportedStatesMask & DeviceStateMasks[D4])
{
*SetDx = D4;
}
else
{
fRet = FALSE;
}
break;
case D4:
if(pBKLinfo->ucSupportedStatesMask & DeviceStateMasks[D4])
{
*SetDx = D4;
}
else
{
fRet = FALSE;
}
break;
default:
ASSERT(FALSE);
break;
}
return fRet;
}
/*
Has the user checked the 'turn on when key pressed...' option for the current power status?
*/
BOOL IsTapOn(BKL_MDD_INFO *pBKLinfo)
{
if(pBKLinfo->fOnAC)
{
return (pBKLinfo->fExternalTapOn? TRUE : FALSE);
}
else
{
return (pBKLinfo->fBatteryTapOn? TRUE : FALSE);
}
}
DWORD GetTimeout(BKL_MDD_INFO *pBKLinfo)
{
if(pBKLinfo->fOnAC)
{
return pBKLinfo->dwACTimeout;
}
else
{
return pBKLinfo->dwBattTimeout;
}
}
/*
Reads the 'turn on when key pressed...' registry settings from the registry
*/
void BacklightUpdateMDDRegSettings(BKL_MDD_INFO *pBKLinfo)
{
DWORD retCode;
BYTE ValueData[MAX_PATH];
DWORD dwType;
void *bData = ValueData;
DWORD cbData;
HKEY hKey;
DEBUGMSG(ZONE_BACKLIGHT,(TEXT("+BacklightReadMDDReg\r\n")));
retCode = RegOpenKeyEx (HKEY_CURRENT_USER, BACKLIGHT_REGKEY, 0, KEY_ALL_ACCESS, &hKey);
if (retCode == ERROR_SUCCESS)
{
//Battery Tap
dwType=REG_DWORD;
cbData = MAX_PATH;
retCode = RegQueryValueEx(hKey, TEXT("BacklightOnTap"), NULL, &dwType, (LPBYTE) bData, (LPDWORD)&cbData);
if (retCode == ERROR_SUCCESS)
{
pBKLinfo->fBatteryTapOn = (*(DWORD *)bData );
}
//External Tap
dwType=REG_DWORD;
cbData = MAX_PATH;
retCode = RegQueryValueEx(hKey, TEXT("ACBacklightOnTap"), NULL, &dwType, (LPBYTE) bData, (LPDWORD)&cbData);
if (retCode == ERROR_SUCCESS)
{
pBKLinfo->fExternalTapOn = (*(DWORD *)bData );
}
//Backlight on battery timeout (we may need to turn the backlight off)
dwType=REG_DWORD;
cbData = MAX_PATH;
retCode = RegQueryValueEx(hKey, TEXT("BatteryTimeout"), NULL, &dwType, (LPBYTE) bData, (LPDWORD)&cbData);
if (retCode == ERROR_SUCCESS)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -