使用Rust绑定调用xcb PutImage时出现长度错误求助
X11 PutImage 长度错误问题修复
尝试用Rust将测试图像绘制到Pixmap时,遇到X协议的长度错误(Error Code 16),代码及错误信息如下:
const B: u8 = 0x00; // background const C: u8 = 0xCC; // corner const E: u8 = 0xEE; // edge const F: u8 = 0xFF; // foreground const CROSSIMG: [u8; 120] = [ B, B, B, B, B, B, B, B, B, B, // 0 B, B, B, C, E, E, C, B, B, B, // 1 B, B, B, E, F, F, E, B, B, B, // 2 B, C, E, E, F, F, E, E, C, B, // 3 B, E, F, F, F, F, F, F, E, B, // 4 B, E, F, F, F, F, F, F, E, B, // 5 B, C, E, E, F, F, E, E, C, B, // 6 B, B, B, E, F, F, E, B, B, B, // 7 B, B, B, E, F, F, E, B, B, B, // 8 B, B, B, E, F, F, E, B, B, B, // 9 B, B, B, C, E, E, C, B, B, B, // 10 B, B, B, B, B, B, B, B, B, B, // 11 ]; let pix_id = conn.generate_id(); conn.check_request(conn.send_request_checked(&x::CreatePixmap { depth: 8, pid: pix_id, drawable: x::Drawable::Window(screen.root()), width: 20, height: 20, }))?; let context = conn.generate_id(); let cookie = conn.send_request_checked(&x::CreateGc { cid: context, drawable: xcb::x::Drawable::Pixmap(pix_id), value_list: &[], }); conn.check_request(cookie)?; println!("{:?}", context.resource_id()); let req = &x::PutImage { format: x::ImageFormat::XyPixmap, drawable: x::Drawable::Pixmap(pix_id), gc: context, width: 10, height: 12, dst_x: 0, dst_y: 0, left_pad: 0, depth: 8, data: &CROSSIMG, }; println!("request: {:?}, length: {:?} ", req, 0); let cookie = conn.send_request_checked(req); conn.check_request(cookie)?;
错误信息:
Error: Protocol(X(Length(RequestError { response_type: 0, error_code: 16, sequence: 17, bad_value: 37748738, minor_opcode: 0, major_opcode: 72, pad: 1 }), Some("x::PutImage")))
问题根源
错误码16对应X11协议的Length错误,核心问题是PutImage的格式参数与数据格式不匹配:
- 你使用了
ImageFormat::XyPixmap(平面格式),但CROSSIMG是每个像素1字节的灰度数据,属于ZPixmap(像素打包格式)。 XyPixmap格式下,depth=8意味着需要8个独立的单色位平面数据,而你的数据是单平面的像素打包数据,导致服务器预期的数据长度与实际发送的不匹配。
修复步骤
- 修改图像格式为ZPixmap:将
PutImage的format参数改为x::ImageFormat::ZPixmap,匹配灰度数据格式。 - 可选:调整Pixmap尺寸匹配图像:将
CreatePixmap的width和height改为10和12,避免创建过大的Pixmap。
修复后的关键代码片段:
// 修改CreatePixmap尺寸(可选) conn.check_request(conn.send_request_checked(&x::CreatePixmap { depth: 8, pid: pix_id, drawable: x::Drawable::Window(screen.root()), width: 10, // 改为图像宽度 height: 12, // 改为图像高度 }))?; // 修改PutImage的format为ZPixmap let req = &x::PutImage { format: x::ImageFormat::ZPixmap, // 此处修改 drawable: x::Drawable::Pixmap(pix_id), gc: context, width: 10, height: 12, dst_x: 0, dst_y: 0, left_pad: 0, depth: 8, data: &CROSSIMG, };
内容的提问来源于stack exchange,提问作者Oliver Gerlach
相关产品推荐
相关产品推荐

