From f1c2db43dcf35d2cf4715390bd2391c28e42a8c2 Mon Sep 17 00:00:00 2001 From: marha Date: Sun, 22 Feb 2015 14:31:16 +0100 Subject: xwininfo fontconfig libX11 libXdmcp libfontenc libxcb libxcb/xcb-proto mesalib xserver xkeyboard-config mkfontscale git update 22 Feb 2015 xserver commit 3a06faf3fcdb7451125a46181f9152e8e59e9770 libxcb commit e3ec1f74637237ce500dfd0ca59f2e422da4e019 libxcb/xcb-proto commit 4c550465934164aab2449a125f75f4ca07816233 xkeyboard-config commit 26f344c93f8c6141e9233eb68088ba4fd56bc9ef libX11 commit c8e19b393defd53f046ddc2da3a16881221b3c34 libXdmcp commit 9f4cac7656b221ce2a8f97e7bd31e5e23126d001 libfontenc commit de1843aaf76015c9d99416f3122d169fe331b849 mkfontscale commit 87d628f8eec170ec13bb9feefb1ce05aed07d1d6 xwininfo commit 0c49f8f2bd56b1e77721e81030ea948386dcdf4e fontconfig commit d6d5adeb7940c0d0beb86489c2a1c2ce59e5c044 mesa commit 4359954d842caa2a9f8d4b50d70ecc789884b68b --- libxcb/src/c_client.py | 444 +++++++++++++++++++++++++---- libxcb/xcb-proto/doc/xml-xcb.txt | 33 +++ libxcb/xcb-proto/src/present.xml | 10 +- libxcb/xcb-proto/src/render.xml | 118 +++++++- libxcb/xcb-proto/src/screensaver.xml | 68 ++++- libxcb/xcb-proto/src/xcb.xsd | 24 +- libxcb/xcb-proto/src/xfixes.xml | 2 +- libxcb/xcb-proto/src/xinput.xml | 527 +++++++++++++++++++++++++---------- libxcb/xcb-proto/src/xprint.xml | 13 +- libxcb/xcb-proto/src/xproto.xml | 414 +++++++++++++++++++++++++-- libxcb/xcb-proto/xcbgen/expr.py | 31 ++- libxcb/xcb-proto/xcbgen/xtypes.py | 8 +- 12 files changed, 1427 insertions(+), 265 deletions(-) (limited to 'libxcb') diff --git a/libxcb/src/c_client.py b/libxcb/src/c_client.py index 56a176608..8a2900c62 100644 --- a/libxcb/src/c_client.py +++ b/libxcb/src/c_client.py @@ -58,6 +58,107 @@ def _hc(fmt, *args): _h(fmt, *args) _c(fmt, *args) +def _c_wr_stringlist(indent, strlist): + ''' + Writes the given list of strings to the source file. + Each line is prepended by the indent string + ''' + for str in strlist: + _c("%s%s", indent, str) + + +class PreCode(object): + ''' + For pre-code generated by expression generation + (for example, the for-loop of a sumof) + This has to account for recursiveness of the expression + generation, i.e., there may be pre-code for pre-code. + Therefore this is implemented as a stack of lists of lines. + + If redirection is switched on, then all output is collected in + self.redirect_code and self.redirect_tempvars instead of + being sent to the output via _h und _c. + ''' + def __init__(self): + self.nesting_level = 0 + self.tempvars = [] + self.codelines = [] + self.redirect_code = None + self.redirect_tempvars = None + self.indent_str = ' ' + self.indent_stack = [] + self.tempvar_num = 0 + + + # start and end of pre-code blocks + def start(self): + self.nesting_level += 1 + + def end(self): + self.nesting_level -= 1 + if self.nesting_level == 0: + # lowest pre-code level is finished -> output to source + if self.redirect_tempvars is None: + _c_wr_stringlist('', self.tempvars) + self.tempvars = [] + else: + self.redirect_tempvars.extend(self.tempvars) + self.tempvars = [] + if self.redirect_code == None: + _c_wr_stringlist('', self.codelines) + self.codelines = [] + else: + self.redirect_code.extend(self.codelines) + self.codelines = [] + + + def output_tempvars(self): + if self.redirect_code == None: + _c_wr_stringlist('', self.tempvars) + self.tempvars = [] + + # output to precode + def code(self, fmt, *args): + self.codelines.append(self.indent_str + fmt % args) + + def tempvar(self, fmt, *args): + self.tempvars.append(' ' + (fmt % args)) + + # get a unique name for a temporary variable + def get_tempvarname(self): + self.tempvar_num += 1 + return "xcb_pre_tmp_%d" % self.tempvar_num + + # indentation + + def push_indent(self, indentstr): + self.indent_stack.append(self.indent_str) + self.indent_str = indentstr + + def push_addindent(self, indent_add_str): + self.push_indent(self.indent_str + indent_add_str) + + def indent(self): + self.push_addindent(' ') + + def pop_indent(self): + self.indent_str = self.indent_stack.pop() + + # redirection to lists + def redirect_start(self, redirect_code, redirect_tempvars=None): + self.redirect_code = redirect_code + self.redirect_tempvars = redirect_tempvars + if redirect_tempvars is not None: + self.tempvar_num = 0 + + def redirect_end(self): + self.redirect_code = None + self.redirect_tempvars = None + +# global PreCode handler +_c_pre = PreCode() + + # XXX See if this level thing is really necessary. def _h_setlevel(idx): ''' @@ -336,12 +437,6 @@ def _c_type_setup(self, name, postfix): first_field_after_varsized = None for field in self.fields: - _c_type_setup(field.type, field.field_type, ()) - if field.type.is_list: - _c_type_setup(field.type.member, field.field_type, ()) - if (field.type.nmemb is None): - self.c_need_sizeof = True - field.c_field_type = _t(field.field_type) field.c_field_const_type = ('' if field.type.nmemb == 1 else 'const ') + field.c_field_type field.c_field_name = _cpp(field.field_name) @@ -391,6 +486,15 @@ def _c_type_setup(self, name, postfix): if field.type.fixed_size(): field.prev_varsized_field = None + # recurse into this field this has to be done here, i.e., + # after the field has been set up. Otherwise the function + # _c_helper_fieldaccess_expr will produce garbage or crash + _c_type_setup(field.type, field.field_type, ()) + if field.type.is_list: + _c_type_setup(field.type.member, field.field_type, ()) + if (field.type.nmemb is None): + self.c_need_sizeof = True + if self.c_need_serialize: # when _unserialize() is wanted, create _sizeof() as well for consistency reasons self.c_need_sizeof = True @@ -427,23 +531,64 @@ def _c_type_setup(self, name, postfix): _c_serialize('sizeof', self) # _c_type_setup() -def _c_helper_absolute_name(prefix, field=None): +# Functions for querying field properties +def _c_field_needs_list_accessor(field): + return field.type.is_list and not field.type.fixed_size() + +def _c_field_needs_field_accessor(field): + if field.type.is_list: + return False + else: + return (field.prev_varsized_field is not None or + not field.type.fixed_size()) + +def _c_field_needs_accessor(field): + return (_c_field_needs_list_accessor(field) or + _c_field_needs_field_accessor(field)) + +def _c_field_is_member_of_case_or_bitcase(field): + return field.parent and field.parent.is_case_or_bitcase + +def _c_helper_fieldaccess_expr(prefix, field=None): """ turn prefix, which is a list of tuples (name, separator, Type obj) into a string - representing a valid name in C (based on the context) - if field is not None, append the field name as well + representing a valid field-access-expression in C (based on the context) + if field is not None, append access to the field as well. + + "separator" is one of the C-operators "." or "->". + + A field access expression can consist of the following components: + * struct/union member access from a value with the "."-operator + * struct/union member access from a pointer with "->"-operator + * function-call of an accessor function: + This is used when a xcb-field is not contained in a struct. + This can, e.g., happen for fields after var-sized fields, etc. """ prefix_str = '' + last_sep ='' for name, sep, obj in prefix: - prefix_str += name - if '' == sep: - sep = '->' - if ((obj.is_case_or_bitcase and obj.has_name) or # named bitcase - (obj.is_switch and len(obj.parents)>1)): - sep = '.' - prefix_str += sep - if field is not None: - prefix_str += _cpp(field.field_name) + prefix_str += last_sep + name + last_sep = sep + + if field is None: + # add separator for access to a yet unknown field + prefix_str += last_sep + else: + if _c_field_needs_accessor(field): + if _c_field_is_member_of_case_or_bitcase(field): + # case members are available in the deserialized struct, + # so there is no need to use the accessor function + # (also, their accessor function needs a different arglist + # so this would require special treatment here) + # Therefore: Access as struct member + prefix_str += last_sep + _cpp(field.field_name) + else: + # Access with the accessor function + prefix_str = field.c_accessor_name + "(" + prefix_str + ")" + else: + # Access as struct member + prefix_str += last_sep + _cpp(field.field_name) + return prefix_str # _c_absolute_name @@ -465,7 +610,7 @@ def _c_helper_field_mapping(complex_type, prefix, flat=False): all_fields.update(_c_helper_field_mapping(b.type, bitcase_prefix, flat)) else: for f in complex_type.fields: - fname = _c_helper_absolute_name(prefix, f) + fname = _c_helper_fieldaccess_expr(prefix, f) if f.field_name in all_fields: raise Exception("field name %s has been registered before" % f.field_name) @@ -578,6 +723,31 @@ def resolve_expr_fields(complex_obj): return unresolved # resolve_expr_fields() +def resolve_expr_fields_list(self, parents): + """ + Find expr fields appearing in a list and descendents + that cannot be resolved within the parents of the list. + These are normally fields that need to be given as function parameters + for length and iterator functions. + """ + all_fields = [] + expr_fields = get_expr_fields(self) + unresolved = [] + + for complex_obj in parents: + for field in complex_obj.fields: + if field.wire: + all_fields.append(field) + + # try to resolve expr fields + for e in expr_fields: + if e not in all_fields and e not in unresolved: + unresolved.append(e) + + return unresolved +# resolve_expr_fields_list() + + def get_serialize_params(context, self, buffer_var='_buffer', aux_var='_aux'): """ functions like _serialize(), _unserialize(), and _unpack() sometimes need additional parameters: @@ -750,7 +920,7 @@ def _c_serialize_helper_switch_field(context, self, field, c_switch_variable, pr # switch is handled by this function as a special case param_fields, wire_fields, params = get_serialize_params(context, self) field_mapping = _c_helper_field_mapping(self, prefix) - prefix_str = _c_helper_absolute_name(prefix) + prefix_str = _c_helper_fieldaccess_expr(prefix) # find the parameters that need to be passed to _serialize()/_unpack(): # all switch expr fields must be given as parameters @@ -787,6 +957,16 @@ def _c_serialize_helper_switch_field(context, self, field, c_switch_variable, pr return length # _c_serialize_helper_switch_field() +def _c_get_additional_type_params(type): + """ + compute list of additional params for functions created for the given type + """ + if type.is_simple: + return [] + else: + param_fields, wire_fields, params = get_serialize_params('sizeof', type) + return params[1:] + def _c_serialize_helper_list_field(context, self, field, code_lines, temp_vars, space, prefix): @@ -794,7 +974,7 @@ def _c_serialize_helper_list_field(context, self, field, helper function to cope with lists of variable length """ expr = field.type.expr - prefix_str = _c_helper_absolute_name(prefix) + prefix_str = _c_helper_fieldaccess_expr(prefix) param_fields, wire_fields, params = get_serialize_params('sizeof', self) param_names = [p[2] for p in params] @@ -825,6 +1005,14 @@ def _c_serialize_helper_list_field(context, self, field, # list with variable-sized elements if not field.type.member.fixed_size(): + # compute string for argumentlist for member-type functions + member_params = _c_get_additional_type_params(field.type.member) + member_arg_names = [p[2] for p in member_params] + member_arg_str = '' + for member_arg_name in member_arg_names: + member_arg_str += ', ' + field_mapping[member_arg_name][0] + + # length = '' if context in ('unserialize', 'sizeof', 'unpack'): int_i = ' unsigned int i;' @@ -836,8 +1024,8 @@ def _c_serialize_helper_list_field(context, self, field, # loop over all list elements and call sizeof repeatedly # this should be a bit faster than using the iterators code_lines.append("%s for(i=0; i<%s; i++) {" % (space, list_length)) - code_lines.append("%s xcb_tmp_len = %s(xcb_tmp);" % - (space, field.type.c_sizeof_name)) + code_lines.append("%s xcb_tmp_len = %s(xcb_tmp%s);" % + (space, field.type.c_sizeof_name, member_arg_str)) code_lines.append("%s xcb_block_len += xcb_tmp_len;" % space) code_lines.append("%s xcb_tmp += xcb_tmp_len;" % space) code_lines.append("%s }" % space) @@ -846,7 +1034,7 @@ def _c_serialize_helper_list_field(context, self, field, code_lines.append('%s xcb_parts[xcb_parts_idx].iov_len = 0;' % space) code_lines.append('%s xcb_tmp = (char *) %s%s;' % (space, prefix_str, field.c_field_name)) code_lines.append('%s for(i=0; i<%s; i++) { ' % (space, list_length)) - code_lines.append('%s xcb_block_len = %s(xcb_tmp);' % (space, field.type.c_sizeof_name)) + code_lines.append('%s xcb_block_len = %s(xcb_tmp%s);' % (space, field.type.c_sizeof_name, member_arg_str)) code_lines.append('%s xcb_parts[xcb_parts_idx].iov_len += xcb_block_len;' % space) code_lines.append('%s }' % space) code_lines.append('%s xcb_block_len = xcb_parts[xcb_parts_idx].iov_len;' % space) @@ -865,7 +1053,7 @@ def _c_serialize_helper_fields_fixed_size(context, self, field, typename = reduce(lambda x,y: "%s.%s" % (x, y), scoped_name) code_lines.append('%s /* %s.%s */' % (space, typename, field.c_field_name)) - abs_field_name = _c_helper_absolute_name(prefix, field) + abs_field_name = _c_helper_fieldaccess_expr(prefix, field) # default for simple cases: call sizeof() length = "sizeof(%s)" % field.c_field_type @@ -927,7 +1115,7 @@ def _c_serialize_helper_fields_fixed_size(context, self, field, def _c_serialize_helper_fields_variable_size(context, self, field, code_lines, temp_vars, space, prefix): - prefix_str = _c_helper_absolute_name(prefix) + prefix_str = _c_helper_fieldaccess_expr(prefix) if context in ('unserialize', 'unpack', 'sizeof'): value = '' @@ -984,6 +1172,8 @@ def _c_serialize_helper_fields(context, self, need_padding = False prev_field_was_variable = False + _c_pre.push_indent(space + ' ') + for field in self.fields: if not field.visible: if not ((field.wire and not field.auto) or 'unserialize' == context): @@ -1072,6 +1262,8 @@ def _c_serialize_helper_fields(context, self, if self.c_var_followed_by_fixed_fields: need_padding = False + _c_pre.pop_indent() + return count # _c_serialize_helper_fields() @@ -1170,6 +1362,8 @@ def _c_serialize(context, self): temp_vars = [] prefix = [] + _c_pre.redirect_start(code_lines, temp_vars) + if 'serialize' == context: if not self.is_switch and not self.c_var_followed_by_fixed_fields: _c(' %s *xcb_out = *_buffer;', self.c_type) @@ -1215,11 +1409,13 @@ def _c_serialize(context, self): _c(' %s _aux;', self.c_type) _c(' return %s(%s, &_aux);', self.c_unpack_name, reduce(lambda x,y: "%s, %s" % (x, y), param_names)) _c('}') + _c_pre.redirect_end() return elif self.c_var_followed_by_fixed_fields: # special case: call _unserialize() _c(' return %s(%s, NULL);', self.c_unserialize_name, reduce(lambda x,y: "%s, %s" % (x, y), param_names)) _c('}') + _c_pre.redirect_end() return else: _c(' char *xcb_tmp = (char *)_buffer;') @@ -1255,6 +1451,8 @@ def _c_serialize(context, self): _c(' unsigned int xcb_pad = 0;') _c(' unsigned int xcb_align_to = 0;') + _c_pre.redirect_end() + _c('') for t in temp_vars: _c(t) @@ -1347,6 +1545,14 @@ def _c_iterator(self, name): _h(' %s *data; /**< */', self.c_type) _h(' int%s rem; /**< */', ' ' * (len(self.c_type) - 2)) _h(' int%s index; /**< */', ' ' * (len(self.c_type) - 2)) + # add additional params of the type "self" as fields to the iterator struct + # so that they can be passed to the sizeof-function by the iterator's next-function + params = _c_get_additional_type_params(self) + for param in params: + _h(' %s%s %s; /**< */', + param[0], + ' ' * (len(self.c_type) + 1 - len(param[0])), + param[2]) _h('} %s;', self.c_iterator_type) _h_setlevel(1) @@ -1374,9 +1580,14 @@ def _c_iterator(self, name): _c(' /* FIXME - determine the size of the union %s */', self.c_type) else: if self.c_need_sizeof: + # compute the string of additional arguments for the sizeof-function + additional_args = '' + for param in params: + additional_args += ', i->' + param[2] + _c(' xcb_generic_iterator_t child;') - _c(' child.data = (%s *)(((char *)R) + %s(R));', - self.c_type, self.c_sizeof_name) + _c(' child.data = (%s *)(((char *)R) + %s(R%s));', + self.c_type, self.c_sizeof_name, additional_args) _c(' i->index = (char *) child.data - (char *) i->data;') else: _c(' xcb_generic_iterator_t child = %s;', _c_iterator_get_end(self.last_varsized_field, 'R')) @@ -1435,12 +1646,7 @@ def _c_accessor_get_length(expr, field_mapping=None): if field_mapping is not None: lenfield_name = field_mapping[lenfield_name][0] - if expr.lenfield is not None and expr.lenfield.prev_varsized_field is not None: - # special case: variable and fixed size fields are intermixed - # if the lenfield is among the fixed size fields, there is no need - # to call a special accessor function like - return field_mapping(expr.lenfield_name) - elif expr.lenfield_name is not None: + if expr.lenfield_name is not None: return lenfield_name else: return str(expr.nmemb) @@ -1477,9 +1683,65 @@ def _c_accessor_get_expr(expr, field_mapping): raise Exception("list field '%s' referenced by sumof not found" % expr.lenfield_name) list_name = field_mapping[field.c_field_name][0] c_length_func = "%s(%s)" % (field.c_length_name, list_name) - # note: xcb_sumof() has only been defined for integers c_length_func = _c_accessor_get_expr(field.type.expr, field_mapping) - return 'xcb_sumof(%s, %s)' % (list_name, c_length_func) + # create explicit code for computing the sum. + # This works for all C-types which can be added to int64_t with += + _c_pre.start() + lengthvar = _c_pre.get_tempvarname() + loopvar = _c_pre.get_tempvarname() + sumvar = _c_pre.get_tempvarname() + listvar = _c_pre.get_tempvarname() + _c_pre.tempvar("int %s; /* sumof length */", lengthvar) + _c_pre.tempvar("int %s; /* sumof loop counter */", loopvar) + _c_pre.tempvar("int64_t %s; /* sumof sum */", sumvar) + _c_pre.tempvar("const %s* %s; /* sumof list ptr */", field.c_field_type, listvar) + _c_pre.code("/* sumof start */") + _c_pre.code("%s = %s;", lengthvar, c_length_func) + _c_pre.code("%s = 0;", sumvar) + _c_pre.code("%s = %s;", listvar, list_name) + _c_pre.code("for (%s = 0; %s < %s; %s++) {", loopvar, loopvar, lengthvar, loopvar) + _c_pre.indent() + + # define and set xcb_listelement, so that it can be used by + # listelement-ref expressions. + if expr.contains_listelement_ref: + _c_pre.code( + "const %s *xcb_listelement = %s;", + field.c_field_type, listvar) + + # summation + if expr.rhs is None: + _c_pre.code("%s += *%s;", sumvar, listvar) + else: + # sumof has a nested expression which has to be evaluated in + # the context of this list element + + # field mapping for the subexpression needs to include + # the fields of the list-member type + scoped_field_mapping = field_mapping.copy() + if not field.type.member.is_simple: + scoped_field_mapping.update( + _c_helper_field_mapping( + field.type.member, + [(listvar, '->', field.type.member)])) + + # cause pre-code of the subexpression be added right here + _c_pre.end() + # compute the subexpression + rhs_expr_str = _c_accessor_get_expr(expr.rhs, scoped_field_mapping) + # resume with our code + _c_pre.start() + # output the summation expression + _c_pre.code("%s += %s;", sumvar, rhs_expr_str) + + _c_pre.code("%s++;", listvar) + _c_pre.pop_indent() + _c_pre.code("}") + _c_pre.code("/* sumof end. Result is in %s */", sumvar) + _c_pre.end() + return sumvar + elif expr.op == 'listelement-ref': + return '(*xcb_listelement)' elif expr.op != None: return ('(' + _c_accessor_get_expr(expr.lhs, field_mapping) + ' ' + expr.op + ' ' + @@ -1609,6 +1871,29 @@ def _c_accessors_list(self, field): # auxiliary object for 'S' parameter S_obj = parents[1] + # for functions generated below: + # * compute list of additional parameters which contains as parameter + # any expr fields that cannot be resolved within self and descendants. + # * and make sure that they are accessed without prefix within the function. + unresolved_fields = resolve_expr_fields_list(list, parents) + additional_params = [] + additional_param_names = set(); + for f in unresolved_fields: + if f.c_field_name not in additional_param_names: + # add to the list of additional params + additional_params.append((f.c_field_type, f.c_field_name)); + # make sure that the param is accessed without prefix within the function + fields[ f.c_field_name ] = (f.c_field_name, f) + + # internal function to compute the parameterlist with given indentation + # such that the formatting of the additional parameters is consistent with + # the other parameters. + def additional_params_to_str(indent): + if len(additional_params) == 0: + return '' + else: + return (',\n' + indent).join([''] + ['%s %s /**< */' % p for p in additional_params]) + _h_setlevel(1) _c_setlevel(1) if list.member.fixed_size(): @@ -1639,31 +1924,32 @@ def _c_accessors_list(self, field): _hc('') _hc('int') + spacing = ' '*(len(field.c_length_name)+2) + add_param_str = additional_params_to_str(spacing) if switch_obj is not None: _hc('%s (const %s *R /**< */,', field.c_length_name, R_obj.c_type) - spacing = ' '*(len(field.c_length_name)+2) - _h('%sconst %s *S /**< */);', spacing, S_obj.c_type) - _c('%sconst %s *S /**< */)', spacing, S_obj.c_type) - length = _c_accessor_get_expr(field.type.expr, fields) + _h('%sconst %s *S /**< */%s);', spacing, S_obj.c_type, add_param_str) + _c('%sconst %s *S /**< */%s)', spacing, S_obj.c_type, add_param_str) else: - _h('%s (const %s *R /**< */);', field.c_length_name, c_type) - _c('%s (const %s *R /**< */)', field.c_length_name, c_type) - length = _c_accessor_get_expr(field.type.expr, fields) + _h('%s (const %s *R /**< */%s);', field.c_length_name, c_type, add_param_str) + _c('%s (const %s *R /**< */%s)', field.c_length_name, c_type, add_param_str) _c('{') + length = _c_accessor_get_expr(field.type.expr, fields) _c(' return %s;', length) _c('}') if field.type.member.is_simple: _hc('') _hc('xcb_generic_iterator_t') + spacing = ' '*(len(field.c_end_name)+2) + add_param_str = additional_params_to_str(spacing) if switch_obj is not None: _hc('%s (const %s *R /**< */,', field.c_end_name, R_obj.c_type) - spacing = ' '*(len(field.c_end_name)+2) - _h('%sconst %s *S /**< */);', spacing, S_obj.c_type) - _c('%sconst %s *S /**< */)', spacing, S_obj.c_type) + _h('%sconst %s *S /**< */%s);', spacing, S_obj.c_type, add_param_str) + _c('%sconst %s *S /**< */%s)', spacing, S_obj.c_type, add_param_str) else: - _h('%s (const %s *R /**< */);', field.c_end_name, c_type) - _c('%s (const %s *R /**< */)', field.c_end_name, c_type) + _h('%s (const %s *R /**< */%s);', field.c_end_name, c_type, add_param_str) + _c('%s (const %s *R /**< */%s)', field.c_end_name, c_type, add_param_str) _c('{') _c(' xcb_generic_iterator_t i;') @@ -1688,21 +1974,27 @@ def _c_accessors_list(self, field): else: _hc('') _hc('%s', field.c_iterator_type) + spacing = ' '*(len(field.c_iterator_name)+2) + add_param_str = additional_params_to_str(spacing) if switch_obj is not None: _hc('%s (const %s *R /**< */,', field.c_iterator_name, R_obj.c_type) - spacing = ' '*(len(field.c_iterator_name)+2) - _h('%sconst %s *S /**< */);', spacing, S_obj.c_type) - _c('%sconst %s *S /**< */)', spacing, S_obj.c_type) + _h('%sconst %s *S /**< */%s);', spacing, S_obj.c_type, add_param_str) + _c('%sconst %s *S /**< */%s)', spacing, S_obj.c_type, add_param_str) else: - _h('%s (const %s *R /**< */);', field.c_iterator_name, c_type) - _c('%s (const %s *R /**< */)', field.c_iterator_name, c_type) + _h('%s (const %s *R /**< */%s);', field.c_iterator_name, c_type, add_param_str) + _c('%s (const %s *R /**< */%s)', field.c_iterator_name, c_type, add_param_str) _c('{') _c(' %s i;', field.c_iterator_type) + _c_pre.start() + length_expr_str = _c_accessor_get_expr(field.type.expr, fields) + if switch_obj is not None: + _c_pre.end() _c(' i.data = %s;', fields[field.c_field_name][0]) - _c(' i.rem = %s;', _c_accessor_get_expr(field.type.expr, fields)) + _c(' i.rem = %s;', length_expr_str) elif field.prev_varsized_field == None: + _c_pre.end() _c(' i.data = (%s *) (R + 1);', field.c_field_type) else: (prev_varsized_field, align_pad) = get_align_pad(field) @@ -1713,12 +2005,20 @@ def _c_accessors_list(self, field): _c(' xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(prev_varsized_field, 'R')) + _c_pre.end() _c(' i.data = (%s *) ((char *) prev.data + %s);', field.c_field_type, align_pad) if switch_obj is None: - _c(' i.rem = %s;', _c_accessor_get_expr(field.type.expr, fields)) + _c(' i.rem = %s;', length_expr_str) _c(' i.index = (char *) i.data - (char *) %s;', 'R' if switch_obj is None else 'S' ) + + # initialize additional iterator fields which are derived from + # additional type parameters for the list member type. + additional_iter_fields = _c_get_additional_type_params(field.type.member) + for iter_field in additional_iter_fields: + _c(' i.%s = %s;', iter_field[2], fields[iter_field[2]][0]) + _c(' return i;') _c('}') @@ -1734,9 +2034,9 @@ def _c_accessors(self, name, base): if True: for field in self.fields: if not field.type.is_pad: - if field.type.is_list and not field.type.fixed_size(): + if _c_field_needs_list_accessor(field): _c_accessors_list(self, field) - elif field.prev_varsized_field is not None or not field.type.fixed_size(): + elif _c_field_needs_field_accessor(field): _c_accessors_field(self, field) def c_simple(self, name): @@ -2837,6 +3137,7 @@ def c_request(self, name): if self.c_need_aux: _c_request_helper(self, name, 'xcb_void_cookie_t', True, False, True) _c_request_helper(self, name, 'xcb_void_cookie_t', True, True, True) + _c_accessors(self, name, name) # We generate the manpage afterwards because _c_type_setup has been called. # TODO: what about aux helpers? @@ -2870,7 +3171,18 @@ def c_event(self, name): force_packed = any(f.type.size == 8 and f.type.is_simple for f in self.fields[(idx+1):]) break - _c_type_setup(self, name, ('event',)) + if self.name == name: + _c_type_setup(self, name, ('event',)) + # generate accessors + # (needed for fields after var-sized fields, for lists with var-sized elements, + # switches, ...) + _c_accessors(self, name, name) + else: + # no type-setup needed for eventcopies + # (the type-setup of an eventcopy would overwrite members of the original + # event, and it would create sizeof-etc funtions which + # called undefined accessor functions) + pass # Opcode define _c_opcode(name, self.opcodes[name]) @@ -2883,6 +3195,22 @@ def c_event(self, name): _h('') _h('typedef %s %s;', _t(self.name + ('event',)), _t(name + ('event',))) + # Create sizeof-function for eventcopies for compatibility reasons + if self.c_need_sizeof: + _h_setlevel(1) + _c_setlevel(1) + _h('') + _h('int') + _h('%s (const void *_buffer /**< */);', _n(name + ('sizeof',))) + _c('') + _c('int') + _c('%s (const void *_buffer /**< */)', _n(name + ('sizeof',))) + _c('{'); + _c(' return %s(_buffer);', _n(self.name + ('sizeof',))) + _c('}'); + _h_setlevel(0) + _c_setlevel(0) + _man_event(self, name) def c_error(self, name): diff --git a/libxcb/xcb-proto/doc/xml-xcb.txt b/libxcb/xcb-proto/doc/xml-xcb.txt index 235958de3..f8129ea9c 100644 --- a/libxcb/xcb-proto/doc/xml-xcb.txt +++ b/libxcb/xcb-proto/doc/xml-xcb.txt @@ -298,6 +298,23 @@ Expressions the structure containing this expression. The identifier is the value of the "name" attribute on the referenced field. +identifier + + A paramref is similar to a fieldref, but it refers to the value of + a field in the context which refers to the struct which contains the paramref. + + So, it refers to a field outside of the structure where it is defined. + This has the following consequences: + * The generator cannot deduce its type. + So, it is mandatory to specify its type. + * The identifier-name must not be used as a field in the structure + which contaons the paramref. + + For an example, see struct "DeviceTimeCoord" and request/reply + "GetDeviceMotionEvents" in xinput.xml, where paramref "num_axes" + in struct DeviceTimeCoord refers to field "num_axes" in + the DeviceTimeCoord reply. + integer The value element represents a literal integer value in an expression. The @@ -322,10 +339,26 @@ Expressions This element represents a sumation of the elements of the referenced list. +expression + + The expression is evaluated for each element of the referenced list, + in the context of this element. + This sumof element then represents a sumation of the results of these + evaluations. + + expression will usually be a fieldref which references a field of + a list-element or an expression containing a fieldref, + such as popcount of a fieldref. + expression This element represents the number of bits set in the expression. + + + This element represents the current list-element when used inside + a list-iteration expression such as . + Documentation ------------- diff --git a/libxcb/xcb-proto/src/present.xml b/libxcb/xcb-proto/src/present.xml index a9adc2ba8..95fee0181 100644 --- a/libxcb/xcb-proto/src/present.xml +++ b/libxcb/xcb-proto/src/present.xml @@ -199,7 +199,15 @@ OF THIS SOFTWARE. - + + + + length + 18 + + 2 + + diff --git a/libxcb/xcb-proto/src/render.xml b/libxcb/xcb-proto/src/render.xml index 55b73f7b8..c54608e72 100644 --- a/libxcb/xcb-proto/src/render.xml +++ b/libxcb/xcb-proto/src/render.xml @@ -280,16 +280,122 @@ for licensing information. - + + + value_mask + + Repeat + + + + AlphaMap + + + + AlphaXOrigin + + + + AlphaYOrigin + + + + ClipXOrigin + + + + ClipYOrigin + + + + ClipMask + + + + GraphicsExposure + + + + SubwindowMode + + + + PolyEdge + + + + PolyMode + + + + Dither + + + + ComponentAlpha + + + - + + + value_mask + + Repeat + + + + AlphaMap + + + + AlphaXOrigin + + + + AlphaYOrigin + + + + ClipXOrigin + + + + ClipYOrigin + + + + ClipMask + + + + GraphicsExposure + + + + SubwindowMode + + + + PolyEdge + + + + PolyMode + + + + Dither + + + + ComponentAlpha + + + diff --git a/libxcb/xcb-proto/src/screensaver.xml b/libxcb/xcb-proto/src/screensaver.xml index 491869e81..8d5abb43d 100644 --- a/libxcb/xcb-proto/src/screensaver.xml +++ b/libxcb/xcb-proto/src/screensaver.xml @@ -95,9 +95,71 @@ Draft Standard Version 1.1 - + + + value_mask + + BackPixmap + + + + BackPixel + + + + BorderPixmap + + + + BorderPixel + + + + BitGravity + + + + WinGravity + + + + BackingStore + + + + BackingPlanes + + + + BackingPixel + + + + OverrideRedirect + + + + SaveUnder + + + + EventMask + + + + DontPropagate + + + + Colormap + + + + Cursor + + + + diff --git a/libxcb/xcb-proto/src/xcb.xsd b/libxcb/xcb-proto/src/xcb.xsd index 85f5bc2af..c1dce3e1e 100644 --- a/libxcb/xcb-proto/src/xcb.xsd +++ b/libxcb/xcb-proto/src/xcb.xsd @@ -146,6 +146,15 @@ authorization from the authors. + + + + + + + + + @@ -162,9 +171,13 @@ authorization from the authors. + + + + @@ -182,15 +195,6 @@ authorization from the authors. - - - - - - - - - @@ -296,7 +300,6 @@ authorization from the authors. - @@ -306,7 +309,6 @@ authorization from the authors. - diff --git a/libxcb/xcb-proto/src/xfixes.xml b/libxcb/xcb-proto/src/xfixes.xml index c5cba352a..0a3d5ffee 100644 --- a/libxcb/xcb-proto/src/xfixes.xml +++ b/libxcb/xcb-proto/src/xfixes.xml @@ -291,13 +291,13 @@ authorization from the authors. - nbytes width height + nbytes diff --git a/libxcb/xcb-proto/src/xinput.xml b/libxcb/xcb-proto/src/xinput.xml index 7f7b0a66d..c729f20fb 100644 --- a/libxcb/xcb-proto/src/xinput.xml +++ b/libxcb/xcb-proto/src/xinput.xml @@ -46,56 +46,10 @@ This will, e.g., be necessary for automatically generated byte-order conversion which will, e.g., be necessary for server-side xcb. This affects the following: -* GetFeedbackControl reply field "feedbacks" ( structs FeedbackState, ... ) -* ChangeFeedbackControl request field "feedback" ( structs FeedbackCtl, ... ) -* QueryDeviceState reply field "classes" ( structs InputState, ... ) -* GetDeviceControl reply field "control" ( structs DeviceState, ... ) -* ChangeDeviceControl request field "control" ( structs ChangeDeviceControl, ... ) -* XIChangeHierarchy request field "changes" ( structs HierarchyChange, ... ) -* struct XIDeviceInfo field "classes" ( structs DeviceClass, ... ) * SendExtensionEvent member "events" ***** -xml and generator have to support of all members of a list - -This is needed for the following XI2-events ( and eventcopies thereof ) - KeyPress - ButtonPress - RawKeyPress - RawKeyPress - RawButtonPress - TouchBegin - RawTouchBegin - - -***** - - should support fields of listmembers. - -This is needed for request "ListInputDevices" - -***** - -xml and generator should support -switch-case similar to switch-bitcase. - -(and maybe: variable sized unions with a mechanism to define -which union-field is selected.) - -One of these features is needed for the InputInfo type -which is used by request "ListInputDevices" for the list "input_infos". - -***** - -Parametrized structs - -This is needed for being able to use the value of the field -"num_axes" of the GetDeviceMotionEvents-reply -in struct DeviceTimeCoord. - -***** - --> @@ -217,6 +171,29 @@ in struct DeviceTimeCoord. + + class_id + + Key + + + + + + + Button + + + + Valuator + + + + + axes_len + + + @@ -234,9 +211,15 @@ in struct DeviceTimeCoord. devices_len - - + + + num_class_info + + + + devices_len + + @@ -346,8 +329,9 @@ in struct DeviceTimeCoord. - + + num_axes + @@ -361,7 +345,9 @@ in struct DeviceTimeCoord. - + + num_events + @@ -609,12 +595,56 @@ in struct DeviceTimeCoord. - - - len - 4 - - + + class_id + + Keyboard + + + + + + + + + + 32 + + + + Pointer + + + + + + + String + + + + num_keysyms + + + + Integer + + + + + + Led + + + + + Bell + + + + + + @@ -696,12 +726,51 @@ in struct DeviceTimeCoord. - - - len - 4 - - + + class_id + + Keyboard + + + + + + + + + + + Pointer + + + + + + + String + + + + num_keysyms + + + + Integer + + + + Led + + + + + Bell + + + + + + @@ -1025,12 +1094,53 @@ in struct DeviceTimeCoord. - - - len - 4 - - + + control_id + + resolution + + + num_valuators + + + num_valuators + + + num_valuators + + + + abs_calib + + + + + + + + + + + core + + + + + + enable + + + + + abs_area + + + + + + + + @@ -1099,12 +1209,48 @@ in struct DeviceTimeCoord. - - - len - 4 - - + + control_id + + resolution + + + + + num_valuators + + + + abs_calib + + + + + + + + + + + core + + + + + enable + + + + + abs_area + + + + + + + + @@ -1205,30 +1351,26 @@ in struct DeviceTimeCoord. format - - + 8Bits num_items - - + + 16Bits num_items - - + + 32Bits num_items - + @@ -1356,15 +1498,37 @@ in struct DeviceTimeCoord. - - - - len - 4 - - 4 - - + + type + + AddMaster + + + + + name_len + + + + + RemoveMaster + + + + + + + + AttachSlave + + + + + DetachSlave + + + + @@ -1560,16 +1724,56 @@ in struct DeviceTimeCoord. - - - - - len - 4 - - 8 - - + + type + + Key + + + num_keys + + + + Button + + + + + num_buttons + 31 + + 32 + + + + num_buttons + + + + Valuator + + + + + + + + + + + Scroll + + + + + + + + Touch + + + + @@ -1776,28 +1980,24 @@ in struct DeviceTimeCoord. format - - + 8Bits num_items - - + + 16Bits num_items - - + + 32Bits num_items - + @@ -1828,30 +2028,26 @@ in struct DeviceTimeCoord. format - - + 8Bits num_items - - + + 16Bits num_items - - + + 32Bits num_items - + @@ -2092,8 +2288,13 @@ in struct DeviceTimeCoord. valuators_len - + + + + + + + @@ -2128,8 +2329,13 @@ in struct DeviceTimeCoord. valuators_len - + + + + + + + @@ -2248,10 +2454,20 @@ in struct DeviceTimeCoord. valuators_len - - + + + + + + + + + + + + + + @@ -2269,10 +2485,20 @@ in struct DeviceTimeCoord. valuators_len - - + + + + + + + + + + + + + + @@ -2311,8 +2537,13 @@ in struct DeviceTimeCoord. valuators_len - + + + + + + + @@ -2351,10 +2582,20 @@ in struct DeviceTimeCoord. valuators_len - - + + + + + + + + + + + + + + diff --git a/libxcb/xcb-proto/src/xprint.xml b/libxcb/xcb-proto/src/xprint.xml index e32293f3b..dc23dd0da 100644 --- a/libxcb/xcb-proto/src/xprint.xml +++ b/libxcb/xcb-proto/src/xprint.xml @@ -209,21 +209,14 @@ authorization from the authors. - + - - - + + diff --git a/libxcb/xcb-proto/src/xproto.xml b/libxcb/xcb-proto/src/xproto.xml index bfb8a4cff..d50a4285a 100644 --- a/libxcb/xcb-proto/src/xproto.xml +++ b/libxcb/xcb-proto/src/xproto.xml @@ -57,6 +57,7 @@ authorization from the authors. GCONTEXT + @@ -64,6 +65,8 @@ authorization from the authors. + + @@ -1293,9 +1296,71 @@ parent's cursor will cause an immediate change in the displayed cursor. - + + + value_mask + + BackPixmap + + + + BackPixel + + + + BorderPixmap + + + + BorderPixel + + + + BitGravity + + + + WinGravity + + + + BackingStore + + + + BackingPlanes + + + + BackingPixel + + + + OverrideRedirect + + + + SaveUnder + + + + EventMask + + + + DontPropagate + + + + Colormap + + + + Cursor + + + + Creates a window - + + + value_mask + + BackPixmap + + + + BackPixel + + + + BorderPixmap + + + + BorderPixel + + + + BitGravity + + + + WinGravity + + + + BackingStore + + + + BackingPlanes + + + + BackingPixel + + + + OverrideRedirect + + + + SaveUnder + + + + EventMask + + + + DontPropagate + + + + Colormap + + + + Cursor + + + + change window attributes - + - + + value_mask + + X + + + + Y + + + + Width + + + + Height + + + + BorderWidth + + + + Sibling + + + + StackMode + + + + Configures window attributes - + + + value_mask + + Function + + + + PlaneMask + + + + Foreground + + + + Background + + + + LineWidth + + + + LineStyle + + + + CapStyle + + + + JoinStyle + + + + FillStyle + + + + FillRule + + + + Tile + + + + Stipple + + + + TileStippleOriginX + + + + TileStippleOriginY + + + + Font + + + + SubwindowMode + + + + GraphicsExposures + + + + ClipOriginX + + + + ClipOriginY + + + + ClipMask + + + + DashOffset + + + + DashList + + + + ArcMode + + + Creates a graphics context - + + + value_mask + + Function + + + + PlaneMask + + + + Foreground + + + + Background + + + + LineWidth + + + + LineStyle + + + + CapStyle + + + + JoinStyle + + + + FillStyle + + + + FillRule + + + + Tile + + + + Stipple + + + + TileStippleOriginX + + + + TileStippleOriginY + + + + Font + + + + SubwindowMode + + + + GraphicsExposures + + + + ClipOriginX + + + + ClipOriginY + + + + ClipMask + + + + DashOffset + + + + DashList + + + + ArcMode + + + change graphics context components - + + + value_mask + + KeyClickPercent + + + + BellPercent + + + + BellPitch + + + + BellDuration + + + + Led + + + + LedMode + + + + Key + + + + AutoRepeatMode + + + + diff --git a/libxcb/xcb-proto/xcbgen/expr.py b/libxcb/xcb-proto/xcbgen/expr.py index e4fb06e93..e4ee8c6e2 100644 --- a/libxcb/xcb-proto/xcbgen/expr.py +++ b/libxcb/xcb-proto/xcbgen/expr.py @@ -22,6 +22,7 @@ class Field(object): self.wire = wire self.auto = auto self.isfd = isfd + self.parent = None class Expression(object): @@ -52,6 +53,8 @@ class Expression(object): self.lhs = None self.rhs = None + self.contains_listelement_ref = False + if elt.tag == 'list': # List going into a request, which has no length field (inferred by server) self.lenfield_name = elt.get('name') + '_len' @@ -61,12 +64,9 @@ class Expression(object): # Standard list with a fieldref self.lenfield_name = elt.text - elif elt.tag == 'valueparam': - # Value-mask. The length bitmask is described by attributes. - self.lenfield_name = elt.get('value-mask-name') - self.lenfield_type = elt.get('value-mask-type') - self.lenwire = True - self.bitfield = True + elif elt.tag == 'paramref': + self.lenfield_name = elt.text + self.lenfield_type = elt.get('type') elif elt.tag == 'op': # Op field. Need to recurse. @@ -103,6 +103,17 @@ class Expression(object): elif elt.tag == 'sumof': self.op = 'sumof' self.lenfield_name = elt.get('ref') + subexpressions = list(elt) + if len(subexpressions) > 0: + # sumof with a nested expression which is to be evaluated + # for each list-element in the context of that list-element. + # sumof then returns the sum of the results of these evaluations + self.rhs = Expression(subexpressions[0], parent) + + elif elt.tag == 'listelement-ref': + # current list element inside iterating expressions such as sumof + self.op = 'listelement-ref' + self.contains_listelement_ref = True else: # Notreached @@ -111,6 +122,12 @@ class Expression(object): def fixed_size(self): return self.nmemb != None + def recursive_resolve_tasks(self, module, parents): + for subexpr in (self.lhs, self.rhs): + if subexpr != None: + subexpr.recursive_resolve_tasks(module, parents) + self.contains_listelement_ref |= subexpr.contains_listelement_ref + def resolve(self, module, parents): if self.op == 'enumref': self.lenfield_type = module.get_type(self.lenfield_name[0]) @@ -127,4 +144,6 @@ class Expression(object): self.lenfield_parent = p self.lenfield_type = fields[self.lenfield_name].field_type break + + self.recursive_resolve_tasks(module, parents) diff --git a/libxcb/xcb-proto/xcbgen/xtypes.py b/libxcb/xcb-proto/xcbgen/xtypes.py index 45d7568f5..4d6bbc031 100644 --- a/libxcb/xcb-proto/xcbgen/xtypes.py +++ b/libxcb/xcb-proto/xcbgen/xtypes.py @@ -76,6 +76,7 @@ class Type(object): return complex_type.fields.append(new_field) + new_field.parent = complex_type def make_fd_of(self, module, complex_type, fd_name): ''' @@ -184,8 +185,6 @@ class ListType(Type): if elt.tag == 'list': elts = list(elt) self.expr = Expression(elts[0] if len(elts) else elt, self) - elif elt.tag == 'valueparam': - self.expr = Expression(elt, self) self.size = member.size if member.fixed_size() else None self.nmemb = self.expr.nmemb if self.expr.fixed_size() else None @@ -328,11 +327,6 @@ class ComplexType(Type): fkey = child.get('type') type = ListType(child, module.get_type(fkey), *self.lenfield_parent) visible = True - elif child.tag == 'valueparam': - field_name = child.get('value-list-name') - fkey = 'CARD32' - type = ListType(child, module.get_type(fkey), *self.lenfield_parent) - visible = True elif child.tag == 'switch': field_name = child.get('name') # construct the switch type name from the parent type and the field name -- cgit v1.2.3