minigui添加键盘支持

本文主要介绍minigui中添加键盘支持功能

一、介绍

由于项目需求,要在minigui中添加键盘处理。

不清楚minigui默认是否支持键盘,作者拿到的代码是改动过的,没有实现键盘功能。键盘的整个流程涉及到libminigui部分和minigui主应用部分,作者的理解中,libminigui类似于HAL的功能,minigui主应用则主要是调用libminigui库提供的功能,所以改动部分主要在libminigui中。

二、libminigui库

1.libminigui库中的主要流程分析

InitGUI()  函数入口

mg_InitLWEvent()  ->  mg_InitIAL()   注册键盘和光标处理函数

SystemThreads()  ->  pthread_create (&__mg_parsor, NULL, EventLoop, &wait);

EventLoop()  线程中循环查询键盘消息和光标消息

EventLoop:

kernel_GetLWEvent()

    ->  kernel_RefreshCursor()  ->  IAL_GetMouseButton() ->  __mg_cur_input->get_mouse_button  获取光标消息

    ->  IAL_UpdateKeyboard()  ->  IAL_GetKeyboardState()  获取键盘消息

ParseEvent()  ->  QueueDeskMessage()  发送键盘和光标消息

以上只是简单分析库的流程,关于查询键盘消息和光标消息的流程不做深入讨论,这里主要是介绍注册函数的实现。

2.mg_InitIAL函数定义如下:

int mg_InitIAL (void)

{

...

for (i = 0; i < NR_INPUTS; i++) {

        //printf("====================input test===================\n");

        if (strncmp (engine, inputs[i].id, LEN_ENGINE_NAME) == 0) {

            //printf("inputs[i].id: %s\n",inputs[i].id);

            __mg_cur_input = inputs + i;

            break;

        }

    }

...

}

在mg_InitIAL中,主要是检测输入引擎是否存在,并将存在inputs赋值给__mg_cur_input。

3.inputs定义如下:

static INPUT inputs [] =

{

...

#ifdef _MGIAL_TSLIB

    {"tslib", InitTSLibInput, TermTSLibInput},

#endif

...

};

其中InitTSLibInput是输入引擎的初始化,TermTSLibInput是销毁函数。

4.InitTSLibInput

#define KBD_DEVICE "/dev/input/event1"

static int keykoard_fd = -1;

static XVFBKEYDATA kbd_data;

static unsigned char kbd_state [NR_KEYS];

static struct input_event kb_event;

BOOL InitTSLibInput(INPUT* input, const char* mdev, const char* mtype)

{

    const char* tsdevice;

    if ((tsdevice = getenv ("TSLIB_TSDEVICE")) == NULL) {

        tsdevice = mdev;

    }

    //printf("[kevin]: tsdevice:%s\n",tsdevice);

    if (tsdevice == NULL) {

        _MG_PRINTF ("IAL>TSLib: Please specify the ts device\n");

        return FALSE;

    }

    //printf("start InitTSLibInput!\n");

    ts = ts_open (tsdevice, 0);

    if (!ts) {

        _MG_PRINTF ("IAL>TSLib: can not open ts device\n");

        return FALSE;

    }

    if (ts_config (ts)) {

        _MG_PRINTF ("IAL>TSLib: can not config ts device\n");

        return FALSE;

    }

    keykoard_fd = open (KBD_DEVICE, O_RDONLY);

    if (keykoard_fd < 0 ) {

        _MG_PRINTF ("IAL>%s: Can not open button key!\n", __FILE__);

        return FALSE;

    }

    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->update_keyboard = keyboard_update;

    input->get_keyboard_state = keyboard_get_state;

    input->set_leds = NULL;

    input->wait_event = wait_event;

    return TRUE;

}

ts是触摸屏相关的文件指针(即光标函数mouse相关部分),keykoard_fd是键盘的文件指针。与键盘有关的部分是后添加的内容,其余为之前就有的部分。

其中主要添加了keyboard_update和keyboard_get_state的实现,以及在wait_event中加入键盘事件检测。

5.keyboard_update和keyboard_get_state

static int keyboard_update(void)

{

    unsigned char scan_code;

    unsigned char nr_changed_keys = 0;       

    scan_code = kbd_data.key_code;

    kbd_state [scan_code] = kbd_data.key_state ? 1 : 0;

    nr_changed_keys = scan_code + 1;

    //printf("scan_code:%d, kbd_state:%d, nr_changed_keys:%d\n", scan_code, kbd_state[scan_code], nr_changed_keys);

    return nr_changed_keys;

}

static const char * keyboard_get_state (void)

{

    return (char*)kbd_state;

}

主要功能是上报键值和键盘的按键状态。

6.wait_event

static int wait_event (int which, int maxfd, fd_set *in, fd_set *out, fd_set *except, struct timeval *timeout)

{

...

    if((which & IAL_KEYEVENT) && keykoard_fd >= 0)

    {

        FD_SET (keykoard_fd, in); 

    }

#ifndef _MGRM_THREADS

    e = select (maxfd + 1, in, out, except, timeout);

#else

    e = select (FD_SETSIZE, in, out, except, timeout);

#endif

    if (e > 0) {

        if (fd > 0 && FD_ISSET (fd, in)) {

            return IAL_MOUSEEVENT;

        }

        else if(keykoard_fd >= 0  && FD_ISSET (keykoard_fd, in) )

        {

            FD_CLR (keykoard_fd, in); 

            if(read (keykoard_fd, &kb_event, sizeof (struct input_event))>0)

            {

                if(kb_event.type==EV_KEY) 

                    if(kb_event.value==0 || kb_event.value==1) 

                    { 

                        kbd_data.key_code = kb_event.code;

                        kbd_data.key_state = kb_event.value;

                        ret |= IAL_KEYEVENT; 

                        //printf("wait_event, key_code:%d, key_state:%d\n", kbd_data.key_code, kbd_data.key_state);

                    } 

            }

        }

    }

...

}

对键盘的相应操作主要是,read键值和状态,并把键值和状态赋值给全局变量,并由上面提到的keyboard_update和keyboard_get_state上报给处理函数。

7.最后是TermTSLibInput

void TermTSLibInput(void)

{

    if (ts) {

        ts_close(ts);   

        ts = NULL;

    }

    if (keykoard_fd < 0) {

        close(keykoard_fd);   

        keykoard_fd = -1;

    }

}

作用是销毁文件指针。

三、minigui主应用中

static int DesktopPanelProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam)

{

...

switch (message)

{

case MSG_KEYDOWN:

printf ("MGS_KEYDOWN: key %d\n", LOWORD(wParam));

break;

case MSG_CHAR:

printf ("MGS_CHAR: char %d\n", wParam);

break;

...

}

return DefaultMainWinProc(hWnd, message, wParam, lParam);

}

在窗口的MainWindowProc中对MSG_KEYDOWN和MSG_CHAR消息进行相应的处理即可。

四、总结

值得注意的是,当插入键盘开机之后,键盘的结点是event0和event1,触摸屏的结点是event2,此时无论是键盘还是触摸屏都无效了(触摸屏open的结点是event0)。当先开机后插入键盘时,键盘的结点是event1和event2,触摸屏的结点是event0,此时键盘和触摸屏都能正常工作。

关于event结点的自动挂载功能实现,暂时还没有思路,如果后面能够解决,作者会将实现方法记录下来供大家参考。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容