支持多种输入方法主要包括三种方法:轮询、slcet、多线程,本节主要介绍轮询方法,这种方法特点是CPU占用率高
一、分析源码
input/input_manager.c
#include <config.h> #include <input_manager.h> #include <string.h> static PT_InputOpr g_ptInputOprHead; int RegisterInputOpr(PT_InputOpr ptInputOpr) { PT_InputOpr ptTmp; if (!g_ptInputOprHead) { g_ptInputOprHead = ptInputOpr; ptInputOpr->ptNext = NULL; } else { ptTmp = g_ptInputOprHead; while (ptTmp->ptNext) { ptTmp = ptTmp->ptNext; } ptTmp->ptNext = ptInputOpr; ptInputOpr->ptNext = NULL; } return 0; } void ShowInputOpr(void) { int i = 0; PT_InputOpr ptTmp = g_ptInputOprHead; while (ptTmp) { printf("%02d %s\n", i++, ptTmp->name); ptTmp = ptTmp->ptNext; } } int InputInit(void) { int iError; iError = StdinInit(); iError |= TouchScreenInit(); return iError; } /*在main函数中被调用*/ int AllInputDevicesInit(void) { PT_InputOpr ptTmp = g_ptInputOprHead; int iError = -1; while (ptTmp) { if (0 == ptTmp->InputDeviceInit()) { iError = 0; } ptTmp = ptTmp->ptNext; } return iError; } int GetInputEvent(PT_InputEvent ptInputEvent) { /*轮询查找输入事件,只要输入事件返回等于0,表明已经获取输入事件*/ PT_InputOpr ptTmp = g_ptInputOprHead; while (ptTmp) { if ( ptTmp->GetInputEvent(ptInputEvent)== 0) { return 0; } ptTmp = ptTmp->ptNext; } return -1; }
#include <input_manager.h> #include <termios.h> /*包含struct termios tTTYState;*/ #include <unistd.h> #include <stdio.h> #include <sys/time.h> #include <sys/types.h> static int StdinInputDeviceInit(void); static int StdioInputDeviceExit(void); static int StdinGetInputEvent(PT_InputEvent ptInputEvent); static T_InputOpr g_tStdinOpr = { .name = "stdin", .InputDeviceInit = StdinInputDeviceInit, .InputDeviceEXit = StdioInputDeviceExit, .GetInputEvent = StdinGetInputEvent, }; static int StdinInputDeviceInit(void) { struct termios tTTYState; //get the terminal state 获取终端状态 tcgetattr(STDIN_FILENO, &tTTYState); //turn off canonical mode 关闭canonical tTTYState.c_lflag &= ~ICANON; //minimum of number input read. tTTYState.c_cc[VMIN] = 1; /* 有一个数据时就立刻返回 */ //set the terminal attributes. tcsetattr(STDIN_FILENO, TCSANOW, &tTTYState); return 0; } static int StdioInputDeviceExit(void) { struct termios tTTYState; //get the terminal state tcgetattr(STDIN_FILENO, &tTTYState); //turn on canonical mode tTTYState.c_lflag |= ICANON; //set the terminal attributes. tcsetattr(STDIN_FILENO, TCSANOW, &tTTYState); return 0; } static int StdinGetInputEvent(PT_InputEvent ptInputEvent) { /* 如果有数据就读取、处理、返回 * 如果没有数据, 立刻返回-1, 不等待 */ /* select, poll 可以参数 UNIX环境高级编程 */ struct timeval tTV; fd_set tFDs; char c; tTV.tv_sec = 0; tTV.tv_usec = 0; FD_ZERO(&tFDs); FD_SET(STDIN_FILENO, &tFDs); //STDIN_FILENO is 0 select(STDIN_FILENO+1, &tFDs, NULL, NULL, &tTV); /*采用非阻塞*/ /*FD_ISSET(STDIN_FILENO, &tFDs) 判断是否设置设置,有数据了*/ if (FD_ISSET(STDIN_FILENO, &tFDs)) { /* 处理数据 */ ptInputEvent->iType = INPUT_TYPE_STDIN; /*记录当前事件时间*/ gettimeofday(&ptInputEvent->tTime, NULL); c = fgetc(stdin); if (c == ‘u‘) { ptInputEvent->iVal = INPUT_VALUE_UP; } else if (c == ‘n‘) { ptInputEvent->iVal = INPUT_VALUE_DOWN; } else if (c == ‘q‘) { ptInputEvent->iVal = INPUT_VALUE_EXIT; } else { ptInputEvent->iVal = INPUT_VALUE_UNKNOWN; } return 0; } else { return -1; } } int StdinInit(void) { return RegisterInputOpr(&g_tStdinOpr); }touchsreen.c
#include <config.h> #include <input_manager.h> #include <stdlib.h> #include <draw.h> /*调用int GetDispResolution(int *piXres, int *piYres);*/ #include <tslib.h> /* 参考tslib里的ts_print.c */ static struct tsdev *g_tTSDev; static int giXres; static int giYres; static int TouchScreenDevInit(void); static int TouchScreenDevExit(void); static int TouchScreenGetInputEvent(PT_InputEvent ptInputEvent); static T_InputOpr g_tTouchScreenOpr = { .name = "touchscreen", .InputDeviceInit = TouchScreenDevInit, .InputDeviceEXit = TouchScreenDevExit, .GetInputEvent = TouchScreenGetInputEvent, }; /* 注意: 由于要用到LCD的分辨率, 此函数要在SelectAndInitDisplay之后调用 */ static int TouchScreenDevInit(void) { char *pcTSName = NULL; if ((pcTSName = getenv("TSLIB_TSDEVICE")) != NULL ) { g_tTSDev = ts_open(pcTSName, 1); /*0:表示阻塞,1代表非阻塞*/ } else { g_tTSDev = ts_open("/dev/input/event0", 1); } if (!g_tTSDev) { DBG_PRINTF("ts_open error!\n"); return -1; } if (ts_config(g_tTSDev)) { DBG_PRINTF("ts_config error!\n"); return -1; } if (GetDispResolution(&giXres, &giYres)) { return -1; } return 0; } static int TouchScreenDevExit(void) { return 0; } static int isOutOf500ms(struct timeval *ptPreTime, struct timeval *ptNowTime) { int iPreMs; int iNowMs; iPreMs = ptPreTime->tv_sec * 1000 + ptPreTime->tv_usec / 1000; iNowMs = ptNowTime->tv_sec * 1000 + ptNowTime->tv_usec / 1000; /*如果iNowMs大于iPreMs,返回1*/ return (iNowMs > iPreMs + 500); } static int TouchScreenGetInputEvent(PT_InputEvent ptInputEvent) { struct ts_sample tSamp; int iRet; static struct timeval tPreTime; /*记录上一次按下的时间值*/ iRet = ts_read(g_tTSDev, &tSamp, 1); if (iRet < 0) { return -1; } /* 处理数据 */ if (isOutOf500ms(&tPreTime, &(tSamp.tv))) /*tSamp.tv 表示记录当前值 ,500毫秒处理一次*/ { /* 如果此次触摸事件发生的时间, 距上次事件超过了500ms */ tPreTime = tSamp.tv; /* 保存此次的时间值,用于下次比较*/ ptInputEvent->tTime = tSamp.tv; /*ptInputEvent 保存此次事件时间值*/ ptInputEvent->iType = INPUT_TYPE_TOUCHSCREEN; /*LCD 坐标系*/ if (tSamp.y < giYres/3) { ptInputEvent->iVal = INPUT_VALUE_UP; } else if (tSamp.y > 2*giYres/3) { ptInputEvent->iVal = INPUT_VALUE_DOWN; } else { ptInputEvent->iVal = INPUT_VALUE_UNKNOWN; } return 0; } else { return -1; } return 0; } int TouchScreenInit(void) { return RegisterInputOpr(&g_tTouchScreenOpr); }
#include <config.h> #include <encoding_manager.h> #include <string.h> #include <stdlib.h> static PT_EncodingOpr g_ptEncodingOprHead; //static T_EncodingOpr *g_ptEncodingOprHead; int RegisterEncodingOpr(PT_EncodingOpr ptEncodingOpr) { PT_EncodingOpr ptTmp; if (!g_ptEncodingOprHead) { g_ptEncodingOprHead = ptEncodingOpr; ptEncodingOpr->ptNext = NULL; } else { ptTmp = g_ptEncodingOprHead; while (ptTmp->ptNext) { ptTmp = ptTmp->ptNext; } ptTmp->ptNext = ptEncodingOpr; ptEncodingOpr->ptNext = NULL; } return 0; } void ShowEncodingOpr(void) { int i = 0; PT_EncodingOpr ptTmp = g_ptEncodingOprHead; while (ptTmp) { printf("%02d %s\n", i++, ptTmp->name); ptTmp = ptTmp->ptNext; } } PT_EncodingOpr SelectEncodingOprForFile(unsigned char *pucFileBufHead) { PT_EncodingOpr ptTmp = g_ptEncodingOprHead; while (ptTmp) { if (ptTmp->isSupport(pucFileBufHead)) return ptTmp; else ptTmp = ptTmp->ptNext; } return NULL; } int AddFontOprForEncoding(PT_EncodingOpr ptEncodingOpr, PT_FontOpr ptFontOpr) { PT_FontOpr ptFontOprCpy; if (!ptEncodingOpr || !ptFontOpr) { return -1; } else { ptFontOprCpy = malloc(sizeof(T_FontOpr)); if (!ptFontOprCpy) { return -1; } else { memcpy(ptFontOprCpy, ptFontOpr, sizeof(T_FontOpr)); ptFontOprCpy->ptNext = ptEncodingOpr->ptFontOprSupportedHead; ptEncodingOpr->ptFontOprSupportedHead = ptFontOprCpy; return 0; } } } int DelFontOprFrmEncoding(PT_EncodingOpr ptEncodingOpr, PT_FontOpr ptFontOpr) { PT_FontOpr ptTmp; PT_FontOpr ptPre; if (!ptEncodingOpr || !ptFontOpr) { return -1; } else { ptTmp = ptEncodingOpr->ptFontOprSupportedHead; if (strcmp(ptTmp->name, ptFontOpr->name) == 0) { /* 删除头节点 */ ptEncodingOpr->ptFontOprSupportedHead = ptTmp->ptNext; free(ptTmp); return 0; } ptPre = ptEncodingOpr->ptFontOprSupportedHead; ptTmp = ptPre->ptNext; while (ptTmp) { if (strcmp(ptTmp->name, ptFontOpr->name) == 0) { /* 从链表里取出、释放 */ ptPre->ptNext = ptTmp->ptNext; free(ptTmp); return 0; } else { ptPre = ptTmp; ptTmp = ptTmp->ptNext; } } return -1; } } int EncodingInit(void) { int iError; iError = AsciiEncodingInit(); if (iError) { DBG_PRINTF("AsciiEncodingInit error!\n"); return -1; } iError = Utf16leEncodingInit(); if (iError) { DBG_PRINTF("Utf16leEncodingInit error!\n"); return -1; } iError = Utf16beEncodingInit(); if (iError) { DBG_PRINTF("Utf16beEncodingInit error!\n"); return -1; } iError = Utf8EncodingInit(); if (iError) { DBG_PRINTF("Utf8EncodingInit error!\n"); return -1; } return 0; }
#include <config.h> #include <encoding_manager.h> #include <string.h> static int isAsciiCoding(unsigned char *pucBufHead); static int AsciiGetCodeFrmBuf(unsigned char *pucBufStart, unsigned char *pucBufEnd, unsigned int *pdwCode); #if 0 typedef struct EncodingOpr { char *name; int iHeadLen; PT_FontOpr ptFontOprSupportedHead; int (*isSupport)(unsigned char *pucBufHead); int (*GetCodeFrmBuf)(unsigned char *pucBufStart, unsigned char *pucBufEnd, unsigned int *pdwCode); struct EncodingOpr *ptNext; }T_EncodingOpr, *PT_EncodingOpr; #endif static T_EncodingOpr g_tAsciiEncodingOpr = { .name = "ascii", .iHeadLen = 0, .isSupport = isAsciiCoding, .GetCodeFrmBuf = AsciiGetCodeFrmBuf, }; /* *功能描述:判断缓冲区的编码方式是否为ANSI编码英文字母用ASCII,汉字用GBK *返回值0 代表 不是 * 1 代表是 */ static int isAsciiCoding(unsigned char *pucBufHead) { const char aStrUtf8[] = {0xEF, 0xBB, 0xBF, 0}; const char aStrUtf16le[] = {0xFF, 0xFE, 0}; const char aStrUtf16be[] = {0xFE, 0xFF, 0}; if(strncmp((const char*)pucBufHead, aStrUtf8, 3) ==0) { return 0; } else if(strncmp((const char*)pucBufHead, aStrUtf16le, 2) ==0) { return 0; } else if(strncmp((const char*)pucBufHead, aStrUtf16be, 2) ==0) { return 0; } else { return 1; } } /* *功能描述: 从缓冲区取出1个字符的ANSI的编码值 *输入参数: pucBufStart 缓冲区起始地址 * pucBufEnd 缓冲区结束地址 *输出参数: pdwCode 取出处理后的编码值 * 返回值 : 0 表示 处理完毕,没有得到编码值 * 其他值 表示从pucBufStat开始头信息字符的个数 */ static int AsciiGetCodeFrmBuf(unsigned char *pucBufStart, unsigned char *pucBufEnd, unsigned int *pdwCode) { unsigned char *pucBuf = pucBufStart; unsigned char c = *pucBuf; if((pucBuf < pucBufEnd) && ( c < (unsigned char )0x80)) { /*返回ASCII 值*/ *pdwCode = (unsigned int)c; return 1; } if(((pucBuf + 1) < pucBufEnd) && (c >= (unsigned char)0x80)) { /*返回GBK 码*/ *pdwCode = (unsigned int)((pucBuf[1]<<8) + pucBuf[0] ); return 2; } if(pucBuf < pucBufEnd) { *pdwCode = (unsigned int)c; return 1; } else { return 0; } } int AsciiEncodingInit(void) { AddFontOprForEncoding(&g_tAsciiEncodingOpr, GetFontOpr("freetype")); AddFontOprForEncoding(&g_tAsciiEncodingOpr, GetFontOpr("ascii")); AddFontOprForEncoding(&g_tAsciiEncodingOpr, GetFontOpr("gbk")); return RegisterEncodingOpr(&g_tAsciiEncodingOpr); }utf8.c
#include <config.h> #include <encoding_manager.h> #include <string.h> static int isUtf8Coding(unsigned char *pucBufHead); static int Utf8GetCodeFrmBuf(unsigned char *pucBufStart, unsigned char *pucBufEnd, unsigned int *pdwCode); static T_EncodingOpr g_tUtf8EncodingOpr = { .name = "utf-8", .iHeadLen = 3, .isSupport = isUtf8Coding, .GetCodeFrmBuf = Utf8GetCodeFrmBuf, }; static int isUtf8Coding(unsigned char *pucBufHead) { const char aStrUtf8[] = {0xEF, 0xBB, 0xBF, 0}; if (strncmp((const char*)pucBufHead, aStrUtf8, 3) == 0) { /* UTF-8 */ return 1; } else { return 0; } } /* 获得前导为1的位的个数 * 比如二进制数 11001111 的前导1有2位 * 11100001 的前导1有3位 */ static int GetPreOneBits(unsigned char ucVal) { int i; int j = 0; for (i = 7; i >= 0; i--) { if (!(ucVal & (1<<i))) break; else j++; } return j; } /* 返回值: 0 - 文件结束 * 正值 - buffer里用几个字节来表示当前的"字"(编码) * */ static int Utf8GetCodeFrmBuf(unsigned char *pucBufStart, unsigned char *pucBufEnd, unsigned int *pdwCode) { #if 0 对于UTF-8编码中的任意字节B,如果B的第一位为0,则B为ASCII码,并且B独立的表示一个字符; 如果B的第一位为1,第二位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的一个字节,并且不为字符的第一个字节编码; 如果B的前两位为1,第三位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的第一个字节,并且该字符由两个字节表示; 如果B的前三位为1,第四位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的第一个字节,并且该字符由三个字节表示; 如果B的前四位为1,第五位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的第一个字节,并且该字符由四个字节表示; 因此,对UTF-8编码中的任意字节,根据第一位,可判断是否为ASCII字符; 根据前二位,可判断该字节是否为一个字符编码的第一个字节; 根据前四位(如果前两位均为1),可确定该字节为字符编码的第一个字节,并且可判断对应的字符由几个字节表示; 根据前五位(如果前四位为1),可判断编码是否有错误或数据传输过程中是否有错误。 #endif int i; int iNum; unsigned char ucVal; unsigned int dwSum = 0; if (pucBufStart >= pucBufEnd) { /* 文件结束 */ return 0; } ucVal = pucBufStart[0]; iNum = GetPreOneBits(pucBufStart[0]); if ((pucBufStart + iNum) > pucBufEnd) { /* 文件结束 */ return 0; } if (iNum == 0) { /* ASCII */ *pdwCode = pucBufStart[0]; return 1; } else { ucVal = ucVal << iNum; ucVal = ucVal >> iNum; dwSum += ucVal; for (i = 1; i < iNum; i++) { ucVal = pucBufStart[i] & 0x3f; dwSum = dwSum << 6; dwSum += ucVal; } *pdwCode = dwSum; return iNum; } } int Utf8EncodingInit(void) { AddFontOprForEncoding(&g_tUtf8EncodingOpr, GetFontOpr("freetype")); AddFontOprForEncoding(&g_tUtf8EncodingOpr, GetFontOpr("ascii")); return RegisterEncodingOpr(&g_tUtf8EncodingOpr); }
#include <config.h> #include <encoding_manager.h> #include <string.h> static int isUtf16leCoding(unsigned char *pucBufHead); static int Utf16leGetCodeFrmBuf(unsigned char *pucBufStart, unsigned char *pucBufEnd, unsigned int *pdwCode); static T_EncodingOpr g_tUtf16leEncodingOpr = { .name = "utf-16le", .iHeadLen = 2, .isSupport = isUtf16leCoding, .GetCodeFrmBuf = Utf16leGetCodeFrmBuf, }; static int isUtf16leCoding(unsigned char *pucBufHead) { const char aStrUtf16le[] = {0xFF, 0xFE, 0}; if (strncmp((const char *)pucBufHead, aStrUtf16le, 2) == 0) { /* UTF-16 little endian */ return 1; } else { return 0; } } static int Utf16leGetCodeFrmBuf(unsigned char *pucBufStart, unsigned char *pucBufEnd, unsigned int *pdwCode) { if (pucBufStart + 1 < pucBufEnd) { *pdwCode = (((unsigned int)pucBufStart[1])<<8) + pucBufStart[0]; return 2; } else { /* 文件结束 */ return 0; } } int Utf16leEncodingInit(void) { AddFontOprForEncoding(&g_tUtf16leEncodingOpr, GetFontOpr("freetype")); AddFontOprForEncoding(&g_tUtf16leEncodingOpr, GetFontOpr("ascii")); return RegisterEncodingOpr(&g_tUtf16leEncodingOpr); }utf-16be.c
#include <config.h> #include <encoding_manager.h> #include <string.h> static int isUtf16beCoding(unsigned char *pucBufHead); static int Utf16beGetCodeFrmBuf(unsigned char *pucBufStart, unsigned char *pucBufEnd, unsigned int *pdwCode); static T_EncodingOpr g_tUtf16beEncodingOpr = { .name = "utf-16be", .iHeadLen = 2, .isSupport = isUtf16beCoding, .GetCodeFrmBuf = Utf16beGetCodeFrmBuf, }; static int isUtf16beCoding(unsigned char *pucBufHead) { const char aStrUtf16be[] = {0xFE, 0xFF, 0}; if (strncmp((const char*)pucBufHead, aStrUtf16be, 2) == 0) { /* UTF-16 big endian */ return 1; } else { return 0; } } static int Utf16beGetCodeFrmBuf(unsigned char *pucBufStart, unsigned char *pucBufEnd, unsigned int *pdwCode) { if (pucBufStart + 1 < pucBufEnd) { *pdwCode = (((unsigned int)pucBufStart[0])<<8) + pucBufStart[1]; return 2; } else { /* 文件结束 */ return 0; } } int Utf16beEncodingInit(void) { AddFontOprForEncoding(&g_tUtf16beEncodingOpr, GetFontOpr("freetype")); AddFontOprForEncoding(&g_tUtf16beEncodingOpr, GetFontOpr("ascii")); return RegisterEncodingOpr(&g_tUtf16beEncodingOpr); }
#include <config.h> #include <fonts_manager.h> #include <string.h> static PT_FontOpr g_ptFontOprHead = NULL; int RegisterFontOpr(PT_FontOpr ptFontOpr) { PT_FontOpr ptTmp; if (!g_ptFontOprHead) { g_ptFontOprHead = ptFontOpr; ptFontOpr->ptNext = NULL; } else { ptTmp = g_ptFontOprHead; while (ptTmp->ptNext) { ptTmp = ptTmp->ptNext; } ptTmp->ptNext = ptFontOpr; ptFontOpr->ptNext = NULL; } return 0; } void ShowFontOpr(void) { int i = 0; PT_FontOpr ptTmp = g_ptFontOprHead; while (ptTmp) { printf("%02d %s\n", i++, ptTmp->name); ptTmp = ptTmp->ptNext; } } PT_FontOpr GetFontOpr(char *pcName) { PT_FontOpr ptTmp = g_ptFontOprHead; while (ptTmp) { if (strcmp(ptTmp->name, pcName) == 0) { return ptTmp; } ptTmp = ptTmp->ptNext; } return NULL; } int FontsInit(void) { int iError; iError = ASCIIInit(); if (iError) { DBG_PRINTF("ASCIIInit error!\n"); return -1; } iError = GBKInit(); if (iError) { DBG_PRINTF("GBKInit error!\n"); return -1; } iError = FreeTypeInit(); if (iError) { DBG_PRINTF("FreeTypeInit error!\n"); return -1; } return 0; }ascii.c
#include <config.h> #include <fonts_manager.h> #define FONTDATAMAX 4096 static int ASCIIFontInit(char *pcFontFile, unsigned int dwFontSize); static int ASCIIGetFontBitmap(unsigned int dwCode, PT_FontBitMap ptFontBitMap); static T_FontOpr g_tASCIIFontOpr = { .name = "ascii", .FontInit = ASCIIFontInit, .GetFontBitmap = ASCIIGetFontBitmap, }; static const unsigned char fontdata_8x16[FONTDATAMAX] = { .... }; static int ASCIIFontInit(char *pcFontFile, unsigned int dwFontSize) { if (dwFontSize != 16) { //DBG_PRINTF("ASCII can‘t support %d font size\n", dwFontSize); return -1; } return 0; } static int ASCIIGetFontBitmap(unsigned int dwCode, PT_FontBitMap ptFontBitMap) { int iPenX = ptFontBitMap->iCurOriginX; int iPenY = ptFontBitMap->iCurOriginY; if (dwCode > (unsigned int)0x80) { //DBG_PRINTF("don‘t support this code : 0x%x\n", dwCode); return -1; } ptFontBitMap->iXLeft = iPenX; ptFontBitMap->iYTop = iPenY - 16; ptFontBitMap->iXMax = iPenX + 8; ptFontBitMap->iYMax = iPenY; ptFontBitMap->iBpp = 1; ptFontBitMap->iPitch = 1; ptFontBitMap->pucBuffer = (unsigned char *)&fontdata_8x16[dwCode * 16];; ptFontBitMap->iNextOriginX = iPenX + 8; ptFontBitMap->iNextOriginY = iPenY; return 0; } int ASCIIInit(void) { return RegisterFontOpr(&g_tASCIIFontOpr); }
#include <config.h> #include <fonts_manager.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/mman.h> #include <unistd.h> static int GBKFontInit(char *pcFontFile, unsigned int dwFontSize); static int GBKGetFontBitmap(unsigned int dwCode, PT_FontBitMap ptFontBitMap); static T_FontOpr g_tGBKFontOpr = { .name = "gbk", .FontInit = GBKFontInit, .GetFontBitmap = GBKGetFontBitmap, }; static int g_iFdHZK; static unsigned char *g_pucHZKMem; static unsigned char *g_pucHZKMemEnd; static int GBKFontInit(char *pcFontFile, unsigned int dwFontSize) { struct stat tStat; if (16 != dwFontSize) { DBG_PRINTF("GBK can‘t support %d fontsize\n", dwFontSize); return -1; } g_iFdHZK = open(pcFontFile, O_RDONLY); if (g_iFdHZK < 0) { DBG_PRINTF("can‘t open %s\n", pcFontFile); return -1; } if(fstat(g_iFdHZK, &tStat)) { DBG_PRINTF("can‘t get fstat\n"); return -1; } g_pucHZKMem = (unsigned char *)mmap(NULL , tStat.st_size, PROT_READ, MAP_SHARED, g_iFdHZK, 0); if (g_pucHZKMem == (unsigned char *)-1) { DBG_PRINTF("can‘t mmap for hzk16\n"); return -1; } g_pucHZKMemEnd = g_pucHZKMem + tStat.st_size; return 0; } static int GBKGetFontBitmap(unsigned int dwCode, PT_FontBitMap ptFontBitMap) { int iArea; int iWhere; int iPenX = ptFontBitMap->iCurOriginX; int iPenY = ptFontBitMap->iCurOriginY; DBG_PRINTF("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__); if (dwCode & 0xffff0000) { DBG_PRINTF("don‘t support this code : 0x%x\n", dwCode); return -1; } iArea = (int)(dwCode & 0xff) - 0xA1; iWhere = (int)((dwCode >> 8) & 0xff) - 0xA1; if ((iArea < 0) || (iWhere < 0)) { DBG_PRINTF("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__); return -1; } ptFontBitMap->iXLeft = iPenX; ptFontBitMap->iYTop = iPenY - 16; ptFontBitMap->iXMax = iPenX + 16; ptFontBitMap->iYMax = iPenY; ptFontBitMap->iBpp = 1; ptFontBitMap->iPitch = 2; ptFontBitMap->pucBuffer = g_pucHZKMem + (iArea * 94 + iWhere)*32;; if (ptFontBitMap->pucBuffer >= g_pucHZKMemEnd) { return -1; } ptFontBitMap->iNextOriginX = iPenX + 16; ptFontBitMap->iNextOriginY = iPenY; DBG_PRINTF("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__); return 0; } int GBKInit(void) { return RegisterFontOpr(&g_tGBKFontOpr); }
#include <config.h> #include <fonts_manager.h> #include <ft2build.h> #include FT_FREETYPE_H #include FT_GLYPH_H static int FreeTypeFontInit(char * pcFontFile, unsigned int dwFontSize); static int FreeTypeGetFontBitmap(unsigned int dwCode, PT_FontBitMap ptFontBitMap); static FT_Library g_tLibrary; static FT_Face g_tFace; static FT_GlyphSlot g_tSlot; #if 0 typedef struct FontBitMap { int iXLeft; int iYTop; int iXMax; int iYMax; int iBpp; int iPitch; int iCurOriginX; int iCurOriginY; unsigned char *pucBuffer; }T_FontBitMap, *PT_FontBitMap; typedef struct FontOpr { char *name; int (*FontInit)(char *pcFontFile, unsigned int dwFontSize); int (*GetFontBitmap)(unsigned int dwCode, PT_FontBitMap ptFontBitMap); struct FontOpr *ptNext; }T_FontOpr, *PT_DispOpr; #endif static T_FontOpr g_tFreeTypeFontOpr = { .name = "freetype", .FontInit = FreeTypeFontInit, .GetFontBitmap = FreeTypeGetFontBitmap, }; static int FreeTypeFontInit(char * pcFontFile, unsigned int dwFontSize) { int iError; iError = FT_Init_FreeType( &g_tLibrary ); /* initialize library */ if(iError) { DBG_PRINTF("FT_Init_FreeType failed\n"); return -1; } iError = FT_New_Face( g_tLibrary,pcFontFile, 0, &g_tFace ); /* create face object */ if(iError) { DBG_PRINTF("FT_New_Face failed\n"); return -1; } g_tSlot = g_tFace->glyph; iError = FT_Set_Pixel_Sizes(g_tFace, dwFontSize, 0); if(iError) { DBG_PRINTF("FT_Set_Pixel_Sizes failed\n"); return -1; } return 0; } static int FreeTypeGetFontBitmap(unsigned int dwCode, PT_FontBitMap ptFontBitMap) { int iError; iError = FT_Load_Char(g_tFace, dwCode, FT_LOAD_RENDER | FT_LOAD_MONOCHROME ); if(iError) { DBG_PRINTF("FT_Load_Char failed\n"); return -1; } /*笛卡尔坐标到LCD 坐标转换*/ ptFontBitMap->iXLeft = ptFontBitMap->iCurOriginX + g_tSlot->bitmap_left; ptFontBitMap->iYTop = ptFontBitMap->iCurOriginY - g_tSlot->bitmap_top; ptFontBitMap->iXMax = ptFontBitMap->iXLeft + g_tSlot->bitmap.width; ptFontBitMap->iYMax = ptFontBitMap->iYTop + g_tSlot->bitmap.rows; /*一位表示一像素*/ ptFontBitMap->iBpp = 1; ptFontBitMap->iPitch = g_tSlot->bitmap.pitch; ptFontBitMap->iNextOriginX = ptFontBitMap->iCurOriginX + g_tSlot->advance.x/64; ptFontBitMap->iNextOriginY = ptFontBitMap->iCurOriginY; ptFontBitMap->pucBuffer = g_tSlot->bitmap.buffer; return 0; } int FreeTypeInit(void) { return RegisterFontOpr(&g_tFreeTypeFontOpr); }disp_manager.h
#include <config.h> #include <disp_manager.h> #include <string.h> static PT_DispOpr g_ptDispOprHead; int RegisterDispOpr(PT_DispOpr ptDispOpr) { PT_DispOpr ptTmp; if (!g_ptDispOprHead) { g_ptDispOprHead = ptDispOpr; ptDispOpr->ptNext = NULL; } else { ptTmp = g_ptDispOprHead; while (ptTmp->ptNext) { ptTmp = ptTmp->ptNext; } ptTmp->ptNext = ptDispOpr; ptDispOpr->ptNext = NULL; } return 0; } void ShowDispOpr(void) { int i = 0; PT_DispOpr ptTmp = g_ptDispOprHead; while (ptTmp) { printf("%02d %s\n", i++, ptTmp->name); ptTmp = ptTmp->ptNext; } } PT_DispOpr GetDispOpr(char *pcName) { PT_DispOpr ptTmp = g_ptDispOprHead; while (ptTmp) { if (strcmp(ptTmp->name, pcName) == 0) { return ptTmp; } ptTmp = ptTmp->ptNext; } return NULL; } int DisplayInit(void) { int iError; iError = FBInit(); return iError; }
#include <config.h> #include <disp_manager.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/ioctl.h> #include <sys/mman.h> #include <linux/fb.h> #include <string.h> /*构造、设置、注册结构体采用面向对象的思想*/ #if 0 typedef struct DispOpr { char* name; int iXres; int iYres; int iBpp; int (*ShowPixel)(int iPenX, int iPenY, unsigned int dwColor); int (*CleanScreen)(unsigned int dwBackColor); int (*DeviceInit)(void); struct DispOpr *ptNext; }T_DispOpr, *PT_DispOpr; int RegisterDispOpr(PT_DispOpr ptDispOpr); void ShowDispOpr(void); int DisplayInit(void); int FBInit(void); #endif static int FBDeviceInit(void); static int FBShowPixel(int iX, int iY, unsigned int dwColor); static int FBCleanScreen(unsigned int dwBackColor); static T_DispOpr g_tFBOpr = { .name = "fb", .DeviceInit = FBDeviceInit, .ShowPixel = FBShowPixel, .CleanScreen = FBCleanScreen, }; static int g_iFBFd; static struct fb_var_screeninfo g_tFBVar; static struct fb_fix_screeninfo g_tFBFix; static unsigned int g_dwScreenSize; static unsigned int g_dwLineWidth; static unsigned int g_dwPixelWidth; static unsigned char * g_pucFBMem; static int FBDeviceInit(void) { g_iFBFd = open(FB_DEVICE_NAME,O_RDWR); if(g_iFBFd < 0) { DBG_PRINTF("open /dev/fb0 failed\n"); return -1; } if (ioctl(g_iFBFd, FBIOGET_VSCREENINFO, &g_tFBVar)) { DBG_PRINTF("get var information failed\n"); return -1; } if (ioctl(g_iFBFd, FBIOGET_FSCREENINFO, &g_tFBFix)) { DBG_PRINTF("get fix information failed\n"); return -1; } g_tFBOpr.iXres = g_tFBVar.xres; g_tFBOpr.iYres = g_tFBVar.yres; g_tFBOpr.iBpp = g_tFBVar.bits_per_pixel; g_dwScreenSize = g_tFBVar.xres * g_tFBVar.yres * g_tFBVar.bits_per_pixel /8; g_dwLineWidth = g_tFBVar.xres * g_tFBVar.bits_per_pixel /8; g_dwPixelWidth = g_tFBVar.bits_per_pixel /8; g_pucFBMem = (unsigned char *)mmap(NULL , g_dwScreenSize, PROT_READ | PROT_WRITE, MAP_SHARED, g_iFBFd, 0); if(g_pucFBMem == (unsigned char *)-1) { DBG_PRINTF("g_pucFBMem mmap failed\n "); return -1; } return 0; } static int FBShowPixel(int iPenX, int iPenY, unsigned int dwColor) { unsigned char *pucFB8pp = (unsigned char*)(g_pucFBMem+iPenY*g_dwLineWidth+iPenX*g_dwPixelWidth); unsigned short *pwFB16pp; unsigned int *pdwFB32pp; pwFB16pp = (unsigned short*)pucFB8pp; pdwFB32pp = (unsigned int*)pucFB8pp; unsigned char red,green,blue; /*0xRRGGBB*/ switch( g_tFBVar.bits_per_pixel) { case 8: *pucFB8pp = dwColor; break; case 16: red = (dwColor >>16)&0xff; green = (dwColor>>8)&0xff; blue = (dwColor>>0)&0xff; dwColor = ((red>>3)<<11)|((green>>2)<<5)|((blue>>3)<<0); *pwFB16pp = dwColor; break; case 32: *pdwFB32pp = dwColor; break; default: DBG_PRINTF("Can‘ support error\n"); return -1; } return 0; } static int FBCleanScreen(unsigned int dwBackColor) { unsigned char *pucFB8pp = (unsigned char*)(g_pucFBMem); unsigned short *pwFB16pp; unsigned int *pdwFB32pp; pwFB16pp = (unsigned short*)pucFB8pp; pdwFB32pp = (unsigned int*)pucFB8pp; unsigned char red,green,blue; int i = 0; /*0xRRGGBB*/ switch(g_tFBVar.bits_per_pixel) { case 8: memset(g_pucFBMem, dwBackColor, g_dwScreenSize); break; case 16: red = (dwBackColor >>16)&0xff; green = (dwBackColor>>8)&0xff; blue = (dwBackColor>>0)&0xff; dwBackColor = ((red>>3)<<11)|((green>>2)<<5)|((blue>>3)<<0); while(i < g_dwScreenSize) { *pwFB16pp = dwBackColor; pwFB16pp++; i +=2; } break; case 32: while(i < g_dwScreenSize) { *pdwFB32pp = dwBackColor; pdwFB32pp++; i += 4; } break; default: DBG_PRINTF("Can‘ support %d bpp\n",g_tFBDispOpr.iBpp); return -1; } return 0; } int FBInit(void) { return RegisterDispOpr(&g_tFBOpr); }
#include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <sys/mman.h> #include <fcntl.h> #include <config.h> #include <draw.h> #include <encoding_manager.h> #include <fonts_manager.h> #include <disp_manager.h> #include <string.h> typedef struct PageDesc { int iPage; unsigned char *pucLcdFirstPosAtFile; unsigned char *pucLcdNextPageFirstPosAtFile; struct PageDesc *ptPrePage; struct PageDesc *ptNextPage; } T_PageDesc, *PT_PageDesc; static int g_iFdTextFile; static unsigned char *g_pucTextFileMem; static unsigned char *g_pucTextFileMemEnd; static PT_EncodingOpr g_ptEncodingOprForFile; static PT_DispOpr g_ptDispOpr; static unsigned char *g_pucLcdFirstPosAtFile; static unsigned char *g_pucLcdNextPosAtFile; static int g_dwFontSize; static PT_PageDesc g_ptPages = NULL; static PT_PageDesc g_ptCurPage = NULL; int OpenTextFile(char *pcFileName) { struct stat tStat; g_iFdTextFile = open(pcFileName, O_RDONLY); if (0 > g_iFdTextFile) { DBG_PRINTF("can‘t open text file %s\n", pcFileName); return -1; } if(fstat(g_iFdTextFile, &tStat)) { DBG_PRINTF("can‘t get fstat\n"); return -1; } g_pucTextFileMem = (unsigned char *)mmap(NULL , tStat.st_size, PROT_READ, MAP_SHARED, g_iFdTextFile, 0); if (g_pucTextFileMem == (unsigned char *)-1) { DBG_PRINTF("can‘t mmap for text file\n"); return -1; } /* 自注释 */ g_pucTextFileMemEnd = g_pucTextFileMem + tStat.st_size; g_ptEncodingOprForFile = SelectEncodingOprForFile(g_pucTextFileMem); if (g_ptEncodingOprForFile) { g_pucLcdFirstPosAtFile = g_pucTextFileMem + g_ptEncodingOprForFile->iHeadLen; return 0; } else { return -1; } } int SetFontsDetail(char *pcHZKFile, char *pcFileFreetype, unsigned int dwFontSize) { int iError = 0; PT_FontOpr ptFontOpr; PT_FontOpr ptTmp; int iRet = -1; g_dwFontSize = dwFontSize; ptFontOpr = g_ptEncodingOprForFile->ptFontOprSupportedHead; while (ptFontOpr) { if (strcmp(ptFontOpr->name, "ascii") == 0) { iError = ptFontOpr->FontInit(NULL, dwFontSize); } else if (strcmp(ptFontOpr->name, "gbk") == 0) { iError = ptFontOpr->FontInit(pcHZKFile, dwFontSize); } else { iError = ptFontOpr->FontInit(pcFileFreetype, dwFontSize); } DBG_PRINTF("%s, %d\n", ptFontOpr->name, iError); ptTmp = ptFontOpr->ptNext; if (iError == 0) { /* 比如对于ascii编码的文件, 可能用ascii字体也可能用gbk字体, * 所以只要有一个FontInit成功, SetTextDetail最终就返回成功 */ iRet = 0; } else { DelFontOprFrmEncoding(g_ptEncodingOprForFile, ptFontOpr); } ptFontOpr = ptTmp; } return iRet; } int SelectAndInitDisplay(char *pcName) { int iError; g_ptDispOpr = GetDispOpr(pcName);/*获取显示设备*/ if (!g_ptDispOpr) { return -1; } iError = g_ptDispOpr->DeviceInit(); /*显示设备初始化*/ return iError; } /*由于用到LCD 的分辨率,所有要在SelectAndInitDisplay 之后作用*/ int GetDispResolution(int *piXres, int *piYres) { if (g_ptDispOpr) { *piXres = g_ptDispOpr->iXres; *piYres = g_ptDispOpr->iYres; return 0; } else { return -1; } } int IncLcdX(int iX) { if (iX + 1 < g_ptDispOpr->iXres) return (iX + 1); else return 0; } int IncLcdY(int iY) { if (iY + g_dwFontSize < g_ptDispOpr->iYres) return (iY + g_dwFontSize); else return 0; } int RelocateFontPos(PT_FontBitMap ptFontBitMap) { int iLcdY; int iDeltaX; int iDeltaY; if (ptFontBitMap->iYMax > g_ptDispOpr->iYres) { /* 满页了 */ return -1; } /* 超过LCD最右边 */ if (ptFontBitMap->iXMax > g_ptDispOpr->iXres) { /* 换行 */ iLcdY = IncLcdY(ptFontBitMap->iCurOriginY); if (0 == iLcdY) { /* 满页了 */ return -1; } else { /* 没满页 */ iDeltaX = 0 - ptFontBitMap->iCurOriginX; iDeltaY = iLcdY - ptFontBitMap->iCurOriginY; ptFontBitMap->iCurOriginX += iDeltaX; ptFontBitMap->iCurOriginY += iDeltaY; ptFontBitMap->iNextOriginX += iDeltaX; ptFontBitMap->iNextOriginY += iDeltaY; ptFontBitMap->iXLeft += iDeltaX; ptFontBitMap->iXMax += iDeltaX; ptFontBitMap->iYTop += iDeltaY; ptFontBitMap->iYMax += iDeltaY;; return 0; } } return 0; } int ShowOneFont(PT_FontBitMap ptFontBitMap) { int x; int y; unsigned char ucByte = 0; int i = 0; int bit; if (ptFontBitMap->iBpp == 1) { for (y = ptFontBitMap->iYTop; y < ptFontBitMap->iYMax; y++) { i = (y - ptFontBitMap->iYTop) * ptFontBitMap->iPitch; for (x = ptFontBitMap->iXLeft, bit = 7; x < ptFontBitMap->iXMax; x++) { if (bit == 7) { ucByte = ptFontBitMap->pucBuffer[i++]; } if (ucByte & (1<<bit)) { g_ptDispOpr->ShowPixel(x, y, COLOR_FOREGROUND); } else { /* 使用背景色, 不用描画 */ // g_ptDispOpr->ShowPixel(x, y, 0); /* 黑 */ } bit--; if (bit == -1) { bit = 7; } } } } else if (ptFontBitMap->iBpp == 8) { for (y = ptFontBitMap->iYTop; y < ptFontBitMap->iYMax; y++) for (x = ptFontBitMap->iXLeft; x < ptFontBitMap->iXMax; x++) { //g_ptDispOpr->ShowPixel(x, y, ptFontBitMap->pucBuffer[i++]); if (ptFontBitMap->pucBuffer[i++]) g_ptDispOpr->ShowPixel(x, y, COLOR_FOREGROUND); } } else { DBG_PRINTF("ShowOneFont error, can‘t support %d bpp\n", ptFontBitMap->iBpp); return -1; } return 0; } int ShowOnePage(unsigned char *pucTextFileMemCurPos) { int iLen; int iError; unsigned char *pucBufStart; unsigned int dwCode; PT_FontOpr ptFontOpr; T_FontBitMap tFontBitMap; int bHasNotClrSceen = 1; int bHasGetCode = 0; tFontBitMap.iCurOriginX = 0; tFontBitMap.iCurOriginY = g_dwFontSize; pucBufStart = pucTextFileMemCurPos; while (1) { iLen = g_ptEncodingOprForFile->GetCodeFrmBuf(pucBufStart, g_pucTextFileMemEnd, &dwCode); if (0 == iLen) { /* 文件结束 */ if (!bHasGetCode) { return -1; } else { return 0; } } bHasGetCode = 1; pucBufStart += iLen; /* 有些文本, \n\r两个一起才表示回车换行 * 碰到这种连续的\n\r, 只处理一次 */ if (dwCode == ‘\n‘) { g_pucLcdNextPosAtFile = pucBufStart; /* 回车换行 */ tFontBitMap.iCurOriginX = 0; tFontBitMap.iCurOriginY = IncLcdY(tFontBitMap.iCurOriginY); if (0 == tFontBitMap.iCurOriginY) { /* 显示完当前一屏了 */ return 0; } else { continue; } } else if (dwCode == ‘\r‘) { continue; } else if (dwCode == ‘\t‘) { /* TAB键用一个空格代替 */ dwCode = ‘ ‘; } DBG_PRINTF("dwCode = 0x%x\n", dwCode); ptFontOpr = g_ptEncodingOprForFile->ptFontOprSupportedHead; while (ptFontOpr) { DBG_PRINTF("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__); iError = ptFontOpr->GetFontBitmap(dwCode, &tFontBitMap); DBG_PRINTF("%s %s %d, ptFontOpr->name = %s, %d\n", __FILE__, __FUNCTION__, __LINE__, ptFontOpr->name, iError); if (0 == iError) { DBG_PRINTF("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__); if (RelocateFontPos(&tFontBitMap)) { /* 剩下的LCD空间不能满足显示这个字符 */ return 0; } DBG_PRINTF("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__); if (bHasNotClrSceen) { /* 首先清屏 */ g_ptDispOpr->CleanScreen(COLOR_BACKGROUND); bHasNotClrSceen = 0; } DBG_PRINTF("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__); /* 显示一个字符 */ if (ShowOneFont(&tFontBitMap)) { return -1; } tFontBitMap.iCurOriginX = tFontBitMap.iNextOriginX; tFontBitMap.iCurOriginY = tFontBitMap.iNextOriginY; g_pucLcdNextPosAtFile = pucBufStart; /* 继续取出下一个编码来显示 */ break; } ptFontOpr = ptFontOpr->ptNext; } } return 0; } static void RecordPage(PT_PageDesc ptPageNew) { PT_PageDesc ptPage; if (!g_ptPages) { g_ptPages = ptPageNew; } else { ptPage = g_ptPages; while (ptPage->ptNextPage) { ptPage = ptPage->ptNextPage; } ptPage->ptNextPage = ptPageNew; ptPageNew->ptPrePage = ptPage; } } int ShowNextPage(void) { int iError; PT_PageDesc ptPage; unsigned char *pucTextFileMemCurPos; if (g_ptCurPage) { pucTextFileMemCurPos = g_ptCurPage->pucLcdNextPageFirstPosAtFile; } else { pucTextFileMemCurPos = g_pucLcdFirstPosAtFile; } iError = ShowOnePage(pucTextFileMemCurPos); DBG_PRINTF("%s %d, %d\n", __FUNCTION__, __LINE__, iError); if (iError == 0) { if (g_ptCurPage && g_ptCurPage->ptNextPage) { g_ptCurPage = g_ptCurPage->ptNextPage; return 0; } ptPage = malloc(sizeof(T_PageDesc)); if (ptPage) { ptPage->pucLcdFirstPosAtFile = pucTextFileMemCurPos; ptPage->pucLcdNextPageFirstPosAtFile = g_pucLcdNextPosAtFile; ptPage->ptPrePage = NULL; ptPage->ptNextPage = NULL; g_ptCurPage = ptPage; DBG_PRINTF("%s %d, pos = 0x%x\n", __FUNCTION__, __LINE__, (unsigned int)ptPage->pucLcdFirstPosAtFile); RecordPage(ptPage); return 0; } else { return -1; } } return iError; } int ShowPrePage(void) { int iError; DBG_PRINTF("%s %d\n", __FUNCTION__, __LINE__); if (!g_ptCurPage || !g_ptCurPage->ptPrePage) { return -1; } DBG_PRINTF("%s %d, pos = 0x%x\n", __FUNCTION__, __LINE__, (unsigned int)g_ptCurPage->ptPrePage->pucLcdFirstPosAtFile); iError = ShowOnePage(g_ptCurPage->ptPrePage->pucLcdFirstPosAtFile); if (iError == 0) { DBG_PRINTF("%s %d\n", __FUNCTION__, __LINE__); g_ptCurPage = g_ptCurPage->ptPrePage; } return iError; } int DrawInit(void) { int iError; iError = DisplayInit(); if (iError) { printf("DisplayInit error!\n"); return -1; } iError = FontsInit(); if (iError) { printf("FontsInit error!\n"); return -1; } iError = EncodingInit(); if (iError) { printf("EncodingInit error!\n"); return -1; } iError = InputInit(); if (iError) { printf("InputInit error!\n"); return -1; } return 0; }
#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <config.h> #include <draw.h> #include <encoding_manager.h> #include <fonts_manager.h> #include <disp_manager.h> #include <input_manager.h> #include <string.h> /* ./show_file [-s Size] [-f freetype_font_file] [-h HZK] <text_file> */ int main(int argc, char **argv) { int iError; unsigned int dwFontSize = 16; char acHzkFile[128]; char acFreetypeFile[128]; char acTextFile[128]; char acDisplay[128]; char cOpr; int bList = 0; T_InputEvent tInputEvent; acHzkFile[0] = ‘\0‘; acFreetypeFile[0] = ‘\0‘; acTextFile[0] = ‘\0‘; strcpy(acDisplay, "fb"); while ((iError = getopt(argc, argv, "ls:f:h:d:")) != -1) { /* 选项 : ./show_file -l */ switch(iError) { case ‘l‘: { bList = 1; break; } case ‘s‘: { dwFontSize = strtoul(optarg, NULL, 0); break; } case ‘f‘: { strncpy(acFreetypeFile, optarg, 128); acFreetypeFile[127] = ‘\0‘; break; } case ‘h‘: { strncpy(acHzkFile, optarg, 128); acHzkFile[127] = ‘\0‘; break; } case ‘d‘: { strncpy(acDisplay, optarg, 128); acDisplay[127] = ‘\0‘; break; } default: { printf("Usage: %s [-s Size] [-d display] [-f font_file] [-h HZK] <text_file>\n", argv[0]); printf("Usage: %s -l\n", argv[0]); return -1; break; } } } if (!bList && (optind >= argc)) { printf("Usage: %s [-s Size] [-d display] [-f font_file] [-h HZK] <text_file>\n", argv[0]); printf("Usage: %s -l\n", argv[0]); return -1; } /*DrawInit 函 数实现DisplayInit 、FontsInit、EncodingInit、InputInit*/ iError = DrawInit(); if (iError) { printf("DrawInit error!\n"); return -1; } /* 列出所支持的各项function*/ if (bList) { printf("supported display:\n"); ShowDispOpr(); printf("supported font:\n"); ShowFontOpr(); printf("supported encoding:\n"); ShowEncodingOpr(); printf("supported encoding:\n"); ShowInputOpr(); return 0; } strncpy(acTextFile, argv[optind], 128); acTextFile[127] = ‘\0‘; /*打开文件*/ iError = OpenTextFile(acTextFile); if (iError) { printf("OpenTextFile error!\n"); return -1; } /*设置文本*/ iError = SetFontsDetail(acHzkFile, acFreetypeFile, dwFontSize); if (iError) { printf("SetFontsDetail error!\n"); return -1; } DBG_PRINTF("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__); /* 显示fb初始化*/ iError = SelectAndInitDisplay(acDisplay); if (iError) { printf("SelectAndInitDisplay error!\n"); return -1; } /*输入设备初始化*/ iError = AllInputDevicesInit(); if (iError) { printf("AllInputDevicesInit error!\n"); return -1; } DBG_PRINTF("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__); iError = ShowNextPage(); DBG_PRINTF("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__); if (iError) { printf("Error to show first page\n"); return -1; } while (1) { #if 0 printf("Enter ‘n‘ to show next page, ‘u‘ to show previous page, ‘q‘ to exit: "); do { cOpr = getchar(); } while ((cOpr != ‘n‘) && (cOpr != ‘u‘) && (cOpr != ‘q‘)); if (cOpr == ‘n‘) { ShowNextPage(); } else if (cOpr == ‘u‘) { ShowPrePage(); } else { return 0; } #endif /*使用轮询的方式*/ if (0 == GetInputEvent(&tInputEvent)) { if(tInputEvent.iVal == INPUT_VALUE_DOWN) ShowNextPage(); if(tInputEvent.iVal == INPUT_VALUE_UP) ShowPrePage(); if(tInputEvent.iVal == INPUT_VALUE_EXIT) return 0; } } return 0; }二、实验测试
1 、实验方法:
a. insmod s3c_ts.ko
确定是哪个设备节点对应触摸屏
b.
export TSLIB_TSDEVICE=/dev/event0
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_PLUGINDIR=/lib/ts
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0
c. 较准
ts_calibrate
d. telnetd -l /bin/sh //启动telnet服务,为了登录进去观察CPU占用率
e. ./show_file -s 20 -f ./FZYTK.TTF ./utf8.txt
f. telnet上开发板执行top命令观察
结果如图所示:
说明,采用此种方法,CPU占用率很高
原文:http://blog.csdn.net/dream890527/article/details/21292503