Update to xcb-proto 1.13. ok tb@

This commit is contained in:
matthieu
2018-09-11 19:31:11 +00:00
parent f4445f7d08
commit cf8b8cfede
16 changed files with 464 additions and 125 deletions

View File

@@ -1,3 +1,14 @@
Release 1.13 (2018-02-28)
=========================
* dri3: Add multi-plane/modifier protocol for v1.2
* present: Add suboptimal-copy protocol for v1.2
* randr: Add output-lease protocol for v1.6
* Add support for variable-sized lists of FDs
* xge: Add safe generic-event sending support
* Fix initial connection handshaking
* Updated XML DTD
* Python 3.x cleanups and compatibility
Release 1.12 (2016-05-18)
=========================
* xinput: Various padding-related additions and fixes

View File

@@ -3,7 +3,7 @@
AC_PREREQ(2.57)
AC_INIT([XCB Proto],
1.12,
1.13,
[xcb@lists.freedesktop.org])
AC_CONFIG_SRCDIR([xcb-proto.pc.in])
AM_INIT_AUTOMAKE([foreign dist-bzip2])

View File

@@ -76,6 +76,12 @@ Top-Level Elements
the field and pad elements described in the section "Structure Contents
below".
<eventstruct name="identifier">event-type-selector list</struct>
This element represents a data structure that is the wire-representation of
an event. The event can be any type that's selected by the
event-type-selector list.
<xidtype name="identifier" />
This element represents an identifier for a particular type of resource.
@@ -359,6 +365,29 @@ Expressions
This element represents the current list-element when used inside
a list-iteration expression such as <sumof>.
Event-Type-Selector List
------------------------
The event-type-selector list selects a set of eventtypes.
It consists of any number of the following elements:
<allowed extension="identifier" xge="boolean"
opcode-min="integer" opcode-max="integer" />
The extension attribute selects events from the given extension.
If the xge attribute is true, the event is an X Generic Event and
will be treated as such.
opcode-min and opcode-max describe the minimum and maximum opcode
respectively. The opcode is the same number as the number-attribute
of an event definition. I.e. this is the offset from the event-base
to the actual number used on the wire.
In the current implementation, only xge="false" is supported.
Documentation
-------------

View File

@@ -1,9 +1,9 @@
#!/bin/sh
# py-compile - Compile a Python program
scriptversion=2011-06-08.12; # UTC
scriptversion=2016-01-11.22; # UTC
# Copyright (C) 2000-2014 Free Software Foundation, Inc.
# Copyright (C) 2000-2017 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -165,6 +165,6 @@ sys.stdout.write('\n')" 2>/dev/null || :
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

View File

@@ -23,7 +23,7 @@ OF THIS SOFTWARE.
-->
<xcb header="dri3" extension-xname="DRI3" extension-name="DRI3"
major-version="1" minor-version="0">
major-version="1" minor-version="2">
<import>xproto</import>
<!-- Types -->
@@ -94,4 +94,73 @@ OF THIS SOFTWARE.
</reply>
</request>
<!-- v1.2 -->
<request name="GetSupportedModifiers" opcode="6">
<field type="CARD32" name="window" />
<field type="CARD8" name="depth"/>
<field type="CARD8" name="bpp"/>
<pad bytes="2"/>
<reply>
<required_start_align align="8" />
<pad bytes="1" />
<field type="CARD32" name="num_window_modifiers" />
<field type="CARD32" name="num_screen_modifiers" />
<pad bytes="16" />
<list type="CARD64" name="window_modifiers">
<fieldref>num_window_modifiers</fieldref>
</list>
<list type="CARD64" name="screen_modifiers">
<fieldref>num_screen_modifiers</fieldref>
</list>
</reply>
</request>
<request name="PixmapFromBuffers" opcode="7">
<required_start_align align="8" />
<field type="PIXMAP" name="pixmap" />
<field type="WINDOW" name="window" />
<field type="CARD8" name="num_buffers" />
<pad bytes="3" />
<field type="CARD16" name="width" />
<field type="CARD16" name="height" />
<field type="CARD32" name="stride0" />
<field type="CARD32" name="offset0" />
<field type="CARD32" name="stride1" />
<field type="CARD32" name="offset1" />
<field type="CARD32" name="stride2" />
<field type="CARD32" name="offset2" />
<field type="CARD32" name="stride3" />
<field type="CARD32" name="offset3" />
<field type="CARD8" name="depth" />
<field type="CARD8" name="bpp" />
<pad bytes="2" />
<field type="CARD64" name="modifier" />
<list type="fd" name="buffers">
<fieldref>num_buffers</fieldref>
</list>
</request>
<request name="BuffersFromPixmap" opcode="8">
<field type="PIXMAP" name="pixmap" />
<reply>
<required_start_align align="8" />
<field type="CARD8" name="nfd"/>
<field type="CARD16" name="width" />
<field type="CARD16" name="height" />
<pad bytes="4"/>
<field type="CARD64" name="modifier" />
<field type="CARD8" name="depth" />
<field type="CARD8" name="bpp" />
<pad bytes="6"/>
<list type="CARD32" name="strides">
<fieldref>nfd</fieldref>
</list>
<list type="CARD32" name="offsets">
<fieldref>nfd</fieldref>
</list>
<list type="fd" name="buffers">
<fieldref>nfd</fieldref>
</list>
</reply>
</request>
</xcb>

View File

@@ -23,7 +23,7 @@ OF THIS SOFTWARE.
-->
<xcb header="present" extension-xname="Present" extension-name="Present"
major-version="1" minor-version="0">
major-version="1" minor-version="2">
<import>xproto</import>
<import>randr</import>
<import>xfixes</import>
@@ -51,6 +51,7 @@ OF THIS SOFTWARE.
<item name="Async"><bit>0</bit></item>
<item name="Copy"><bit>1</bit></item>
<item name="UST"><bit>2</bit></item>
<item name="Suboptimal"><bit>3</bit></item>
</enum>
<enum name="Capability">
@@ -69,6 +70,7 @@ OF THIS SOFTWARE.
<item name="Copy"><value>0</value></item>
<item name="Flip"><value>1</value></item>
<item name="Skip"><value>2</value></item>
<item name="SuboptimalCopy"><value>3</value></item>
</enum>
<struct name="Notify">

View File

@@ -27,7 +27,7 @@ authorization from the authors.
-->
<xcb header="randr" extension-xname="RANDR" extension-name="RandR"
major-version="1" minor-version="5">
major-version="1" minor-version="6">
<import>xproto</import>
<import>render</import>
@@ -37,6 +37,7 @@ authorization from the authors.
<xidtype name="CRTC" />
<xidtype name="OUTPUT" />
<xidtype name="PROVIDER" />
<xidtype name="LEASE" />
<!-- Errors -->
@@ -124,6 +125,7 @@ authorization from the authors.
<item name="ProviderChange"> <bit>4</bit></item>
<item name="ProviderProperty"><bit>5</bit></item>
<item name="ResourceChange"> <bit>6</bit></item>
<item name="Lease"> <bit>7</bit></item>
</enum>
<request name="SelectInput" opcode="4">
@@ -798,6 +800,7 @@ authorization from the authors.
<item name="ProviderChange"> <value>3</value></item>
<item name="ProviderProperty"><value>4</value></item>
<item name="ResourceChange"> <value>5</value></item>
<item name="Lease"> <value>6</value></item>
</enum>
<struct name="CrtcChange">
@@ -858,20 +861,6 @@ authorization from the authors.
<pad bytes="20" />
</struct>
<union name="NotifyData">
<field type="CrtcChange" name="cc" />
<field type="OutputChange" name="oc" />
<field type="OutputProperty" name="op" />
<field type="ProviderChange" name="pc" />
<field type="ProviderProperty" name="pp" />
<field type="ResourceChange" name="rc" />
</union>
<event name="Notify" number="1">
<field type="CARD8" name="subCode" enum="Notify" />
<field type="NotifyData" name="u" />
</event>
<!-- New in version 1.5 -->
<struct name="MonitorInfo">
@@ -914,4 +903,52 @@ authorization from the authors.
<field type="WINDOW" name="window" />
<field type="ATOM" name="name" />
</request>
<!-- new in 1.6 -->
<request name="CreateLease" opcode="45">
<field type="WINDOW" name="window" />
<field type="LEASE" name="lid" />
<field type="CARD16" name="num_crtcs" />
<field type="CARD16" name="num_outputs" />
<list type="CRTC" name="crtcs">
<fieldref>num_crtcs</fieldref>
</list>
<list type="OUTPUT" name="outputs">
<fieldref>num_outputs</fieldref>
</list>
<reply>
<field type="CARD8" name="nfd" />
<fd name="master_fd" />
<pad bytes="24" />
</reply>
</request>
<request name="FreeLease" opcode="46">
<field type="LEASE" name="lid" />
<field type="BYTE" name="terminate" />
</request>
<struct name="LeaseNotify">
<field type="TIMESTAMP" name="timestamp" />
<field type="WINDOW" name="window" />
<field type="LEASE" name="lease" />
<field type="CARD8" name="created" />
<pad bytes="15" />
</struct>
<union name="NotifyData">
<field type="CrtcChange" name="cc" />
<field type="OutputChange" name="oc" />
<field type="OutputProperty" name="op" />
<field type="ProviderChange" name="pc" />
<field type="ProviderProperty" name="pp" />
<field type="ResourceChange" name="rc" />
<field type="LeaseNotify" name="lc" />
</union>
<event name="Notify" number="1">
<field type="CARD8" name="subCode" enum="Notify" />
<field type="NotifyData" name="u" />
</event>
</xcb>

View File

@@ -55,7 +55,15 @@ authorization from the authors.
<field type="ClientIdSpec" name="spec" />
<field type="CARD32" name="length" />
<list type="CARD32" name="value">
<fieldref>length</fieldref>
<!-- The specification says that the length is in units of CARD32,
but the specification also says that the length is 4 when a
single LocalClientPid is present (ie. the length is in bytes).
The current server implementation sets the length to 4 when a
single CARD32 is present on the wire (length is in bytes). -->
<op op="/">
<fieldref>length</fieldref>
<value>4</value>
</op>
</list>
</struct>

View File

@@ -44,6 +44,15 @@ authorization from the authors.
<xsd:complexType>
<xsd:attribute name="bytes" type="xsd:integer" use="optional" />
<xsd:attribute name="align" type="xsd:integer" use="optional" />
<xsd:attribute name="serialize" type="xsd:boolean" use="optional" />
</xsd:complexType>
</xsd:element>
<!-- Alignment -->
<xsd:element name="required_start_align" >
<xsd:complexType>
<xsd:attribute name="align" type="xsd:integer" use="required" />
<xsd:attribute name="offset" type="xsd:integer" use="optional" />
</xsd:complexType>
</xsd:element>
@@ -76,14 +85,13 @@ authorization from the authors.
<xsd:sequence>
<!-- switch(expression) -->
<xsd:group ref="expression" minOccurs="1" maxOccurs="1" />
<xsd:element ref="required_start_align" minOccurs="0" maxOccurs="1" />
<xsd:choice>
<!-- bitcase expression - bit test -->
<xsd:element name="bitcase" type="caseexpr" minOccurs="0" maxOccurs="unbounded" />
<!-- case expression - value test -->
<xsd:element name="case" type="caseexpr" minOccurs="0" maxOccurs="unbounded" />
</xsd:choice>
<!-- default: -->
<xsd:group ref="fields" minOccurs="0" maxOccurs="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
@@ -201,6 +209,7 @@ authorization from the authors.
<xsd:element ref="field" />
<xsd:element ref="list" />
<xsd:element ref="fd" />
<xsd:element ref="required_start_align" />
</xsd:choice>
</xsd:group>
@@ -231,6 +240,22 @@ authorization from the authors.
<xsd:attribute name="ref" type="xsd:string" use="required" />
</xsd:complexType>
<!-- Type for a structure that is an event
which can be of an event type from a set of event types -->
<xsd:complexType name="eventstruct">
<xsd:sequence>
<xsd:element name="allowed">
<xsd:complexType>
<xsd:attribute name="extension" type="xsd:string" use="required" />
<xsd:attribute name="xge" type="xsd:boolean" use="required" />
<xsd:attribute name="opcode-min" type="xsd:integer" use="required" />
<xsd:attribute name="opcode-max" type="xsd:integer" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
<!-- Type for bit values -->
<xsd:simpleType name="bitType">
<xsd:restriction base="xsd:integer">
@@ -345,6 +370,7 @@ authorization from the authors.
<xsd:element name="errorcopy" type="packet-struct-copy" />
<xsd:element name="struct" type="struct" />
<xsd:element name="union" type="struct" />
<xsd:element name="eventstruct" type="eventstruct" />
<xsd:element name="xidtype">
<xsd:complexType>
<xsd:attribute name="name" type="xsd:string" use="required" />

View File

@@ -32,27 +32,6 @@ authorization from the authors.
http://cgit.freedesktop.org/xorg/proto/inputproto/tree/specs/XI2proto.txt
-->
<!-- TODO: Things which need to be done for full XInput support
but cannot be done now ( August 18, 2014 ) with the current feature-set
of the xml and the generator:
*****
replace "uninterpreted_data" or similar constructs
with a semantic that shows how to interpret this data.
This requires enhancements to the xml-schema and generator such as union with selector.
This will, e.g., be necessary for automatically generated byte-order conversion code,
which will, e.g., be necessary for server-side xcb.
This affects the following:
* SendExtensionEvent member "events"
*****
-->
<xcb header="xinput" extension-xname="XInputExtension" extension-name="Input"
major-version="2" minor-version="3">
<import>xfixes</import>
@@ -226,10 +205,11 @@ This affects the following:
</request>
<!-- OpenDevice -->
<typedef oldname="CARD8" newname="EventTypeBase" />
<struct name="InputClassInfo">
<field type="CARD8" name="class_id" enum="InputClass" />
<field type="CARD8" name="event_type_base" />
<field type="EventTypeBase" name="event_type_base" />
</struct>
<request name="OpenDevice" opcode="3">
@@ -986,25 +966,8 @@ This affects the following:
</reply>
</request>
<!-- SendExtensionEvent -->
<request name="SendExtensionEvent" opcode="31">
<field type="WINDOW" name="destination" />
<field type="CARD8" name="device_id" />
<field type="BOOL" name="propagate" />
<field type="CARD16" name="num_classes" />
<field type="CARD8" name="num_events" />
<pad bytes="3" />
<list type="CARD8" name="events">
<op op="*">
<fieldref>num_events</fieldref>
<value>32</value>
</op>
</list>
<list type="EventClass" name="classes">
<fieldref>num_classes</fieldref>
</list>
</request>
<!-- SendExtensionEvent (opcode 16) has to be defined after the events
because we do not support backward references -->
<!-- DeviceBell -->
@@ -2641,6 +2604,42 @@ This affects the following:
<eventcopy name="BarrierLeave" number="26" ref="BarrierHit" />
<!-- ⋅⋅⋅ Requests that depend on events ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ -->
<!-- SendExtensionEvent -->
<eventstruct name="EventForSend">
<allowed extension="Input" xge="false" opcode-min="0" opcode-max="16" />
<!-- We need not allow the newer events which are based on
the GenericEvent extension:
The wire-protocol-spec
https://cgit.freedesktop.org/xorg/lib/libXi/tree/specs/encoding.xml?idĺibXi-1.7.9#n1793
only allows fixed sized events, which seems
to rule out GenericEvent.
The xlib-implementation also assumes fixed-sized events.
https://cgit.freedesktop.org/xorg/lib/libXi/tree/src/XSndExEv.c?id=libXi-1.7.9#n106
The Xserver also allows only non-GE events:
https:g/xorg/xserver/tree/Xi/sendexev.c?id=xorg-server-1.19.1#n144
-->
</eventstruct>
<request name="SendExtensionEvent" opcode="31">
<field type="WINDOW" name="destination" />
<field type="CARD8" name="device_id" />
<field type="BOOL" name="propagate" />
<field type="CARD16" name="num_classes" />
<field type="CARD8" name="num_events" />
<pad bytes="3" />
<list type="EventForSend" name="events">
<fieldref>num_events</fieldref>
</list>
<list type="EventClass" name="classes">
<fieldref>num_classes</fieldref>
</list>
</request>
<!-- ⋅⋅⋅ Errors (v1.0) ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ -->
<error name="Device" number="0" />

View File

@@ -198,9 +198,11 @@ authorization from the authors.
<list type="char" name="authorization_protocol_name">
<fieldref>authorization_protocol_name_len</fieldref>
</list>
<pad align="4" />
<list type="char" name="authorization_protocol_data">
<fieldref>authorization_protocol_data_len</fieldref>
</list>
<pad align="4" />
</struct>
<struct name="SetupFailed">

View File

@@ -16,12 +16,12 @@ class Alignment(object):
return self.align == other.align and self.offset == other.offset
def __str__(self):
return "(align=%d, offset=%d)" % (self.align, self.offset)
return "(align=%d, offset=%d)" % (self.align, self.offset)
@staticmethod
def for_primitive_type(size):
# compute the required start_alignment based on the size of the type
if size % 8 == 0:
# compute the required start_alignment based on the size of the type
if size % 8 == 0:
# do 8-byte primitives require 8-byte alignment in X11?
return Alignment(8,0)
elif size % 4 == 0:
@@ -33,7 +33,7 @@ class Alignment(object):
def align_after_fixed_size(self, size):
new_offset = (self.offset + size) % self.align
new_offset = (self.offset + size) % self.align
return Alignment(self.align, new_offset)
@@ -41,7 +41,7 @@ class Alignment(object):
'''
Assuming the given external_align, checks whether
self is fulfilled for all cases.
Returns True if yes, False otherwise.
Returns True if yes, False otherwise.
'''
if self.align == 1 and self.offset == 0:
# alignment 1 with offset 0 is always fulfilled
@@ -55,9 +55,9 @@ class Alignment(object):
# the external align guarantees less alignment -> not guaranteed
return False
if external_align.align % self.align != 0:
if external_align.align % self.align != 0:
# the external align cannot be divided by our align
# -> not guaranteed
# -> not guaranteed
# (this can only happen if there are alignments that are not
# a power of 2, which is highly discouraged. But better be
# safe and check for it)
@@ -72,7 +72,7 @@ class Alignment(object):
def combine_with(self, other):
# returns the alignment that is guaranteed when
# both, self or other, can happen
# both, self or other, can happen
new_align = gcd(self.align, other.align)
new_offset_candidate1 = self.offset % new_align
new_offset_candidate2 = other.offset % new_align
@@ -83,8 +83,8 @@ class Alignment(object):
new_align = gcd(new_align, offset_diff)
new_offset_candidate1 = self.offset % new_align
new_offset_candidate2 = other.offset % new_align
assert new_offset_candidate1 == new_offset_candidate2
new_offset = new_offset_candidate1
assert new_offset_candidate1 == new_offset_candidate2
new_offset = new_offset_candidate1
# return the result
return Alignment(new_align, new_offset)
@@ -92,44 +92,44 @@ class Alignment(object):
class AlignmentLog(object):
def __init__(self):
self.ok_list = []
self.fail_list = []
self.verbosity = 1
self.ok_list = []
self.fail_list = []
self.verbosity = 1
def __str__(self):
result = ""
result = ""
# output the OK-list
for (align_before, field_name, type_obj, callstack, align_after) in self.ok_list:
stacksize = len(callstack)
# output the OK-list
for (align_before, field_name, type_obj, callstack, align_after) in self.ok_list:
stacksize = len(callstack)
indent = ' ' * stacksize
if self.ok_callstack_is_relevant(callstack):
if self.ok_callstack_is_relevant(callstack):
if field_name is None or field_name == "":
result += (" %sok: %s:\n\t%sbefore: %s, after: %s\n"
% (indent, str(type_obj), indent, str(align_before), str(align_after)))
else:
result += (" %sok: field \"%s\" in %s:\n\t%sbefore: %s, after: %s\n"
% (indent, str(field_name), str(type_obj),
indent, str(align_before), str(align_after)))
result += (" %sok: %s:\n\t%sbefore: %s, after: %s\n"
% (indent, str(type_obj), indent, str(align_before), str(align_after)))
else:
result += (" %sok: field \"%s\" in %s:\n\t%sbefore: %s, after: %s\n"
% (indent, str(field_name), str(type_obj),
indent, str(align_before), str(align_after)))
if self.verbosity >= 1:
result += self.callstack_to_str(indent, callstack)
result += self.callstack_to_str(indent, callstack)
# output the fail-list
for (align_before, field_name, type_obj, callstack, reason) in self.fail_list:
stacksize = len(callstack)
# output the fail-list
for (align_before, field_name, type_obj, callstack, reason) in self.fail_list:
stacksize = len(callstack)
indent = ' ' * stacksize
if field_name is None or field_name == "":
result += (" %sfail: align %s is incompatible with\n\t%s%s\n\t%sReason: %s\n"
% (indent, str(align_before), indent, str(type_obj), indent, reason))
else:
result += (" %sfail: align %s is incompatible with\n\t%sfield \"%s\" in %s\n\t%sReason: %s\n"
% (indent, str(align_before), indent, str(field_name), str(type_obj), indent, reason))
if field_name is None or field_name == "":
result += (" %sfail: align %s is incompatible with\n\t%s%s\n\t%sReason: %s\n"
% (indent, str(align_before), indent, str(type_obj), indent, reason))
else:
result += (" %sfail: align %s is incompatible with\n\t%sfield \"%s\" in %s\n\t%sReason: %s\n"
% (indent, str(align_before), indent, str(field_name), str(type_obj), indent, reason))
if self.verbosity >= 1:
result += self.callstack_to_str(indent, callstack)
result += self.callstack_to_str(indent, callstack)
return result
return result
def callstack_to_str(self, indent, callstack):
@@ -137,41 +137,41 @@ class AlignmentLog(object):
for stack_elem in callstack:
result += "\t %s%s\n" % (indent, str(stack_elem))
result += "\t%s]\n" % indent
return result
return result
def ok_callstack_is_relevant(self, ok_callstack):
# determine whether an ok callstack is relevant for logging
if self.verbosity >= 2:
return True
# empty callstacks are always relevant
if len(ok_callstack) == 0:
if self.verbosity >= 2:
return True
# check whether the ok_callstack is a subset or equal to a fail_callstack
# empty callstacks are always relevant
if len(ok_callstack) == 0:
return True
# check whether the ok_callstack is a subset or equal to a fail_callstack
for (align_before, field_name, type_obj, fail_callstack, reason) in self.fail_list:
if len(ok_callstack) <= len(fail_callstack):
zipped = zip(ok_callstack, fail_callstack[:len(ok_callstack)])
is_subset = all([i == j for i, j in zipped])
if is_subset:
is_subset = all([i == j for i, j in zipped])
if is_subset:
return True
return False
def ok(self, align_before, field_name, type_obj, callstack, align_after):
self.ok_list.append((align_before, field_name, type_obj, callstack, align_after))
self.ok_list.append((align_before, field_name, type_obj, callstack, align_after))
def fail(self, align_before, field_name, type_obj, callstack, reason):
self.fail_list.append((align_before, field_name, type_obj, callstack, reason))
self.fail_list.append((align_before, field_name, type_obj, callstack, reason))
def append(self, other):
self.ok_list.extend(other.ok_list)
self.fail_list.extend(other.fail_list)
self.ok_list.extend(other.ok_list)
self.fail_list.extend(other.fail_list)
def ok_count(self):
return len(self.ok_list)
return len(self.ok_list)

View File

@@ -169,6 +169,7 @@ class Expression(object):
else:
self.lenfield_parent = p
self.lenfield_type = fields[self.lenfield_name].field_type
self.lenfield = fields[self.lenfield_name]
break
self.recursive_resolve_tasks(module, parents)

View File

@@ -57,6 +57,12 @@ def struct(node, module, namespace):
type = Struct(name, node)
module.add_type(id, namespace.ns, name, type)
def eventstruct(node, module, namespace):
id = node.get('name')
name = namespace.prefix + (id,)
type = EventStruct(name, node)
module.add_type(id, namespace.ns, name, type)
def union(node, module, namespace):
id = node.get('name')
name = namespace.prefix + (id,)
@@ -103,6 +109,7 @@ funcs = {'import' : import_,
'xidunion' : xidunion,
'enum' : enum,
'struct' : struct,
'eventstruct' : eventstruct,
'union' : union,
'request' : request,
'event' : event,

View File

@@ -32,6 +32,9 @@ class Namespace(object):
self.root = parse(filename).getroot()
self.header = self.root.get('header')
self.ns = self.header + ':'
# Events
self.events = {}
# Get root element attributes
if self.root.get('extension-xname', False):
@@ -46,6 +49,17 @@ class Namespace(object):
self.ext_name = ''
self.prefix = ('xcb',)
def add_event(self, id, name, item):
self.events[id] = (name, item)
def get_event_by_opcode(self, opcode, is_ge_event):
for id, (name, event) in self.events.items():
if event.is_ge_event == is_ge_event:
opcode_specific_name = event.get_name_for_opcode( opcode )
if opcode_specific_name is not None:
return (opcode_specific_name, event)
return None
class Module(object):
'''
@@ -72,6 +86,11 @@ class Module(object):
self.errors = {}
self.all = []
# dict of namespaces by ext_name
self.namespaces = {}
# enter the main namespace here
self.namespaces[self.namespace.ext_name] = self.namespace
# Register some common types
self.add_type('CARD8', '', ('uint8_t',), tcard8)
self.add_type('CARD16', '', ('uint16_t',), tcard16)
@@ -94,6 +113,7 @@ class Module(object):
# Recursively resolve all types
def resolve(self):
self.add_events_to_namespaces()
for (name, item) in self.all:
self.pads = 0
item.resolve(self)
@@ -112,6 +132,7 @@ class Module(object):
if self.import_level == 0:
self.direct_imports.append((name, namespace.header))
self.imports.append((name, namespace.header))
self.namespaces[namespace.ext_name] = namespace
def has_import(self, name):
for (name_, header) in self.imports:
@@ -149,6 +170,9 @@ class Module(object):
def get_type_name(self, id):
return self.get_type_impl(id, 0)
def get_namespace(self, ext_name):
return self.namespaces[ext_name]
# Keeps track of request datatypes
def add_request(self, id, name, item):
if name[:-1] == self.namespace.prefix:
@@ -160,6 +184,23 @@ class Module(object):
if name[:-1] == self.namespace.prefix:
self.all.append((name, item))
def add_events_to_namespaces(self):
# add to its namespace object
for id, (name,item) in self.events.items():
if name[:-1] == ('xcb',):
# core event
namespace_name = ''
else:
# extension event
namespace_name = name[-2]
namespace = self.namespaces[namespace_name]
if namespace is not None:
namespace.add_event(id, name, item)
def get_event(self, id):
return self.events[id][1]

View File

@@ -36,10 +36,13 @@ class Type(object):
self.is_reply = False
self.is_union = False
self.is_pad = False
self.is_eventstruct = False
self.is_event = False
self.is_switch = False
self.is_case_or_bitcase = False
self.is_bitcase = False
self.is_case = False
self.is_fd = False
self.required_start_align = Alignment()
# the biggest align value of an align-pad contained in this type
@@ -66,7 +69,7 @@ class Type(object):
'''
raise Exception('abstract fixed_size method not overridden!')
def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto, enum=None):
def make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto, enum=None, is_fd=False):
'''
Default method for making a data type a member of a structure.
Extend this if the data type needs to add an additional length field or something.
@@ -75,7 +78,7 @@ class Type(object):
complex_type is the structure object.
see Field for the meaning of the other parameters.
'''
new_field = Field(self, field_type, field_name, visible, wire, auto, enum)
new_field = Field(self, field_type, field_name, visible, wire, auto, enum, is_fd)
# We dump the _placeholder_byte if any fields are added.
for (idx, field) in enumerate(complex_type.fields):
@@ -215,6 +218,18 @@ tchar = SimpleType(('char',), 1)
tfloat = SimpleType(('float',), 4)
tdouble = SimpleType(('double',), 8)
class FileDescriptor(SimpleType):
'''
Derived class which represents a file descriptor.
'''
def __init__(self):
SimpleType.__init__(self, ('int'), 4)
self.is_fd = True
def fixed_size(self):
return True
out = __main__.output['simple']
class Enum(SimpleType):
'''
@@ -308,7 +323,9 @@ class ListType(Type):
type.make_member_of(module, complex_type, lenfield_type, lenfield_name, True, lenwire, False, enum)
# Add ourself to the structure by calling our original method.
Type.make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto, enum)
if self.member.is_fd:
wire = False
Type.make_member_of(self, module, complex_type, field_type, field_name, visible, wire, auto, enum, self.member.is_fd)
def resolve(self, module):
if self.resolved:
@@ -501,7 +518,7 @@ class ComplexType(Type):
int(required_start_align_element.get('align', "4"), 0),
int(required_start_align_element.get('offset', "0"), 0))
if verbose_align_log:
print "Explicit start-align for %s: %s\n" % (self, self.required_start_align)
print ("Explicit start-align for %s: %s\n" % (self, self.required_start_align))
def resolve(self, module):
if self.resolved:
@@ -530,7 +547,12 @@ class ComplexType(Type):
elif child.tag == 'list':
field_name = child.get('name')
fkey = child.get('type')
type = ListType(child, module.get_type(fkey), *self.lenfield_parent)
if fkey == 'fd':
ftype = FileDescriptor()
fkey = 'INT32'
else:
ftype = module.get_type(fkey)
type = ListType(child, ftype, *self.lenfield_parent)
visible = True
elif child.tag == 'switch':
field_name = child.get('name')
@@ -592,7 +614,7 @@ class ComplexType(Type):
if verbose_align_log:
print ("calc_required_start_align: %s has start-align %s"
% (str(self), str(self.required_start_align)))
print "Details:\n" + str(log)
print ("Details:\n" + str(log))
if self.required_start_align.offset != 0:
print (("WARNING: %s\n\thas start-align with non-zero offset: %s"
+ "\n\tsuggest to add explicit definition with:"
@@ -619,12 +641,12 @@ class ComplexType(Type):
for offset in range(0,align):
align_candidate = Alignment(align, offset)
if verbose_align_log:
print "trying %s for %s" % (str(align_candidate), str(self))
print ("trying %s for %s" % (str(align_candidate), str(self)))
my_log = AlignmentLog()
if self.is_possible_start_align(align_candidate, callstack, my_log):
log.append(my_log)
if verbose_align_log:
print "found start-align %s for %s" % (str(align_candidate), str(self))
print ("found start-align %s for %s" % (str(align_candidate), str(self)))
return align_candidate
else:
my_ok_count = my_log.ok_count()
@@ -641,7 +663,7 @@ class ComplexType(Type):
# none of the candidates applies
# this type has illegal internal aligns for all possible start_aligns
if verbose_align_log:
print "didn't find start-align for %s" % str(self)
print ("didn't find start-align for %s" % str(self))
log.append(best_log)
return None
@@ -900,7 +922,7 @@ class SwitchType(ComplexType):
# aux function for unchecked_get_alignment_after
def get_align_for_selected_case_field(self, case_field, start_align, callstack, log):
if verbose_align_log:
print "get_align_for_selected_case_field: %s, case_field = %s" % (str(self), str(case_field))
print ("get_align_for_selected_case_field: %s, case_field = %s" % (str(self), str(case_field)))
total_align = start_align
for field in self.bitcases:
my_callstack = callstack[:]
@@ -1164,6 +1186,82 @@ class Request(ComplexType):
out = __main__.output['request']
class EventStructAllowedRule:
def __init__(self, parent, elt):
self.elt = elt
self.extension = elt.get('extension')
self.ge_events = elt.get('xge') == "true"
self.min_opcode = int( elt.get('opcode-min') )
self.max_opcode = int( elt.get('opcode-max') )
def resolve(self, parent, module):
# get the namespace of the specified extension
extension_namespace = module.get_namespace( self.extension )
if extension_namespace is None:
raise Exception( "EventStructAllowedRule.resolve: cannot find extension \"" + self.extension + "\"" )
return
# find and add the selected events
for opcode in range(self.min_opcode, self.max_opcode):
name_and_event = extension_namespace.get_event_by_opcode( opcode, self.ge_events )
if name_and_event is None:
# could not find event -> error handling
if self.ge_events:
raise Exception("EventStructAllowedRule.resolve: cannot find xge-event with opcode " + str(opcode) + " in extension " + self.extension )
else:
raise Exception("EventStructAllowedRule.resolve: cannot find oldstyle-event with opcode " + str(opcode) + " in extension " + self.extension )
return
( name, event ) = name_and_event
# add event to EventStruct
parent.add_event( module, self.extension, opcode, name, event )
class EventStruct(Union):
'''
Derived class representing an event-use-as-struct data type.
'''
def __init__(self, name, elt):
Union.__init__(self, name, elt)
self.is_eventstruct = True
self.events = []
self.allowedRules = []
self.contains_ge_events = False
for item in list(elt):
if item.tag == 'allowed':
allowedRule = EventStructAllowedRule(self, item)
self.allowedRules.append( allowedRule )
if allowedRule.ge_events:
self.contains_ge_events = True
out = __main__.output['eventstruct']
def resolve(self, module):
if self.resolved:
return
for allowedRule in self.allowedRules:
allowedRule.resolve(self, module)
Union.resolve(self,module)
self.resolved = True
# add event. called by resolve
def add_event(self, module, extension, opcode, name, event_type ):
self.events.append( (extension, opcode, name, event_type) )
# Add the field to ourself
event_type.make_member_of(module, self, name, name[-1], True, True, False)
# Recursively resolve the event (could be another structure, list)
event_type.resolve(module)
def fixed_size(self):
is_fixed_size = True
for extension, opcode, name, event in self.events:
if not event.fixed_size():
is_fixed_size = False
return is_fixed_size
class Event(ComplexType):
'''
Derived class representing an event data type.
@@ -1183,6 +1281,8 @@ class Event(ComplexType):
self.is_ge_event = bool(elt.get('xge'))
self.is_event = True
self.doc = None
for item in list(elt):
if item.tag == 'doc':
@@ -1193,6 +1293,13 @@ class Event(ComplexType):
if main:
self.name = name
def get_name_for_opcode(self, opcode):
for name, my_opcode in self.opcodes.items():
if int(my_opcode) == opcode:
return name
else:
return None
def resolve(self, module):
def add_event_header():
self.fields.append(Field(tcard8, tcard8.name, 'response_type', False, True, True))