3. 键盘通知器

可以使用 register_keyboard_notifier 注册键盘事件的回调函数(详情参见 kbd_keycode() 函数)。 传递的结构是 keyboard_notifier_param(参见 <linux/keyboard.h>)

  • ‘vc’ 始终提供键盘事件适用的 VC;

  • ‘down’ 对于按键事件为 1,对于释放事件为 0;

  • ‘shift’ 是当前的修饰符状态,掩码位索引为 KG_*;

  • ‘ledstate’ 是当前的 LED 状态;

  • ‘value’ 取决于事件的类型。

  • KBD_KEYCODE 事件总是在其他事件之前发送,value 是键码。

  • 如果键码未绑定到键符,则发送 KBD_UNBOUND_KEYCODE 事件。 value 是键码。

  • 如果键码 -> 键符转换产生 Unicode 字符,则发送 KBD_UNICODE 事件。 value 是 Unicode 值。

  • 如果键码 -> 键符转换产生非 Unicode 字符,则发送 KBD_KEYSYM 事件。 value 是键符。

  • KBD_POST_KEYSYM 事件在处理非 Unicode 键符之后发送。 这允许检查生成的 LED,例如。

对于每种事件(除了最后一种),回调可以返回 NOTIFY_STOP 以“吃掉”事件:通知循环停止,键盘事件被丢弃。

在一个粗略的 C 代码片段中,我们有

kbd_keycode(keycode) {
    ...
    params.value = keycode;
    if (notifier_call_chain(KBD_KEYCODE,&params) == NOTIFY_STOP)
        || !bound) {
            notifier_call_chain(KBD_UNBOUND_KEYCODE,&params);
            return;
    }

    if (unicode) {
            param.value = unicode;
            if (notifier_call_chain(KBD_UNICODE,&params) == NOTIFY_STOP)
                    return;
            emit unicode;
            return;
    }

    params.value = keysym;
    if (notifier_call_chain(KBD_KEYSYM,&params) == NOTIFY_STOP)
            return;
    apply keysym;
    notifier_call_chain(KBD_POST_KEYSYM,&params);
}

注意

此通知器通常从中断上下文调用。