Stefan Dirsch
852073b9aa
- U_add-support-for-eventstruct.patch * Update xinput to the state when it was enabled by default upstream. - Update xinput to the state when it was enabled by default upstream. (bnc#1074249) * U_SendExtensionEvent-uses-eventstruct.patch * U_add-support-for-eventstruct.patch * U_xinput-typedef-for-event_type_base.patch OBS-URL: https://build.opensuse.org/package/show/X11:XOrg/xcb-proto?expand=0&rev=23
344 lines
12 KiB
Diff
344 lines
12 KiB
Diff
From 4aa40fbd5e05833b72327ea37421b09dff246732 Mon Sep 17 00:00:00 2001
|
|
From: Christian Linhart <chris@demorecorder.com>
|
|
Date: Wed, 25 Jan 2017 10:31:18 +0100
|
|
Subject: [PATCH] add support for eventstruct
|
|
|
|
eventstruct is a new xml element that allows to use events
|
|
as part of requests.
|
|
|
|
This is, e.g., needed by the SendExtensionEvent request
|
|
of the XINPUT extension.
|
|
|
|
Signed-off-by: Christian Linhart <chris@demorecorder.com>
|
|
---
|
|
doc/xml-xcb.txt | 29 +++++++++++++++++++
|
|
src/xcb.xsd | 17 +++++++++++
|
|
xcbgen/matcher.py | 7 +++++
|
|
xcbgen/state.py | 41 ++++++++++++++++++++++++++
|
|
xcbgen/xtypes.py | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
5 files changed, 181 insertions(+)
|
|
|
|
diff --git a/doc/xml-xcb.txt b/doc/xml-xcb.txt
|
|
index 9cef1de..f5b9aed 100644
|
|
--- a/doc/xml-xcb.txt
|
|
+++ b/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/src/xcb.xsd b/src/xcb.xsd
|
|
index f0c5f44..dc3d7cc 100644
|
|
--- a/src/xcb.xsd
|
|
+++ b/src/xcb.xsd
|
|
@@ -240,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">
|
|
@@ -354,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/xcbgen/matcher.py b/xcbgen/matcher.py
|
|
index bfa315e..97a8b43 100644
|
|
--- a/xcbgen/matcher.py
|
|
+++ b/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/xcbgen/state.py b/xcbgen/state.py
|
|
index a6ad3a1..a8346bb 100644
|
|
--- a/xcbgen/state.py
|
|
+++ b/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/xcbgen/xtypes.py b/xcbgen/xtypes.py
|
|
index b83b119..c1f5986 100644
|
|
--- a/xcbgen/xtypes.py
|
|
+++ b/xcbgen/xtypes.py
|
|
@@ -36,6 +36,8 @@ 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
|
|
@@ -1164,6 +1166,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 +1261,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 +1273,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))
|
|
--
|
|
2.13.6
|
|
|