简单的IAL分析
一、程序说明
1.下面程序是基于一个红外的设备文件,从该设备中能接收到红外遥控的硬件编码。
2.两个文件需要覆盖掉libmingiui*/src/ial/中的两个文件编译时加上 --enable-video-qvfb
3.为了简单,就直接在qvfb引擎上进行修改
二、程序源码及代码说明
/*
qvfb.h
*/
#ifndef _IAL_qvfb_h
#define _IAL_qvfb_h
#define kb_dev "/dev/ir"
//一个现成的红外设备,当按钮按下后可以从这里读到一个整型
#define TIME_KEYUP 30
//设定一个按钮自动弹起的时钟30ms
struct QVFbKeyData
{
unsigned int unicode;
//unsigned int modifiers;
//BYTE press;
//BYTE repeat;
};//读到红外数据的结构,实际是一个无符号整型
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
BOOL InitQVFBInput (INPUT* input, const char* mdev, const char* mtype);
void TermQVFBInput (void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _IAL_qvfb_h */
***文件结束************************************
/*
qvfb.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include "common.h"
#ifdef _QVFB_IAL
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "minigui.h"
#include "misc.h"
#include "ial.h"
#include "qvfb.h"
extern unsigned int __mg_timer_counter;
// minigui自带的一个计时器
static int mouse_fd = -1;
static int kbd_fd = -1;
//static POINT mouse_pt;
//static int mouse_buttons;
static struct QVFbKeyData kbd_data;
static unsigned char kbd_state [NR_KEYS];
static unsigned char last = 0;
//保存上一次取道的扫描码
static int time_pre = -1 ;
//下面是一个硬件码到扫描码的转化表
static int keycode_scancode[0x21] =
{
SCANCODE_CURSORBLOCKUP, /*0x00 UP0 UP*/
SCANCODE_CURSORBLOCKDOWN, /*0x01 Down DOWN*/
SCANCODE_CURSORBLOCKRIGHT, /*0x02 Right RIGHT*/
SCANCODE_CURSORBLOCKLEFT, /*0x03 Left LEFT*/
0x003C, /*0x04 Audio F2*/
SCANCODE_LEFTALT, /*0x05 MENU*/
0x0040, /*0x06 Radio 电/广F6*/
SCANCODE_ESCAPE, /*0x07 Exit ESC*/
0x003D, /*0x08 Pause F3*/
0x003B, /*0x09 FAV F1*/
0x0044, /*0x0A OWER F10*/
0x003F, /*0x0B TV 缩放F5*/
0x0057, /*0x0C MUTE F11*/
0x0000, /*0x0D 没有该按钮*/
0x0042, /*0x0E TV/Sat 搜台F8*/
0x003E, /*0x0F TXT F4*/
SCANCODE_0, /*0x10 0 0*/
SCANCODE_1, /*0x11 1 1*/
SCANCODE_2, /*0x12 2 2*/
SCANCODE_3, /*0x13 3 3*/
SCANCODE_4, /*0x14 4 4*/
SCANCODE_5, /*0x15 5 5*/
SCANCODE_6, /*0x16 6 6*/
SCANCODE_7, /*0x17 7 7*/
SCANCODE_8, /*0x18 8 8*/
SCANCODE_9, /*0x19 9 9*/
SCANCODE_CAPSLOCK, /*0x1A quality CAPLOCK*/
SCANCODE_BACKSPACE, /*0x1B recall BACKSPACE*/
SCANCODE_PAGEUP, /*0x1C Sat PAGEUP*/
SCANCODE_PAGEDOWN, /*0x1D Skew PAGEDOWN*/
0x0043, /*0x1E Guid F9*/
SCANCODE_ENTER, /*0x1F OK ENTER*/
0x0041 /*0x40 Info F7*/
};
static unsigned char keycode_to_scancode (unsigned int keycode)
{
keycode >>= 16;
keycode &= 0x0FF;
fprintf (stderr, "IAL:keycode = %d!\n",keycode);
if(keycode >= 0x20)
{
keycode = 0x20;
}
return keycode_scancode[keycode];
}
/************************ Low Level Input Operations **********************/
/*
* Mouse operations -- Event
*鼠标函数空,忽略
*/
static int mouse_update (void)
{
return 1;
}
static void mouse_getxy (int *x, int* y)
{
;
}
static int mouse_getbutton (void)
{
return 0;
}
////////////////////////////////////////////
static int keyboard_update (void)
{
struct QVFbKeyData l_kbd_data;
int ret;
if(!(last & 0x80))
{
ret = read (kbd_fd, &l_kbd_data, sizeof (struct QVFbKeyData));
////////////////////判断是否有数据
if (ret == sizeof (struct QVFbKeyData)) {
kbd_data = l_kbd_data;
}
else
{
return 0;
}
/////////////////////////////////
//按钮未弹起前不接收其他按钮
last = keycode_to_scancode (kbd_data.unicode);
kbd_state[last]=1; //新按钮按下
time_pre = __mg_timer_counter;//开始按钮弹起计时
fprintf (stderr, "IAL:Key Down!\n");
}
else
{
kbd_state[last & 0x7f]=0;
time_pre = -1;
last = 0;
fprintf (stderr, "IAL:Key Up!\n");
}
return NR_KEYS;
}
static const char* keyboard_getstate (void)
{
return kbd_state;
}
/* NOTE by weiym: Do not ignore the fd_set in, out, and except */
#ifdef _LITE_VERSION
static int wait_event (int which, int maxfd, fd_set *in, fd_set *out, fd_set *except,
struct timeval *timeout)
#else
static int wait_event (int which, fd_set *in, fd_set *out, fd_set *except,
struct timeval *timeout)
#endif
{
int interval;
fd_set rfds;
int retvalue = 0;
int fd, e;
////////////////////////////////
if(time_pre > 0)
{
interval= __mg_timer_counter - time_pre;
if (interval > TIME_KEYUP)
{
//kbd_state[last] = 0;
last |= 0x80; //发送按钮弹起数据
retvalue |= IAL_KEYEVENT ;
return retvalue;
}
}
/////////////////////////////////
if (!in) {
in = &rfds;
FD_ZERO (in);
}
if (which & IAL_MOUSEEVENT && mouse_fd >= 0) {
fd = mouse_fd;
FD_SET (fd, in);
#ifdef _LITE_VERSION
if (fd > maxfd) maxfd = fd;
#endif
}
if (which & IAL_KEYEVENT){
fd = kbd_fd;
FD_SET (kbd_fd, in);
#ifdef _LITE_VERSION
if (fd > maxfd) maxfd = fd;
#endif
}
/* FIXME: pass the real set size */
#ifdef _LITE_VERSION
e = select (maxfd + 1, in, out, except, timeout) ;
#else
e = select (FD_SETSIZE, in, out, except, timeout) ;
#endif
if (e > 0 && time_pre < 0) { //按钮按下后就不产生事件,直到按钮弹起
fd = mouse_fd;
/* If data is present on the mouse fd, service it: */
if (fd >= 0 && FD_ISSET (fd, in)) {
FD_CLR (fd, in);
retvalue |= IAL_MOUSEEVENT;
}
fd = kbd_fd;
/* If data is present on the keyboard fd, service it: */
if (fd >= 0 && FD_ISSET (fd, in)) {
FD_CLR (fd, in);
retvalue |= IAL_KEYEVENT;
}
} else if (e < 0 || time_pre > 0) {
return -1;
}
return retvalue;
}
BOOL InitQVFBInput (INPUT* input, const char* mdev, const char* mtype)
{
kbd_fd = open (kb_dev, O_RDONLY);
if (kbd_fd < 0)
{
fprintf (stderr, "IAL:Can not open /dev/ir !\n");
}
/////////////////////////////////////////////////////
input->update_mouse = mouse_update;
input->get_mouse_xy = mouse_getxy;
input->set_mouse_xy = NULL;
input->get_mouse_button = mouse_getbutton;
input->set_mouse_range = NULL;
input->suspend_mouse= NULL;
input->resume_mouse = NULL;
input->update_keyboard = keyboard_update;
input->get_keyboard_state = keyboard_getstate;
input->suspend_keyboard = NULL;
input->resume_keyboard = NULL;
input->set_leds = NULL;
input->wait_event = wait_event;
return TRUE;
}
void TermQVFBInput (void)
{
if (kbd_fd >= 0)
close (kbd_fd);
}
#endif /* _QVFB_IAL */
***文件结束************************************