summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2018-09-11 19:31:12 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2018-09-11 19:31:12 +0000
commit26e88f304a40144b9cc2579824a419bd96418454 (patch)
tree1d90c1b2c88f0116a7b4b93ce5a5d039e331887f
parent667f20ac8083e400aafc6d1e5ba43b642ef4d290 (diff)
Update to xcb-proto 1.13. ok tb@
-rw-r--r--proto/xcb-proto/NEWS11
-rw-r--r--proto/xcb-proto/configure.ac2
-rw-r--r--proto/xcb-proto/doc/xml-xcb.txt29
-rw-r--r--proto/xcb-proto/py-compile6
-rw-r--r--proto/xcb-proto/src/dri3.xml71
-rw-r--r--proto/xcb-proto/src/present.xml4
-rw-r--r--proto/xcb-proto/src/randr.xml67
-rw-r--r--proto/xcb-proto/src/res.xml10
-rw-r--r--proto/xcb-proto/src/xcb.xsd30
-rw-r--r--proto/xcb-proto/src/xinput.xml81
-rw-r--r--proto/xcb-proto/src/xproto.xml2
-rw-r--r--proto/xcb-proto/xcbgen/align.py96
-rw-r--r--proto/xcb-proto/xcbgen/expr.py1
-rw-r--r--proto/xcb-proto/xcbgen/matcher.py7
-rw-r--r--proto/xcb-proto/xcbgen/state.py41
-rw-r--r--proto/xcb-proto/xcbgen/xtypes.py127
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))