通过 XCB 的 GetDeviceInfo XKB 请求产生 BadAccess 错误
GetDeviceInfo XKB request through XCB yields BadAccess error
我正在尝试使用 XCB 的 XKB 扩展来捕获键盘输入。我正在编写的特定实现是生锈的,但是代码的错误部分主要是通过 FFI 调用。我的目标是能够处理键盘事件,例如按下、释放等键,并且能够将键码转换为 unicode。目前我正在尝试从 libxkbcommon 快速指南中获取 this example 工作。
下面是我试过的代码:
let (conn, screen_num) = Connection::connect(None)?;
// Other code...
let raw_conn = conn.get_raw_conn() as *mut xkbcommon_sys::xcb_connection_t;
let context = unsafe { xkb_context_new(XKB_CONTEXT_NO_FLAGS) };
if context.is_null() {
return Err(Error::XkbContextInit);
}
let device_id = unsafe { xkb_x11_get_core_keyboard_device_id(raw_conn) };
// This branch is taken
if device_id == -1 {
unsafe { xkb_context_unref(context); }
return Err(Error::XkbGetCoreKbDev);
}
我希望能够获取核心键盘的设备 ID,但是函数返回 -1
,表示错误。
经过一些试验和挖掘,我发现 xkb_x11_get_core_keyboard_device_id
函数特别失败 on this request,它使用 XCB_XKB_ID_USE_CORE_KBD
作为设备规范的值。由于我没有从这个函数中得到太多的错误信息,我将对X服务器的请求翻译成了rust,得到了以下错误:
// Output from debugging the returned error enum
Protocol(
X(
Access(
RequestError {
response_type: 0,
error_code: 10,
sequence: 3,
bad_value: 2003,
minor_opcode: 1,
major_opcode: 130,
pad: 1
}
)
)
)
我还尝试了列出的设备规格的其他一些值 here,但收到了同样的错误。
不确定这是否是 X 服务器的问题,我在安装 Kali 以及 Ubuntu 20.04 VM 时尝试了它,两者都产生了相同的错误(尽管bad_value
字段)。此外,每当我在需要设备规格的地方使用 XCB_XKB_ID_USE_CORE_KBD
时,我都会收到此错误。我不太确定是什么导致了这个问题。这似乎与 XKB 特别相关,因为我也在使用 XCB 捕获屏幕,到目前为止我还没有遇到任何错误。任何帮助或指导将不胜感激。
搜索了一段时间后,我发现 this post 链接到一些文档,这让我意识到我从未设置 XKB 扩展。添加以下代码修复了问题:
let res = unsafe {
xkb_x11_setup_xkb_extension(
raw_conn,
MAJOR_VERSION as u16,
MINOR_VERSION as u16,
XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS,
ptr::null_mut(),
ptr::null_mut(),
ptr::null_mut(),
ptr::null_mut()
)
};
if res == 0 {
return Err(Error::XkbInit);
}
如果您使用的是 xcb 和 xkbcommon crate,他们有一个使用(当前)beta 版本的 crate 的示例,该 crate 使用 API 而不是不安全的函数:
let context = xkb::Context::new(xkb::CONTEXT_NO_FLAGS);
let device_id = xkb::x11::get_core_keyboard_device_id(&connection);
let keymap = xkb::x11::keymap_new_from_device(
&context,
&connection,
device_id,
xkb::KEYMAP_COMPILE_NO_FLAGS,
);
let state = xkb::x11::state_new_from_device(&keymap, &connection, device_id);
https://github.com/rust-x-bindings/toy_xcb/blob/master/src/keyboard.rs
我正在尝试使用 XCB 的 XKB 扩展来捕获键盘输入。我正在编写的特定实现是生锈的,但是代码的错误部分主要是通过 FFI 调用。我的目标是能够处理键盘事件,例如按下、释放等键,并且能够将键码转换为 unicode。目前我正在尝试从 libxkbcommon 快速指南中获取 this example 工作。
下面是我试过的代码:
let (conn, screen_num) = Connection::connect(None)?;
// Other code...
let raw_conn = conn.get_raw_conn() as *mut xkbcommon_sys::xcb_connection_t;
let context = unsafe { xkb_context_new(XKB_CONTEXT_NO_FLAGS) };
if context.is_null() {
return Err(Error::XkbContextInit);
}
let device_id = unsafe { xkb_x11_get_core_keyboard_device_id(raw_conn) };
// This branch is taken
if device_id == -1 {
unsafe { xkb_context_unref(context); }
return Err(Error::XkbGetCoreKbDev);
}
我希望能够获取核心键盘的设备 ID,但是函数返回 -1
,表示错误。
经过一些试验和挖掘,我发现 xkb_x11_get_core_keyboard_device_id
函数特别失败 on this request,它使用 XCB_XKB_ID_USE_CORE_KBD
作为设备规范的值。由于我没有从这个函数中得到太多的错误信息,我将对X服务器的请求翻译成了rust,得到了以下错误:
// Output from debugging the returned error enum
Protocol(
X(
Access(
RequestError {
response_type: 0,
error_code: 10,
sequence: 3,
bad_value: 2003,
minor_opcode: 1,
major_opcode: 130,
pad: 1
}
)
)
)
我还尝试了列出的设备规格的其他一些值 here,但收到了同样的错误。
不确定这是否是 X 服务器的问题,我在安装 Kali 以及 Ubuntu 20.04 VM 时尝试了它,两者都产生了相同的错误(尽管bad_value
字段)。此外,每当我在需要设备规格的地方使用 XCB_XKB_ID_USE_CORE_KBD
时,我都会收到此错误。我不太确定是什么导致了这个问题。这似乎与 XKB 特别相关,因为我也在使用 XCB 捕获屏幕,到目前为止我还没有遇到任何错误。任何帮助或指导将不胜感激。
搜索了一段时间后,我发现 this post 链接到一些文档,这让我意识到我从未设置 XKB 扩展。添加以下代码修复了问题:
let res = unsafe {
xkb_x11_setup_xkb_extension(
raw_conn,
MAJOR_VERSION as u16,
MINOR_VERSION as u16,
XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS,
ptr::null_mut(),
ptr::null_mut(),
ptr::null_mut(),
ptr::null_mut()
)
};
if res == 0 {
return Err(Error::XkbInit);
}
如果您使用的是 xcb 和 xkbcommon crate,他们有一个使用(当前)beta 版本的 crate 的示例,该 crate 使用 API 而不是不安全的函数:
let context = xkb::Context::new(xkb::CONTEXT_NO_FLAGS);
let device_id = xkb::x11::get_core_keyboard_device_id(&connection);
let keymap = xkb::x11::keymap_new_from_device(
&context,
&connection,
device_id,
xkb::KEYMAP_COMPILE_NO_FLAGS,
);
let state = xkb::x11::state_new_from_device(&keymap, &connection, device_id);
https://github.com/rust-x-bindings/toy_xcb/blob/master/src/keyboard.rs