免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2125 | 回复: 0
打印 上一主题 下一主题

xkb ,kernel keycode,xserver keycode, [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-09-03 18:34 |只看该作者 |倒序浏览

                偷空几分钟写一篇,
关于键盘这里是比较复杂的,不同的键盘布局等等,
kernel里面的scancode,make code,breakcode可以参考这里的文档
http://www.win.tue.nl/~aeb/linux/kbd/scancodes-10.html
关于kernel keycode到 xserver keycode的转换,
基本上是加8
之前看到一个网页的,忘记地址了,反正是一个数组的。
好像记得是这个邮件
http://lists.freedesktop.org/archives/xorg/2006-June/015589.html
记住范围是8~255
关于xkb,这个是xserver这边处理非常复杂的一块。
xorg, libx11, xkbcomp等等,都要关注。
xkb的设置函数基本都在libx11里面。
关于键值是怎么映射的,
给一个简单的例子,下周又要出征US了,抓紧时间。
比如我们发现audio play的键值不对,蓝牙控制无法使用。
最简单的说明如下
1:kernel里面的驱动,比如说键盘,可能是不标准的键盘,报键值164上面,
也就是说我们从evbug里面看到是164,到xserver这边就被转换到了172基本是加8的关系,
这个可以从/usr/share/X11/xkb/keycodes/evdev
我们默认使用的是这个keycode,这些都是rules里面定的。
     = 172;    // #define KEY_PLAYPAUSE           164
定义如下,就是
然后到/usr/share/X11/xkb/symbols/inet里面定义的是这样的
    key    {      [ XF86AudioPlay, XF86AudioPause ] };
就是这个事件没错了。
然后这个是下面的定义,libx11里面有一个文件要关注
root@vax:/mnt/sdb1/qct2/stuff/workspace/work/armv7a-ThunderST-linux-gnueabi/libx11-1_1.2.1-r3/libX11-1.2.1/src#
这里目录下面是有一个文件
XKeysymDB
运行时是装在这里的
/usr/share/X11/XKeysymDB
看看,定义如下
XF86AudioPlay        :1008FF14
XF86AudioStop        :1008FF15
XF86AudioPrev        :1008FF16
XF86AudioNext        :1008FF17
这个都是系统内部的实现,上层应用程序是不需要关注这些的。
我们用的是头文件
/usr/include/X11/XF86keysym.h
#define XF86XK_AudioPlay    0x1008FF14   /* Start playing of audio >   */
#define XF86XK_AudioStop    0x1008FF15   /* Stop playing audio         */
#define XF86XK_AudioPrev    0x1008FF16   /* Previous track             */
#define XF86XK_AudioNext    0x1008FF17   /* Next track                 */
我们程序用的都是这些key,典型应用如下(rhythmbox)
if (XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioPlay) == key->keycode) {
        rb_shell_player_playpause (player, FALSE, NULL);
        return GDK_FILTER_REMOVE;
    } else if (XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioPause) == key->keycode) {
        rb_shell_player_pause (player, NULL);
        return GDK_FILTER_REMOVE;
    } else if (XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioStop) == key->keycode) {
        rb_shell_player_stop (player);
        return GDK_FILTER_REMOVE;
    } else if (XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioPrev) == key->keycode) {
        rb_shell_player_do_previous (player, NULL);
        return GDK_FILTER_REMOVE;
    } else if (XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioNext) == key->keycode) {
        rb_shell_player_do_next (player, NULL);
还有一个问题就是PLAYPAUSE 164和PLAYCD,PAUSECD
有什么区别,恩,是个问题,不过我们一版用164,不用PLAYCD(200->208),PAUSECD(201->209)
实际上定义是一样
     = 208;    // #define KEY_PLAYCD              200
     = 209;    // #define KEY_PAUSECD             201
     = 174;    // #define KEY_STOPCD              166
     = 175;    // #define KEY_RECORD              167
     = 171;    // #define KEY_NEXTSONG            163
     = 172;    // #define KEY_PLAYPAUSE           164
     = 173;    // #define KEY_PREVIOUSSONG        165
inet里面sym如下
    key    {      [ XF86AudioPlay, XF86AudioPause ] };
    key    {      [ XF86AudioPrev         ]       };
    key    {      [ XF86AudioStop, XF86Eject ]    };
    key    {      [ XF86AudioRecord       ]       };
    key    {      [ XF86AudioRewind       ]       };
    key    {      [ XF86Phone             ]       };
//  key    {      [ ]       }; // KEY_ISO
    key    {      [ XF86Tools             ]       };
    key    {      [ XF86HomePage          ]       };
    key    {      [ XF86Refresh           ]       };
    key    {      [ XF86Close             ]       };
//  key    {      [ ]       }; // KEY_MOVE
//  key    {      [ ]       }; // KEY_EDIT
    key    {      [ XF86ScrollUp          ]       };
    key    {      [ XF86ScrollDown        ]       };
    key    {      [ parenleft             ]       };
    key    {      [ parenright            ]       };
    key    {      [ XF86New               ]       };
    key    {      [ Redo                  ]       };
    key    {      [ XF86AudioPlay         ]       };
    key    {      [ XF86AudioPause        ]       };
区别就在于play和pause是否有单独的按键,还是说共用一个按键,
另外就是两个按键的话,反查keycode会有问题。
我记得kdrive是不支持xkb的好像,直接使用的是linux/input.h
下面是一些记录(数万字,太长,cut一下,没有整理)
1:kernel报evcode上面比如163
2:rules里面对应/usr/share/X11/xkb/
evdev
     = 171;    // #define KEY_NEXTSONG            163
这里是171
inet里面定义
    key    {      [ XF86AudioNext         ]       };
而keysym是在libx11里面写死的。
root@vax:/mnt/sdb1/qct2/stuff/workspace/work/armv7a-ThunderST-linux-gnueabi/libx11-1_1.2.1-r3/libX11-1.2.1# grep Play * -R
Binary file src/StrKeysym.o matches
src/XKeysymDB:XF86AudioPlay        :1008FF14
src/XKeysymDB:XF86AudioRandomPlay    :1008FF99
Binary file src/.libs/libX11.so.6.2.0 matches
Binary file src/.libs/libX11.a matches
Binary file src/.libs/libX11.so.6 matches
Binary file src/.libs/StrKeysym.o matches
Binary file src/.libs/libX11.so.6.2.0T matches
Binary file src/.libs/libX11.so matches
root@vax:/mnt/sdb1/qct2/stuff/workspace/work/armv7a-ThunderST-linux-gnueabi/libx11-1_1.2.1-r3/libX11-1.2.1#
XF86AudioPlay        :1008FF14
XF86AudioStop        :1008FF15
XF86AudioPrev        :1008FF16
XF86AudioNext        :1008FF17
定义了这些键,
而普通的应用程序是从上往下使用的,我们使用的代码会类似如下
    } else if (XKeysymToKeycode (GDK_DISPLAY (), XF86XK_AudioPrev) == key->keycode) {
而这个宏是给应用程序用的。
/usr/include/X11/XF86keysym.h
#define XF86XK_AudioStop    0x1008FF15   /* Stop playing audio         */
#define XF86XK_AudioPrev    0x1008FF16   /* Previous track             */
#define XF86XK_AudioNext    0x1008FF17   /* Next track                 */
这里就对应上了。
/mnt/sdb1/qct2/stuff/workspace/work/armv7a-ThunderST-linux-gnueabi/xproto-1_7.0.15-r0/xproto-7.0.15
是proto里面定义的,编译X和x的程序都需要的。
libx11编译的时候指定这个。
configure:XKEYSYMDB="${X11_DATADIR}/XKeysymDB"
DB和头文件必须保持一致。
db文件里面也说明了。
rc/StrKeysym.c:#ifndef XKEYSYMDB
src/StrKeysym.c:#define KEYSYMDB XKEYSYMDB
src/StrKeysym.c:    dbname = getenv("XKEYSYMDB");
src/config.h.in:#undef XKEYSYMDB
XrmDatabase
_XInitKeysymDB(void)
{
    if (!initialized)
    {
    const char *dbname;
    XrmInitialize();
    /* use and name of this env var is not part of the standard */
    /* implementation-dependent feature */
    dbname = getenv("XKEYSYMDB");
    if (!dbname)
        dbname = KEYSYMDB;
    keysymdb = XrmGetFileDatabase(dbname);
    if (keysymdb)
        Qkeysym[0] = XrmStringToQuark("Keysym");
    initialized = True;
    }
    return keysymdb;
}
XStringToKeysym里面调用这个。
               
               
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/40978/showart_2045015.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP