reply_t vs request_t - passing them in interchange

2019-09-09 22:38发布

问题:

I'm having an issue with XCB. I don't understand the difference between *_reply_t vs *_request_t types.

It seems that the *_reply_t is passed in place of the *_response_t, however the structures are very different.

For instance:

xcb_randr_get_screen_resources_current_reply_t *reply = xcb_randr_get_screen_resources_current_reply(
        connection, xcb_randr_get_screen_resources_current(connection, root), NULL);

So now reply is the type of *_reply_t. But now I need to use xcb_randr_get_screen_resources_current_outputs which expects the first argument to be of type xcb_randr_get_screen_resources_current_request_t as per the docs here:

http://www.linuxhowtos.org/manpages/3/xcb_randr_get_screen_resources_current_outputs.htm

          xcb_randr_output_t *xcb_randr_get_screen_resources_current_outputs(
            const xcb_randr_get_screen_resources_current_request_t *reply
          );

However the response from the first call is of type xcb_randr_get_screen_resources_current_reply_t (*_reply_t). How is it possible to pass this into the outputs call without casting? The structures are completely different per the docs:

typedef struct xcb_randr_get_screen_resources_current_reply_t {
    uint8_t         response_type;
    uint8_t         pad0;
    uint16_t        sequence;
    uint32_t        length;
    xcb_timestamp_t timestamp;
    xcb_timestamp_t config_timestamp;
    uint16_t        num_crtcs;
    uint16_t        num_outputs;
    uint16_t        num_modes;
    uint16_t        names_len;
    uint8_t         pad1[8];
} xcb_randr_get_screen_resources_current_reply_t;

And the struct for the *_request_t is not in the docs I got it from the source code here:

https://xcb.freedesktop.org/manual/randr_8h_source.html#l00896

   typedef struct xcb_randr_get_screen_resources_current_request_t {
       uint8_t      major_opcode; 
       uint8_t      minor_opcode; 
       uint16_t     length; 
       xcb_window_t window; 
   } xcb_randr_get_screen_resources_current_request_t;

I do ctypes so I have to declare the type I am going to pass in beforehand for the signature of the method. So I am very confused on how something of a totally different structure (reply) is going into a second call which has structure of request.

回答1:

I think what you have stumbled upon is simply a documentation bug. All the functions which claim to take *_request_t actually expect *_reply_t. From the very source you linked from, just look at the actual function definition (rather than what the man page says) and you'll find

xcb_randr_output_t *
    xcb_randr_get_screen_resources_current_outputs (const xcb_randr_get_screen_resources_current_reply_t *R  );

The struct you found is not actually used anywhere in the file, so it's probably some forgotten leftover, or maybe is still kept around for compatibility reasons.



标签: xcb