diff options
author | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2018-09-11 19:31:12 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2018-09-11 19:31:12 +0000 |
commit | 26e88f304a40144b9cc2579824a419bd96418454 (patch) | |
tree | 1d90c1b2c88f0116a7b4b93ce5a5d039e331887f | |
parent | 667f20ac8083e400aafc6d1e5ba43b642ef4d290 (diff) |
Update to xcb-proto 1.13. ok tb@
-rw-r--r-- | proto/xcb-proto/NEWS | 11 | ||||
-rw-r--r-- | proto/xcb-proto/configure.ac | 2 | ||||
-rw-r--r-- | proto/xcb-proto/doc/xml-xcb.txt | 29 | ||||
-rw-r--r-- | proto/xcb-proto/py-compile | 6 | ||||
-rw-r--r-- | proto/xcb-proto/src/dri3.xml | 71 | ||||
-rw-r--r-- | proto/xcb-proto/src/present.xml | 4 | ||||
-rw-r--r-- | proto/xcb-proto/src/randr.xml | 67 | ||||
-rw-r--r-- | proto/xcb-proto/src/res.xml | 10 | ||||
-rw-r--r-- | proto/xcb-proto/src/xcb.xsd | 30 | ||||
-rw-r--r-- | proto/xcb-proto/src/xinput.xml | 81 | ||||
-rw-r--r-- | proto/xcb-proto/src/xproto.xml | 2 | ||||
-rw-r--r-- | proto/xcb-proto/xcbgen/align.py | 96 | ||||
-rw-r--r-- | proto/xcb-proto/xcbgen/expr.py | 1 | ||||
-rw-r--r-- | proto/xcb-proto/xcbgen/matcher.py | 7 | ||||
-rw-r--r-- | proto/xcb-proto/xcbgen/state.py | 41 | ||||
-rw-r--r-- | proto/xcb-proto/xcbgen/xtypes.py | 127 |
16 files changed, 462 insertions, 123 deletions
diff --git a/proto/xcb-proto/NEWS b/proto/xcb-proto/NEWS index caf1ffad4..efae961ab 100644 --- a/proto/xcb-proto/NEWS +++ b/proto/xcb-proto/NEWS @@ -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 diff --git a/proto/xcb-proto/configure.ac b/proto/xcb-proto/configure.ac index 540a8dd17..88b3439c9 100644 --- a/proto/xcb-proto/configure.ac +++ b/proto/xcb-proto/configure.ac @@ -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]) diff --git a/proto/xcb-proto/doc/xml-xcb.txt b/proto/xcb-proto/doc/xml-xcb.txt index 9cef1de11..f5b9aed13 100644 --- a/proto/xcb-proto/doc/xml-xcb.txt +++ b/proto/xcb-proto/doc/xml-xcb.txt @@ -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 ------------- diff --git a/proto/xcb-proto/py-compile b/proto/xcb-proto/py-compile index bc2039140..3693d96b0 100644 --- a/proto/xcb-proto/py-compile +++ b/proto/xcb-proto/py-compile @@ -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: diff --git a/proto/xcb-proto/src/dri3.xml b/proto/xcb-proto/src/dri3.xml index 608af3157..895d12a53 100644 --- a/proto/xcb-proto/src/dri3.xml +++ b/proto/xcb-proto/src/dri3.xml @@ -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> diff --git a/proto/xcb-proto/src/present.xml b/proto/xcb-proto/src/present.xml index a648ad77c..fb06e73f0 100644 --- a/proto/xcb-proto/src/present.xml +++ b/proto/xcb-proto/src/present.xml @@ -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"> diff --git a/proto/xcb-proto/src/randr.xml b/proto/xcb-proto/src/randr.xml index 722f715bf..703d6ba25 100644 --- a/proto/xcb-proto/src/randr.xml +++ b/proto/xcb-proto/src/randr.xml @@ -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> diff --git a/proto/xcb-proto/src/res.xml b/proto/xcb-proto/src/res.xml index 17e6f833d..be32ca18b 100644 --- a/proto/xcb-proto/src/res.xml +++ b/proto/xcb-proto/src/res.xml @@ -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> diff --git a/proto/xcb-proto/src/xcb.xsd b/proto/xcb-proto/src/xcb.xsd index c1dce3e1e..dc3d7cc18 100644 --- a/proto/xcb-proto/src/xcb.xsd +++ b/proto/xcb-proto/src/xcb.xsd @@ -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" /> diff --git a/proto/xcb-proto/src/xinput.xml b/proto/xcb-proto/src/xinput.xml index 94855bac8..5f88a9857 100644 --- a/proto/xcb-proto/src/xinput.xml +++ b/proto/xcb-proto/src/xinput.xml @@ -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" /> diff --git a/proto/xcb-proto/src/xproto.xml b/proto/xcb-proto/src/xproto.xml index 437dc30af..dea48dfed 100644 --- a/proto/xcb-proto/src/xproto.xml +++ b/proto/xcb-proto/src/xproto.xml @@ -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"> diff --git a/proto/xcb-proto/xcbgen/align.py b/proto/xcb-proto/xcbgen/align.py index 5e3183801..d4c12ee40 100644 --- a/proto/xcb-proto/xcbgen/align.py +++ b/proto/xcb-proto/xcbgen/align.py @@ -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 + if self.verbosity >= 2: + return True # empty callstacks are always relevant - if len(ok_callstack) == 0: + if len(ok_callstack) == 0: return True - # check whether the ok_callstack is a subset or equal to a fail_callstack + # 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) diff --git a/proto/xcb-proto/xcbgen/expr.py b/proto/xcb-proto/xcbgen/expr.py index a716d3443..bf46c6360 100644 --- a/proto/xcb-proto/xcbgen/expr.py +++ b/proto/xcb-proto/xcbgen/expr.py @@ -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) diff --git a/proto/xcb-proto/xcbgen/matcher.py b/proto/xcb-proto/xcbgen/matcher.py index bfa315eb5..97a8b43bb 100644 --- a/proto/xcb-proto/xcbgen/matcher.py +++ b/proto/xcb-proto/xcbgen/matcher.py @@ -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, diff --git a/proto/xcb-proto/xcbgen/state.py b/proto/xcb-proto/xcbgen/state.py index a6ad3a11e..a8346bb20 100644 --- a/proto/xcb-proto/xcbgen/state.py +++ b/proto/xcb-proto/xcbgen/state.py @@ -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] diff --git a/proto/xcb-proto/xcbgen/xtypes.py b/proto/xcb-proto/xcbgen/xtypes.py index c3b57583d..1e270ae61 100644 --- a/proto/xcb-proto/xcbgen/xtypes.py +++ b/proto/xcb-proto/xcbgen/xtypes.py @@ -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)) |