📄 backlight.c
字号:
#include "BackLight.h"
//------------------------------------------------------------------------------
// Global Variables in this driver
//------------------------------------------------------------------------------
CRITICAL_SECTION CriticalSection;
CEDEVICE_POWER_STATE PMState = D0;
LPWSTR lpActivePath = NULL;
////////////////////////////
const TCHAR szevtBacklightChange[] = TEXT("BackLightChangeEvent");
const TCHAR szevtPowerChanged[] = TEXT("PowerChangedEvent");
const TCHAR szevtUserInput[] = TEXT("UserInputEvent");
const TCHAR szevtBklLevelChange[] = TEXT("BklLevelChangeEvent"); //"BklLevelChangeEvent"
const TCHAR szregRootKey[] = TEXT("ControlPanel\\Backlight");
const TCHAR szregBatteryTimeout[] = TEXT("BatteryTimeout");
const TCHAR szregACTimeout[] = TEXT("ACTimeout");
const TCHAR szregBatteryAuto[] = TEXT("BacklightOnTap");
const TCHAR szregACAuto[] = TEXT("ACBacklightOnTap");
const TCHAR szregBatteryUse[] = TEXT("UseBattery");
const TCHAR szregACUse[] = TEXT("UseExt");
const TCHAR szRegBatteryLevel[] = TEXT("BattBacklightLevel");
const TCHAR szRegExtLevel[] = TEXT("ACBacklightLevel");
const TCHAR szregBacklightLevel[] = TEXT("BacklightLevel"); //"BacklightLevel"
BLStruct g_BLInfo;
HANDLE g_evtSignal[3];
HANDLE g_evtLevelChange;
HANDLE ManageThread = NULL;
//////////////////////////////////////////////////////
//------------------------------------------------------------------------------
// Functions
//------------------------------------------------------------------------------
BOOL WINAPI
DllMain(HANDLE hinstDLL,
unsigned long dwReason,
LPVOID lpReserved)
{
return TRUE;
}
// uninitialize the backlight
void BLT_Deinit()
{
int i;
RETAILMSG(DBG_MSG, (TEXT("%s\r\n"), _T(__FUNCTION__)));
// Clean up
for(i=0; i<3; i++)
{
if(g_evtSignal[i])
{
CloseHandle(g_evtSignal[i]);
}
}
if(g_evtLevelChange)
{
CloseHandle(g_evtLevelChange);
}
if (ManageThread)
{
if (TerminateThread(ManageThread,1))
CloseHandle(ManageThread);
}
}
BOOL BLT_Init(unsigned long dwContext)
{
InitializeCriticalSection(&CriticalSection);
// Set backlight on as default
g_BLInfo.m_dwStatus = LEVEL_OFF;
BLT_ChangeLevel(LEVEL_DEFAULT);
if (dwContext)
{ // Get the device key from active device registry key
if (lpActivePath = (unsigned short *)LocalAlloc(LPTR, wcslen((LPWSTR)dwContext)*sizeof(WCHAR)+sizeof(WCHAR)))
{
wcscpy(lpActivePath, (LPWSTR)dwContext);
}
RETAILMSG(DBG_MSG, (_T("%s - ActiveKey(copy) = %s (0x%x)\r\n"), _T(__FUNCTION__), lpActivePath, lpActivePath));
}
// Set up the thread.
ManageThread = CreateThread(NULL,0,BLT_BacklightThread,(LPVOID)(&dwContext),0,NULL);
// Set up all the events we need.
g_evtSignal[0] = CreateEvent(NULL, FALSE, FALSE, szevtBacklightChange);
g_evtSignal[1] = CreateEvent(NULL, FALSE, FALSE, szevtPowerChanged);
g_evtSignal[2] = CreateEvent(NULL, FALSE, FALSE, szevtUserInput);
g_evtLevelChange = CreateEvent(NULL, FALSE, FALSE, szevtBklLevelChange);
if(!g_evtSignal[0] || !g_evtSignal[1] || !g_evtSignal[2] || !g_evtLevelChange)
{
BLT_Deinit();
return FALSE;
}
return TRUE;
}
unsigned long
BLT_Open(
unsigned long dwData,
unsigned long dwAccess,
unsigned long dwShareMode
)
{
EnterCriticalSection(&CriticalSection);
RETAILMSG(DBG_MSG, (_T("%s\r\n"), _T(__FUNCTION__)));
LeaveCriticalSection(&CriticalSection);
return 1;
}
BOOL
BLT_Close(
unsigned long dwContext
)
{
EnterCriticalSection(&CriticalSection);
RETAILMSG(DBG_MSG, (_T("%s\r\n"), _T(__FUNCTION__)));
LeaveCriticalSection(&CriticalSection);
return TRUE;
}
BOOL
BLT_IOControl(
unsigned long Handle,
unsigned long dwIoControlCode,
unsigned char * pInBuf,
unsigned long nInBufSize,
unsigned char * pOutBuf,
unsigned long nOutBufSize,
unsigned long * pBytesReturned
)
{
RETAILMSG(DBG_MSG, (_T("%s(%d) entered\r\n"), _T(__FUNCTION__), dwIoControlCode));
//
// Check parameters
//
switch (dwIoControlCode)
{
case IOCTL_POWER_CAPABILITIES:
if (pOutBuf == NULL
|| nOutBufSize < sizeof(POWER_CAPABILITIES)
|| pBytesReturned == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
break;
case IOCTL_POWER_QUERY:
if(pOutBuf == NULL
|| nOutBufSize != sizeof(CEDEVICE_POWER_STATE)
|| pBytesReturned == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
break;
case IOCTL_POWER_SET:
if(pOutBuf == NULL
|| nOutBufSize != sizeof(CEDEVICE_POWER_STATE)
|| pBytesReturned == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
break;
case IOCTL_POWER_GET:
if(pOutBuf == NULL
|| nOutBufSize != sizeof(CEDEVICE_POWER_STATE)
|| pBytesReturned == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
//
// Execute dwIoControlCode
//
switch (dwIoControlCode)
{
case IOCTL_POWER_CAPABILITIES:
{
PPOWER_CAPABILITIES ppc = (PPOWER_CAPABILITIES) pOutBuf;
memset(ppc, 0, sizeof(*ppc));
// ppc->DeviceDx = 0xF; // support all
ppc->DeviceDx = 0xB; // support D0, D1, D3
RETAILMSG(DBG_MSG, (_T("%s - Power Capabilities: 0x%x\r\n"),
_T(__FUNCTION__), ppc->DeviceDx));
*pBytesReturned = sizeof(*ppc);
return TRUE;
}
case IOCTL_POWER_QUERY:
RETAILMSG(DBG_MSG, (_T("%s - Power Query\r\n"), _T(__FUNCTION__)));
return TRUE;
case IOCTL_POWER_SET:
{
// int j;
EnterCriticalSection(&CriticalSection);
PMState = *(PCEDEVICE_POWER_STATE) pOutBuf;
*(PCEDEVICE_POWER_STATE) pOutBuf = PMState;
*pBytesReturned = sizeof(CEDEVICE_POWER_STATE);
RETAILMSG(DBG_MSG, (_T("%s - Power Set: 0x%x\r\n"), _T(__FUNCTION__), PMState));
if (PMState == D0)
SetEvent(g_evtSignal[1]);
if (PMState == D3)
BLT_ChangeLevel(LEVEL_OFF);
LeaveCriticalSection(&CriticalSection);
return TRUE;
}
case IOCTL_POWER_GET:
{
EnterCriticalSection(&CriticalSection);
*(PCEDEVICE_POWER_STATE) pOutBuf = PMState;
*pBytesReturned = sizeof(CEDEVICE_POWER_STATE);
RETAILMSG(DBG_MSG, (_T("%s - Power Get: 0x%x\r\n"), _T(__FUNCTION__), PMState));
LeaveCriticalSection(&CriticalSection);
return TRUE;
}
default:
RETAILMSG(DBG_MSG, (_T("%s - (default) \r\n"), _T(__FUNCTION__)));
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
}
// Utility function to read from registry for the parameters
void BLT_ReadRegistry(BLStruct *pBLInfo)
{
HKEY hKey;
LONG lResult;
DWORD dwType;
DWORD dwVal;
DWORD dwLen;
lResult = RegOpenKeyEx(HKEY_CURRENT_USER, szregRootKey, 0, KEY_ALL_ACCESS, &hKey);
if(ERROR_SUCCESS == lResult) {
dwType = REG_DWORD;
dwLen = sizeof(DWORD);
lResult = RegQueryValueEx(hKey, szregBatteryTimeout, NULL, &dwType,
(LPBYTE)&dwVal, &dwLen);
if(ERROR_SUCCESS == lResult) {
pBLInfo->m_dwBatteryTimeout = dwVal;
}
lResult = RegQueryValueEx(hKey, szregBatteryAuto, NULL, &dwType, (LPBYTE)&dwVal,
&dwLen);
if(ERROR_SUCCESS == lResult) {
pBLInfo->m_bBatteryAuto = (BOOL) dwVal;
}
lResult = RegQueryValueEx(hKey, szregBatteryUse, NULL, &dwType, (LPBYTE)&dwVal,
&dwLen);
if(ERROR_SUCCESS == lResult) {
if (!dwVal)
pBLInfo->m_dwBatteryTimeout = 0;
}
lResult = RegQueryValueEx(hKey, szRegBatteryLevel, NULL, &dwType, (LPBYTE)&dwVal,
&dwLen);
if(ERROR_SUCCESS == lResult) {
pBLInfo->m_dwUserLevel = dwVal;
}
/*
lResult = RegQueryValueEx(hKey, szregACTimeout, NULL, &dwType, (LPBYTE)&dwVal,
&dwLen);
if(ERROR_SUCCESS == lResult) {
pBLInfo->m_dwACTimeout = dwVal;
}
lResult = RegQueryValueEx(hKey, szregACAuto, NULL, &dwType, (LPBYTE)&dwVal,
&dwLen);
if(ERROR_SUCCESS == lResult) {
pBLInfo->m_bACAuto = (BOOL) dwVal;
}
*/
RegCloseKey(hKey);
}
else {
RETAILMSG(DBG_MSG, (TEXT("%s - HKEY_CURRENT_USER\\%s key doesn't exist!\r\n"), _T(__FUNCTION__), szregRootKey));
}
}
void BLT_WriteRegistry(BLStruct *pBLInfo)
{
HKEY hKey;
LONG lResult;
DWORD dwType;
DWORD dwVal;
DWORD dwLen;
lResult = RegOpenKeyEx(HKEY_CURRENT_USER, szregRootKey, 0, KEY_ALL_ACCESS, &hKey);
if(ERROR_SUCCESS == lResult) {
dwType = REG_DWORD;
dwLen = sizeof(DWORD);
dwVal = pBLInfo->m_dwStatus;
lResult = RegSetValueEx(hKey, szregBacklightLevel, 0, dwType,
(LPBYTE)&dwVal, dwLen);
if(ERROR_SUCCESS != lResult) {
pBLInfo->m_dwStatus = LEVEL_OFF;
} // If failed, we set the status to the default value:0
RegCloseKey(hKey);
}
else {
RETAILMSG(DBG_MSG, (TEXT("%s - HKEY_CURRENT_USER\\%s key doesn't exist!\r\n"), _T(__FUNCTION__), szregRootKey));
}
}
void BLT_ChangeLevel(unsigned long level)
{
if (level >= 0 && level <= 20)
{
if (g_BLInfo.m_dwStatus != level)
{
g_BLInfo.m_dwStatus = level;
BLT_WriteRegistry(&g_BLInfo);
SetEvent(g_evtLevelChange);
RETAILMSG(1, (_T("%s - *** %d ***^^^^^^^\r\n"), _T(__FUNCTION__), level));
}
}
}
unsigned long WINAPI
BLT_BacklightThread(LPVOID dwContext)
{
DWORD dwResult;
DWORD dwTimeout;
SetThreadPriority(GetCurrentThread, 106);
// Initialization stuff is here
//
// Initialize the events
// Initialize the BLInfo data structure
// Those are default values. Modify them if necessary
g_BLInfo.m_bACAuto = TRUE;
g_BLInfo.m_bBatteryAuto = TRUE;
g_BLInfo.m_dwBatteryTimeout = 20; // 20 Seconds
g_BLInfo.m_dwACTimeout = 60; // 1 minutes
g_BLInfo.m_dwUserLevel = LEVEL_DEFAULT; // set to default backlignt level
// Now read from the registry to see what they say
BLT_ReadRegistry(&g_BLInfo);
// RETAILMSG(DBG_MSG, (_T("%s - m_bACAuto:%d\r\n"), _T(__FUNCTION__), g_BLInfo.m_bACAuto));
RETAILMSG(DBG_MSG, (_T("%s - m_bBatteryAuto:%d\r\n"), _T(__FUNCTION__), g_BLInfo.m_bBatteryAuto));
RETAILMSG(DBG_MSG, (_T("%s - m_dwBatteryTimeout:%d\r\n"), _T(__FUNCTION__), g_BLInfo.m_dwBatteryTimeout));
// RETAILMSG(DBG_MSG, (_T("%s - m_dwACTimeout:%d\r\n"), _T(__FUNCTION__), g_BLInfo.m_dwACTimeout));
RETAILMSG(DBG_MSG, (_T("%s - m_dwUserLevel:%d\r\n"), _T(__FUNCTION__), g_BLInfo.m_dwUserLevel));
while(1) {
__try {
dwTimeout = g_BLInfo.m_dwBatteryTimeout * 1000;
// However, if user wants BL on all the time, we have to let him
// do that. Or if we come back here, and BL is off, we want to
// put this thread to sleep until other event happens.
if(dwTimeout == 0 || g_BLInfo.m_dwStatus == LEVEL_OFF)
{
dwTimeout = INFINITE;
}
// Now let's wait for either there is an update on registry, or
// there is user action on the device, or there is activity on
// AC power supply.
dwResult = WaitForMultipleObjects(3, &g_evtSignal[0], FALSE, dwTimeout);
// If we are signaled by registry event
if(WAIT_OBJECT_0 == dwResult) {
// All we need to do is to read from registry and update the tick count
RETAILMSG(DBG_MSG, (_T("%s - BackLight Thread: registry edit!\r\n"), _T(__FUNCTION__)));
Sleep(50); // Wait a little while
BLT_ReadRegistry(&g_BLInfo);
RETAILMSG(DBG_MSG, (_T("%s - m_bBatteryAuto:%d\r\n"), _T(__FUNCTION__), g_BLInfo.m_bBatteryAuto));
RETAILMSG(DBG_MSG, (_T("%s - m_dwBatteryTimeout:%d\r\n"), _T(__FUNCTION__), g_BLInfo.m_dwBatteryTimeout));
// RETAILMSG(DBG_MSG, (_T("%s - m_dwACTimeout:%d\r\n"), _T(__FUNCTION__), g_BLInfo.m_dwACTimeout));
// RETAILMSG(DBG_MSG, (_T("%s - m_bACAuto:%d\r\n"), _T(__FUNCTION__), g_BLInfo.m_bACAuto));
RETAILMSG(DBG_MSG, (_T("%s - m_dwUserLevel:%d\r\n"), _T(__FUNCTION__), g_BLInfo.m_dwUserLevel));
// Always turn on the Backlight after a change to registry
BLT_ChangeLevel(g_BLInfo.m_dwUserLevel);
}
else if(dwResult == WAIT_OBJECT_0+1) {
// When AC is plugged or un-plugged, we don't really need to do anything
// We continue the loop. The correct timeout value will be assigned at
// the top of the while loop.
RETAILMSG(DBG_MSG, (_T("%s - BackLight Thread: power changed!\r\n"), _T(__FUNCTION__)));
BLT_ChangeLevel(g_BLInfo.m_dwUserLevel);
}
else if(dwResult == WAIT_OBJECT_0+2) {
RETAILMSG(DBG_MSG, (_T("%s - BackLight Thread: user input!\r\n"), _T(__FUNCTION__)));
BLT_ChangeLevel(g_BLInfo.m_dwUserLevel);
}
else if(dwResult == WAIT_TIMEOUT) {
// Time out, let's turn the device off
RETAILMSG(DBG_MSG, (_T("%s - Timeout, turn off the backlight!\r\n"), _T(__FUNCTION__)));
BLT_ChangeLevel(LEVEL_OFF);
}
else {
RETAILMSG(DBG_MSG, (_T("%s - Do nothing!\r\n"), _T(__FUNCTION__)));
}
}
__except(EXCEPTION_EXECUTE_HANDLER){
// do nothing
RETAILMSG(DBG_MSG, (_T("%s - An exception is raised in BLT_MonitorThread... \r\n"), _T(__FUNCTION__)));
}
}
return 1;
}
//------------------------------------------------------------------------------
//
// Reserved
//
//------------------------------------------------------------------------------
unsigned long BLT_Read(unsigned long Handle, LPVOID pBuffer, unsigned long dwNumBytes){return 0;}
unsigned long BLT_Write(unsigned long Handle, LPVOID pBuffer, unsigned long dwNumBytes){return 0;}
unsigned long BLT_Seek(unsigned long Handle, long lDistance, unsigned long dwMoveMethod){return 0;}
void BLT_PowerUp(void){RETAILMSG(DBG_MSG, (_T("%s\r\n"), _T(__FUNCTION__)));}
void BLT_PowerDown(void){RETAILMSG(DBG_MSG, (_T("%s\r\n"), _T(__FUNCTION__)));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -