软件整体框架
主要考虑触摸屏输入与网络输入,主要由一个头文件、三个源文件与一个包含main函数的可执行文件组成,以下是一些主要功能介绍。
input_manager.h
typedef struct InputDevice{
char *name;
int (*GetInputEvent)(PInputEvent ptInputEvent);
int (*DeviceInit)(void);
int (*DeviceExit)(void);
struct InputDevice *ptNext;
}InputDevice,*PInputDevice;
typedef struct InputEvent{
struct timeval tTime;
int iType;
int iXPos;
int iYPos;
int iPre;
char str[1024];
}InputEvent,*PInputEvent;
将输入设备与输入事件抽象为具有共性的两个结构体,对于InputDevice结构体使用了函数指针,定义了指向什么类型的函数,这样写对于不同的输入设备的.c文件,可以实现不同的底层功能,与C++中的类相似。InputEvent是存储输入事件信息的结构体,使两种输入设备可以共用一种统一的结构体。
touchscreen.c
//定义并初始化触摸屏结构体
static InputDevice g_tTouchscreenDev = {
.name = "touchscreen",
.GetInputEvent = TouchscreenGetInputEvent,
.DeviceInit = TouchscreenDeviceInit,
.DeviceExit = TouchscreenDeviceExit,
};
//定义获取触摸屏事件信息的函数,并将信息保存在ptInputEvent结构体中
static int TouchscreenGetInputEvent(PInputEvent ptInputEvent)
//定义初始化函数
static int TouchscreenDeviceInit(void)
//定义退出函数
static int TouchscreenDeviceExit(void)
该文件主要通过tslib工具实现对触摸屏事件信息的获取过程:初始化->获取event->保存(返回)信息->关闭。
netinput.c
static InputDevice g_tNetinputDev = {
.name = "netinput",
.GetInputEvent = NetinputGetInputEvent,
.DeviceInit = NetinputDeviceInit,
.DeviceExit = NetinputDeviceExit,
};
同touchscreen.c文件一样,实现设备结构体及内部函数。
input_manager.c
采用多线程是为了能够同时监测触摸屏与网络设备的输入,采用环形buffer是为了不丢失数据
/* 注册各个输入设备 */
void InputInit(void)
/* 初始化输入设备,并为每个输入设备创建线程 同时获得多个输入设备的信息*/
void InputDeviceInit(void)
/* 在APP中调用这个函数,如果buffer为空,则睡眠,等待唤醒 */
int GetInputEvent(PInputEvent pInputEvent)
/* 线程函数->每个硬件对应一个线程,检测到event,就把event保存到buffer中,并唤醒等待数据的线程(告诉这些线程,来数据了) */
static void *input_recv_thread_func(void *data)
//环形buffer
/* start 实现环形缓冲区 */
#define BUFFER_LEN 20
static int g_iRead = 0;
static int g_iWrite = 0;
static InputEvent g_atInputEvents[BUFFER_LEN];
static int isInputBufferFull(void)
{
return (g_iWrite == ((g_iRead + 1) % BUFFER_LEN)); //下一个写的位置等于读的位置,表示为满
}
static int isInputBufferEmpty(void)
{
if (g_iWrite == g_iRead)
{
return 1;
}else
{
return 0;
}
}
static void PutInputEventToBuffer(PInputEvent ptInputEvent)
{
if (!isInputBufferFull())
{
g_atInputEvents[g_iWrite] = *ptInputEvent;
g_iWrite = (g_iWrite + 1) % BUFFER_LEN;
}
}
static int GetInputEventFromBuffer(PInputEvent ptInputEvent)
{
if (!isInputBufferEmpty())
{
*ptInputEvent = g_atInputEvents[g_iRead];
g_iRead = (g_iRead + 1) % BUFFER_LEN;
return 1;
}else
{
return 0;
}
}
/* end 实现环形缓冲区 */