支持多种输入方法主要包括三种方法:轮询、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;
}
stdin.c
#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);
}
encode_manger.c
#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;
}
ascii_demo.c
#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);
}
utf-16le.c
#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);
}
fonts_manager.c
#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);
}
gdk.c
#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);
}
freetype_demo.c
#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;
}
mian.c
#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占用率很高