[Xcb] parametrized structs

Daniel Martin consume.noise at gmail.com
Tue Aug 26 01:10:22 PDT 2014


Sorry for jumping in to/that late.

On 22 August 2014 12:01, Christian Linhart <chris at demorecorder.com> wrote:
> On 08/22/14 09:53, Ran Benita wrote:
>> On Mon, Aug 18, 2014 at 04:41:23PM +0200, Christian Linhart wrote:
>>> Add TODO list of things which cannot be done yet
>>> with the current feature-set of xml and the generator.
>>> ---
>>>  src/xinput.xml | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>>  1 file changed, 67 insertions(+)
>>>
>>
>> ...
>>
>>> +Parametrized structs
>>
>> What does this mean?
>>
> This is something similar to C++ templates ( but a bit simpler... )
> ( I'll provide an alternative further below )
>
> Here's why we need that:
>
> The struct DeviceTimeCoord contains a list whose length is determined
> from outside: It is determined by the member "num_axes" in the
> GetDeviceMotionEvents-reply.
>
> So we need a mechanism to get that length into the struct.

Imho, you shouldn't stress yourself to much with this request.
It would be nice to have for completeness, but:
- Ask the server for a list of events within a timeframe?
  One could just register for the events and queue them on the
  client-side.
- And more important it's for "legacy" XI 1 events.

> One way is to parametrize the struct similar to a C++ - template, but run-time evaluated.
>
> The xml could look like follows ( explanations further below )
>
> ===============================================================================
> 01    <struct name="DeviceTimeCoord">
> 02        <param name="num_axes" type="CARD8" />
> 03        <field type="TIMESTAMP" name="time" />
> 04        <list type="INT32" name="valuators">
> 05            <paramref>num_axes</paramref>
> 06        </list>
> 07    </struct>
> 08
> 09    <request name="GetDeviceMotionEvents" opcode="10">
> 10        <field type="TIMESTAMP" name="start" />
> 11        <field type="TIMESTAMP" name="stop" altenum="Time" />
> 12        <field type="CARD8"     name="device_id" />
> 13        <pad bytes="3"/>
> 14        <reply>
> 15            <field type="CARD8"  name="xi_reply_type" />
> 16            <field type="CARD32" name="num_events" />
> 17            <field type="CARD8"  name="num_axes" />
> 18            <field type="CARD8"  name="device_mode" enum="ValuatorMode" />
> 19            <pad bytes="18" />
> 20            <list name="events" >
> 21                <type>
> 22                     <structref>DeviceTimeCoord</structref>
> 23                     <arg name="num_axes"><fieldref>num_axes</fieldref></arg>
> 24                </type>
> 25                <fieldref>num_events</fieldref>
> 26            </list>
> 27        </reply>
> 28    </request>
> ===============================================================================
>
>
> Explanations:
>
> In line 2, the <param>-tag declares a parameter for this struct ( name of parameter "num_axes", type CARD8 ).
>
> In line 5, the <paramref>-tag is an expression which delivers the value of the parameter,
> which in this case is used for the length of the list
>
> in lines 20 - 24, the type of a list element cannot be specified as xml-attribute "type"
> because it is more complex ( has an argument list ).
> Therefore the type is specified as a tag named "type" in the body of the list-tag.
> It contains the reference to struct DeviceTimeCoord, and the argument-list,
> where the "name"-attribute is the name of the parameter.
>
> In pseudo-C++-code this would look like.
>
> ==================================================================
> template< CARD8 num_axes >   /* derived from line 2 of the xml */
>      struct DeviceTimeCoord
> {
>         TIMESTAMP time;
>         INT32 valuators[num_axes];  /* drived from lines 4-6 of the xml */
> };
>
> struct GetDeviceMotionEvents_Reply
> {
>         CARD8 xi_reply_type;
>         CARD32 num_events;
>         CARD8 num_axes;
>         CARD7 device_mode;
>         BYTE pad[18];
>         DeviceTimeCoord<num_axes> events[num_events];
>                         /* derived from lines 20-26 of the xml */
>                         /* num_axes and num_events are run-time values,
>                         which would be illegal in C++, but I hope the
>                         C++ pseudo-code still helps with understanding */
> };
> ==================================================================
>
> ***
>
> Alternative: Inline structs:
>
> Another possibility would be inline structs (where the generator
> would have to extract the implicit parametrization to add these
> params to the param-list of Sizeof, Unpack, ... functions.
>
> This could look like:
> ==================================================================
> 01    <request name="GetDeviceMotionEvents" opcode="10">
> 02        <field type="TIMESTAMP" name="start" />
> 03        <field type="TIMESTAMP" name="stop" altenum="Time" />
> 04        <field type="CARD8"     name="device_id" />
> 05        <pad bytes="3"/>
> 06        <reply>
> 07            <field type="CARD8"  name="xi_reply_type" />
> 08            <field type="CARD32" name="num_events" />
> 09            <field type="CARD8"  name="num_axes" />
> 10            <field type="CARD8"  name="device_mode" enum="ValuatorMode" />
> 11            <pad bytes="18" />
> 12            <list name="events" >
> 13                <struct name="DeviceTimeCoord">
> 14                    <field type="TIMESTAMP" name="time" />
> 15                    <list type="INT32" name="valuators">
> 16                        <fieldref>num_axes</fieldref>
> 17                    </list>
> 18                </struct>
> 19                <fieldref>num_events</fieldref>
> 20            </list>
> 21        </reply>
> 22    </request>
> ==================================================================
>
> In lines 13 to 17, the struct is defined inline and therefore it is clear
> what "num_axes" refers to.
>
> In this example, the inline struct has a name, but the name could be
> omitted. This would then be an anonymous inline struct.
>
> ***
>
> For me it is not clear what will be better:
> * explicit parametrization like in the first example?
> * implicit parametrization by inlining as in the second example?
>
> My guess is that explicit parametrization will be easier to implement in the generator.
>
> Implicit parametrization by inlining will make writing the xml easier
> when such a struct is only needed at one place.
>
> When it is needed in multiple places, then inlining will cause
> code-duplication whereas explicit parametrization will
> allow code-reuse.
>
> ***
>
> What do you think?

I would vote for the inline struct. There's another request where this
could be usefull (skip the API-compatibility for this thought):
    RandR/GetScreenResources
    http://cgit.freedesktop.org/xcb/proto/tree/src/randr.xml#n220

With inlined structs it could be changed somehow like:

<request name="GetScreenResources" opcode="8">
  <field type="WINDOW" name="window" />
  <reply>
    <pad bytes="1" />
    ...
    <list name="modes">
      <struct name="ModeInfo">
        ...
        <field type="CARD16" name="name_len" />
      </struct>
      <fieldref>num_modes</fieldref>
    </list>
    <list name="names">
      <list type="char" name="mode_name"> <!-- nest into a struct? -->
        <fieldref>name_len</fieldref>
      </list>
      <fieldref>num_modes</fieldref>
    </list>
  </reply>
</request>


Cheers,
    Daniel Martin


More information about the Xcb mailing list