通过Rust绑定调用xcb PutImage时出现长度错误

7d7tgy0s  于 2023-04-21  发布在  其他
关注(0)|答案(1)|浏览(149)

我试图将一个简单的测试图像放到pixmap(然后放到屏幕上)。然而,我总是得到一个长度错误。从我能找到的所有C示例(不多,Rust没有)来看,这应该可以工作。我假设我得到了一些错误。任何帮助都很感激。下面是我的代码:

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")))
iklwldmw

iklwldmw1#

我 * 打赌 * 你会得到类似的输出比我当运行以下:

$ xdpyinfo | grep 'depth 8'
    depth 8, bits_per_pixel 8, scanline_pad 32

这意味着对于depth 8,每一个图像行都必须对齐4字节的倍数。因此,对于宽度为10的PutImage,每行需要12字节,总像素数据需要12*12字节。
X11服务器中的实际长度检查可能是这样的:

if ((bytes_to_int32(lengthProto * stuff->height) +
         bytes_to_int32(sizeof(xPutImageReq))) != client->req_len)
        return BadLength;

lengthProto(在本例中为XYPixmap)来自同一函数中的以下代码:

length = BitmapBytePad(stuff->width + stuff->leftPad);
        length *= stuff->depth;

方案参考的相关部分:
每条扫描线被填充到由bitmap-scanline-pad给定的多个位。填充位具有任意值。

相关问题