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 是键码。

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

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

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

  • 在处理非 unicode keysym 之后发送 KBD_POST_KEYSYM 事件。这允许人们例如检查结果 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);
}

注意

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