[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