1. 程式人生 > >使用IOCTL程式碼實現LCD背光調節

使用IOCTL程式碼實現LCD背光調節

國內這樣的程式碼找不到,於是參考了相關程式碼後完善如下程式碼,且實現方式通過IOCTL程式碼實現LCD背光調節的功能。

適合場合為平板電腦或者筆記本。主要還是要靠BIOS支援與否。

編譯環境使用:Dev-cpp工具編寫。

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <ddk/Ntddvdeo.h>

typedef struct _DISPLAY_BRIGHTNESS {
    UCHAR ucDisplayPolicy;
    UCHAR ucACBrightness;
    UCHAR ucDCBrightness;
} DISPLAY_BRIGHTNESS, *PDISPLAY_BRIGHTNESS;

#define IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS  CTL_CODE(FILE_DEVICE_VIDEO, 0x125, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS 	CTL_CODE(FILE_DEVICE_VIDEO, 0x126, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS 		CTL_CODE(FILE_DEVICE_VIDEO, 0x127, METHOD_BUFFERED, FILE_ANY_ACCESS)

void help(void)
{
	fprintf(stderr, "(c) Tody, 2014\n");
	fprintf(stderr, "Usage: wbl.exe -b <level>\n");
	fprintf(stderr, "  Option:\n");
	fprintf(stderr, "     -b <level>\t brightness level need to be specified\n");
	fprintf(stderr, "\n  Error code:\n");
	fprintf(stderr, "     Pass: 0;  Fail: 1\n");
	
	exit(1);
}

int setBrightness(int level)
{
	HANDLE h ;
	DWORD nOutBufferSize = 256;
	BYTE SupportedBrightness[256];
	DWORD g_supportedLevelCount; 
	DISPLAY_BRIGHTNESS DisplayBrightness;
	
	memset(SupportedBrightness, 0, sizeof(SupportedBrightness));
	
	/* use createfile function to open lcd.  
	* url from microsoft about IOCTL code.
	*  http://msdn.microsoft.com/en-us/library/windows/desktop/aa372703%28v=vs.85%29.aspx
	*/
	h = CreateFile("\\\\.\\LCD", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
	if(h == INVALID_HANDLE_VALUE){
		printf("Open \\\\.\\LCD error");
		exit(1);
	}

	/* Query for display supported level */
	if(!DeviceIoControl(h, IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS, NULL, 0, SupportedBrightness, nOutBufferSize, &g_supportedLevelCount, NULL)){
		printf("IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS error - %d, - buffer: %d ", g_supportedLevelCount, nOutBufferSize);
		exit(1);		
	}
	if (g_supportedLevelCount == 0)  	/* 0 means not supported */
	{
		printf("\nLCD not support LEVEL COUNT", g_supportedLevelCount);
		exit(1);
	}

	DisplayBrightness.ucDisplayPolicy = 0;
	DisplayBrightness.ucACBrightness = level;
	DisplayBrightness.ucDCBrightness = level;

	/* Set display backlight level */
	nOutBufferSize = sizeof(DisplayBrightness);
	if(!DeviceIoControl(h, IOCTL_VIDEO_SET_DISPLAY_BRIGHTNESS, (DISPLAY_BRIGHTNESS *)&DisplayBrightness, nOutBufferSize, NULL, 0, &nOutBufferSize, NULL)){
		printf("IOCTL_VIDEO_SET_SUPPORTED_BRIGHTNESS error - %d, - buffer: %d ", g_supportedLevelCount, nOutBufferSize);
		exit(1);		
	}
	
	Sleep(500); /* delay for some time while wmi event changed */
	nOutBufferSize = sizeof(DisplayBrightness);
	if(!DeviceIoControl(h, IOCTL_VIDEO_QUERY_DISPLAY_BRIGHTNESS, NULL, 0, (DISPLAY_BRIGHTNESS *)&DisplayBrightness, nOutBufferSize, &nOutBufferSize, NULL)){
		printf("IOCTL_VIDEO_QUERY_SUPPORTED_BRIGHTNESS error - %d, - buffer: %d ", g_supportedLevelCount, nOutBufferSize);
		exit(1);		
	}
	printf("\nBrightness_AC: %d\nBrightness_DC: %d", DisplayBrightness.ucACBrightness, DisplayBrightness.ucDCBrightness);		
}


int main(int argc, char *argv[]) {
	/* program with arguments support */
	if (argc == 3 && strcmp("-b", argv[1])==0){
		setBrightness(atoi(argv[2]));
	}else{
		help();
	}

	return 0;
}