2 from xml.etree.cElementTree import *
4 from os.path import basename
7 # Jump to the bottom of this file for the main routine
9 # Some hacks to make the API more readable, and to keep backwards compability
10 _cname_re = re.compile('([A-Z0-9][a-z]+|[A-Z0-9]+(?![a-z])|[a-z]+)')
11 _cname_special_cases = {'DECnet':'decnet'}
13 _extension_special_cases = ['XPrint', 'XCMisc', 'BigRequests']
15 _cplusplus_annoyances = {'class' : '_class',
19 _cardinal_types = ['CARD8', 'uint8_t',
39 Writes the given line to the header file.
41 _hlines[_hlevel].append(fmt % args)
45 Writes the given line to the source file.
47 _clines[_clevel].append(fmt % args)
51 Writes the given line to both the header and source files.
56 # XXX See if this level thing is really necessary.
59 Changes the array that header lines are written to.
60 Supports writing different sections of the header file.
63 while len(_hlines) <= idx:
69 Changes the array that source lines are written to.
70 Supports writing to different sections of the source file.
73 while len(_clines) <= idx:
79 Does C-name conversion on a single string fragment.
80 Uses a regexp with some hard-coded special cases.
82 if str in _cname_special_cases:
83 return _cname_special_cases[str]
85 split = _cname_re.finditer(str)
86 name_parts = [match.group(0) for match in split]
87 return '_'.join(name_parts)
91 Checks for certain C++ reserved words and fixes them.
93 if str in _cplusplus_annoyances:
94 return _cplusplus_annoyances[str]
100 Does C-name conversion on an extension name.
101 Has some additional special cases on top of _n_item.
103 if str in _extension_special_cases:
104 return _n_item(str).lower()
110 Does C-name conversion on a tuple of strings.
111 Different behavior depending on length of tuple, extension/not extension, etc.
112 Basically C-name converts the individual pieces, then joins with underscores.
117 parts = [list[0], _n_item(list[1])]
119 parts = [list[0], _ext(list[1])] + [_n_item(i) for i in list[2:]]
121 parts = [list[0]] + [_n_item(i) for i in list[1:]]
122 return '_'.join(parts).lower()
126 Does C-name conversion on a tuple of strings representing a type.
127 Same as _n but adds a "_t" on the end.
132 parts = [list[0], _n_item(list[1]), 't']
134 parts = [list[0], _ext(list[1])] + [_n_item(i) for i in list[2:]] + ['t']
136 parts = [list[0]] + [_n_item(i) for i in list[1:]] + ['t']
137 return '_'.join(parts).lower()
142 Exported function that handles module open.
143 Opens the files and writes out the auto-generated comment, header file includes, etc.
147 _ns.c_ext_global_name = _n(_ns.prefix + ('id',))
153 _hc(' * This file generated automatically from %s by c_client.py.', _ns.file)
154 _hc(' * Edit at your peril.')
159 _h(' * @defgroup XCB_%s_API XCB %s API', _ns.ext_name, _ns.ext_name)
160 _h(' * @brief %s XCB Protocol Implementation.', _ns.ext_name)
164 _h('#ifndef __%s_H', _ns.header.upper())
165 _h('#define __%s_H', _ns.header.upper())
167 _h('#include "xcb.h"')
169 _c('#include <string.h>')
170 _c('#include <assert.h>')
171 _c('#include "xcbext.h"')
172 _c('#include "%s.h"', _ns.header)
175 for (n, h) in self.imports:
176 _hc('#include "%s.h"', h)
179 _h('#define XCB_%s_MAJOR_VERSION %s', _ns.ext_name.upper(), _ns.major_version)
180 _h('#define XCB_%s_MINOR_VERSION %s', _ns.ext_name.upper(), _ns.minor_version)
182 _h('extern xcb_extension_t %s;', _ns.c_ext_global_name)
185 _c('xcb_extension_t %s = { "%s" };', _ns.c_ext_global_name, _ns.ext_xname)
189 Exported function that handles module close.
190 Writes out all the stored content lines, then closes the files.
203 hfile = open('%s.h' % _ns.header, 'w')
211 cfile = open('%s.c' % _ns.header, 'w')
218 def c_enum(self, name):
220 Exported function that handles enum declarations.
224 _h('typedef enum %s {', _t(name))
226 count = len(self.values)
228 for (enam, eval) in self.values:
230 equals = ' = ' if eval != '' else ''
231 comma = ',' if count > 0 else ''
232 _h(' %s%s%s%s', _n(name + (enam,)).upper(), equals, eval, comma)
234 _h('} %s;', _t(name))
236 def _c_type_setup(self, name, postfix):
238 Sets up all the C-related state by adding additional data fields to
239 all Field and Type objects. Here is where we figure out most of our
240 variable and function names.
242 Recurses into child fields and list member types.
244 # Do all the various names in advance
245 self.c_type = _t(name + postfix)
246 self.c_wiretype = 'char' if self.c_type == 'void' else self.c_type
248 self.c_iterator_type = _t(name + ('iterator',))
249 self.c_next_name = _n(name + ('next',))
250 self.c_end_name = _n(name + ('end',))
252 self.c_request_name = _n(name)
253 self.c_checked_name = _n(name + ('checked',))
254 self.c_unchecked_name = _n(name + ('unchecked',))
255 self.c_reply_name = _n(name + ('reply',))
256 self.c_reply_type = _t(name + ('reply',))
257 self.c_cookie_type = _t(name + ('cookie',))
259 if self.is_container:
261 self.c_container = 'union' if self.is_union else 'struct'
262 prev_varsized_field = None
263 prev_varsized_offset = 0
264 first_field_after_varsized = None
266 for field in self.fields:
267 _c_type_setup(field.type, field.field_type, ())
268 if field.type.is_list:
269 _c_type_setup(field.type.member, field.field_type, ())
271 field.c_field_type = _t(field.field_type)
272 field.c_field_const_type = ('' if field.type.nmemb == 1 else 'const ') + field.c_field_type
273 field.c_field_name = _cpp(field.field_name)
274 field.c_subscript = '[%d]' % field.type.nmemb if (field.type.nmemb > 1) else ''
275 field.c_pointer = ' ' if field.type.nmemb == 1 else '*'
277 field.c_iterator_type = _t(field.field_type + ('iterator',)) # xcb_fieldtype_iterator_t
278 field.c_iterator_name = _n(name + (field.field_name, 'iterator')) # xcb_container_field_iterator
279 field.c_accessor_name = _n(name + (field.field_name,)) # xcb_container_field
280 field.c_length_name = _n(name + (field.field_name, 'length')) # xcb_container_field_length
281 field.c_end_name = _n(name + (field.field_name, 'end')) # xcb_container_field_end
283 field.prev_varsized_field = prev_varsized_field
284 field.prev_varsized_offset = prev_varsized_offset
286 if prev_varsized_offset == 0:
287 first_field_after_varsized = field
288 field.first_field_after_varsized = first_field_after_varsized
290 if field.type.fixed_size():
291 prev_varsized_offset += field.type.size
293 self.last_varsized_field = field
294 prev_varsized_field = field
295 prev_varsized_offset = 0
297 def _c_iterator_get_end(field, accum):
299 Figures out what C code is needed to find the end of a variable-length structure field.
300 For nested structures, recurses into its last variable-sized field.
301 For lists, calls the end function
303 if field.type.is_container:
304 accum = field.c_accessor_name + '(' + accum + ')'
305 # XXX there could be fixed-length fields at the end
306 return _c_iterator_get_end(field.type.last_varsized_field, accum)
307 if field.type.is_list:
308 # XXX we can always use the first way
309 if field.type.c_type in _cardinal_types:
310 return field.c_end_name + '(' + accum + ')'
312 return field.type.member.c_end_name + '(' + field.c_iterator_name + '(' + accum + '))'
314 def _c_iterator(self, name):
316 Declares the iterator structure and next/end functions for a given type.
321 _h(' * @brief %s', self.c_iterator_type)
323 _h('typedef struct %s {', self.c_iterator_type)
324 _h(' %s *data; /**< */', self.c_type)
325 _h(' int%s rem; /**< */', ' ' * (len(self.c_type) - 2))
326 _h(' int%s index; /**< */', ' ' * (len(self.c_type) - 2))
327 _h('} %s;', self.c_iterator_type)
333 _h(' * Get the next element of the iterator')
334 _h(' * @param i Pointer to a %s', self.c_iterator_type)
336 _h(' * Get the next element in the iterator. The member rem is')
337 _h(' * decreased by one. The member data points to the next')
338 _h(' * element. The member index is increased by sizeof(%s)', self.c_type)
342 _hc('/*****************************************************************************')
344 _hc(' ** void %s', self.c_next_name)
346 _hc(' ** @param %s *i', self.c_iterator_type)
347 _hc(' ** @returns void')
349 _hc(' *****************************************************************************/')
352 _h('%s (%s *i /**< */);', self.c_next_name, self.c_iterator_type)
353 _c('%s (%s *i /**< */)', self.c_next_name, self.c_iterator_type)
356 if not self.fixed_size():
357 _c(' %s *R = i->data;', self.c_type)
358 _c(' xcb_generic_iterator_t child = %s;', _c_iterator_get_end(self.last_varsized_field, 'R'))
360 _c(' i->data = (%s *) child.data;', self.c_type)
361 _c(' i->index = child.index;')
365 _c(' i->index += sizeof(%s);', self.c_type)
371 _h(' * Return the iterator pointing to the last element')
372 _h(' * @param i An %s', self.c_iterator_type)
373 _h(' * @return The iterator pointing to the last element')
375 _h(' * Set the current element in the iterator to the last element.')
376 _h(' * The member rem is set to 0. The member data points to the')
377 _h(' * last element.')
381 _hc('/*****************************************************************************')
383 _hc(' ** xcb_generic_iterator_t %s', self.c_end_name)
385 _hc(' ** @param %s i', self.c_iterator_type)
386 _hc(' ** @returns xcb_generic_iterator_t')
388 _hc(' *****************************************************************************/')
390 _hc('xcb_generic_iterator_t')
391 _h('%s (%s i /**< */);', self.c_end_name, self.c_iterator_type)
392 _c('%s (%s i /**< */)', self.c_end_name, self.c_iterator_type)
394 _c(' xcb_generic_iterator_t ret;')
396 if self.fixed_size():
397 _c(' ret.data = i.data + i.rem;')
398 _c(' ret.index = i.index + ((char *) ret.data - (char *) i.data);')
401 _c(' while(i.rem > 0)')
402 _c(' %s(&i);', self.c_next_name)
403 _c(' ret.data = i.data;')
404 _c(' ret.rem = i.rem;')
405 _c(' ret.index = i.index;')
410 def _c_accessor_get_length(expr, prefix=''):
412 Figures out what C code is needed to get a length field.
413 For fields that follow a variable-length field, use the accessor.
414 Otherwise, just reference the structure field directly.
416 prefarrow = '' if prefix == '' else prefix + '->'
418 if expr.lenfield != None and expr.lenfield.prev_varsized_field != None:
419 return expr.lenfield.c_accessor_name + '(' + prefix + ')'
420 elif expr.lenfield_name != None:
421 return prefarrow + expr.lenfield_name
423 return str(expr.nmemb)
425 def _c_accessor_get_expr(expr, prefix=''):
427 Figures out what C code is needed to get the length of a list field.
428 Recurses for math operations.
429 Returns bitcount for value-mask fields.
430 Otherwise, uses the value of the length field.
432 lenexp = _c_accessor_get_length(expr, prefix)
435 return '(' + _c_accessor_get_expr(expr.lhs, prefix) + ' ' + expr.op + ' ' + _c_accessor_get_expr(expr.rhs, prefix) + ')'
437 return 'xcb_popcount(' + lenexp + ')'
441 def _c_accessors_field(self, field):
443 Declares the accessor functions for a non-list field that follows a variable-length field.
445 if field.field_type[0] in _cardinal_types:
448 _hc('/*****************************************************************************')
450 _hc(' ** %s %s', field.c_field_type, field.c_accessor_name)
452 _hc(' ** @param const %s *R', self.c_type)
453 _hc(' ** @returns %s', field.c_field_type)
455 _hc(' *****************************************************************************/')
457 _hc('%s', field.c_field_type)
458 _h('%s (const %s *R /**< */);', field.c_accessor_name, self.c_type)
459 _c('%s (const %s *R /**< */)', field.c_accessor_name, self.c_type)
461 _c(' xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
462 _c(' return * (%s *) ((char *) prev.data + XCB_TYPE_PAD(%s, prev.index) + %d);', field.c_field_type, field.first_field_after_varsized.type.c_type, field.prev_varsized_offset)
467 _hc('/*****************************************************************************')
469 _hc(' ** %s * %s', field.c_field_type, field.c_accessor_name)
471 _hc(' ** @param const %s *R', self.c_type)
472 _hc(' ** @returns %s *', field.c_field_type)
474 _hc(' *****************************************************************************/')
476 _hc('%s *', field.c_field_type)
477 _h('%s (const %s *R /**< */);', field.c_accessor_name, self.c_type)
478 _c('%s (const %s *R /**< */)', field.c_accessor_name, self.c_type)
480 _c(' xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
481 _c(' return (%s *) ((char *) prev.data + XCB_TYPE_PAD(%s, prev.index) + %d);', field.c_field_type, field.first_field_after_varsized.type.c_type, field.prev_varsized_offset)
484 def _c_accessors_list(self, field):
486 Declares the accessor functions for a list field.
487 Declares a direct-accessor function only if the list members are fixed size.
488 Declares length and get-iterator functions always.
494 if list.member.fixed_size():
497 _hc('/*****************************************************************************')
499 _hc(' ** %s * %s', field.c_field_type, field.c_accessor_name)
501 _hc(' ** @param const %s *R', self.c_type)
502 _hc(' ** @returns %s *', field.c_field_type)
504 _hc(' *****************************************************************************/')
506 _hc('%s *', field.c_field_type)
507 _h('%s (const %s *R /**< */);', field.c_accessor_name, self.c_type)
508 _c('%s (const %s *R /**< */)', field.c_accessor_name, self.c_type)
511 if field.prev_varsized_field == None:
512 _c(' return (%s *) (R + 1);', field.c_field_type)
514 _c(' xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
515 _c(' return (%s *) ((char *) prev.data + XCB_TYPE_PAD(%s, prev.index) + %d);', field.c_field_type, field.first_field_after_varsized.type.c_type, field.prev_varsized_offset)
521 _hc('/*****************************************************************************')
523 _hc(' ** int %s', field.c_length_name)
525 _hc(' ** @param const %s *R', self.c_type)
526 _hc(' ** @returns int')
528 _hc(' *****************************************************************************/')
531 _h('%s (const %s *R /**< */);', field.c_length_name, self.c_type)
532 _c('%s (const %s *R /**< */)', field.c_length_name, self.c_type)
534 _c(' return %s;', _c_accessor_get_expr(field.type.expr, 'R'))
537 if field.field_type[0] in _cardinal_types:
540 _hc('/*****************************************************************************')
542 _hc(' ** xcb_generic_iterator_t %s', field.c_end_name)
544 _hc(' ** @param const %s *R', self.c_type)
545 _hc(' ** @returns xcb_generic_iterator_t')
547 _hc(' *****************************************************************************/')
549 _hc('xcb_generic_iterator_t')
550 _h('%s (const %s *R /**< */);', field.c_end_name, self.c_type)
551 _c('%s (const %s *R /**< */)', field.c_end_name, self.c_type)
553 _c(' xcb_generic_iterator_t i;')
555 if field.prev_varsized_field == None:
556 _c(' i.data = ((%s *) (R + 1)) + (%s);', field.type.c_wiretype, _c_accessor_get_expr(field.type.expr, 'R'))
558 _c(' xcb_generic_iterator_t child = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
559 _c(' i.data = ((%s *) child.data) + (%s);', field.type.c_wiretype, _c_accessor_get_expr(field.type.expr, 'R'))
562 _c(' i.index = (char *) i.data - (char *) R;')
569 _hc('/*****************************************************************************')
571 _hc(' ** %s %s', field.c_iterator_type, field.c_iterator_name)
573 _hc(' ** @param const %s *R', self.c_type)
574 _hc(' ** @returns %s', field.c_iterator_type)
576 _hc(' *****************************************************************************/')
578 _hc('%s', field.c_iterator_type)
579 _h('%s (const %s *R /**< */);', field.c_iterator_name, self.c_type)
580 _c('%s (const %s *R /**< */)', field.c_iterator_name, self.c_type)
582 _c(' %s i;', field.c_iterator_type)
584 if field.prev_varsized_field == None:
585 _c(' i.data = (%s *) (R + 1);', field.c_field_type)
587 _c(' xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
588 _c(' i.data = (%s *) ((char *) prev.data + XCB_TYPE_PAD(%s, prev.index));', field.c_field_type, field.c_field_type)
590 _c(' i.rem = %s;', _c_accessor_get_expr(field.type.expr, 'R'))
591 _c(' i.index = (char *) i.data - (char *) R;')
595 def _c_accessors(self, name, base):
597 Declares the accessor functions for the fields of a structure.
599 for field in self.fields:
600 if field.type.is_list and not field.type.fixed_size():
601 _c_accessors_list(self, field)
602 elif field.prev_varsized_field != None:
603 _c_accessors_field(self, field)
605 def c_simple(self, name):
607 Exported function that handles cardinal type declarations.
608 These are types which are typedef'd to one of the CARDx's, char, float, etc.
610 _c_type_setup(self, name, ())
612 if (self.name != name):
617 _h('typedef %s %s;', _t(self.name), my_name)
620 _c_iterator(self, name)
622 def _c_complex(self):
624 Helper function for handling all structure types.
625 Called for all structs, requests, replies, events, errors.
630 _h(' * @brief %s', self.c_type)
632 _h('typedef %s %s {', self.c_container, self.c_type)
637 for field in self.fields:
638 if not field.type.fixed_size():
641 struct_fields.append(field)
643 for field in struct_fields:
644 if len(field.c_field_type) > maxtypelen:
645 maxtypelen = len(field.c_field_type)
647 for field in struct_fields:
648 spacing = ' ' * (maxtypelen - len(field.c_field_type))
649 _h(' %s%s %s%s; /**< */', field.c_field_type, spacing, field.c_field_name, field.c_subscript)
651 _h('} %s;', self.c_type)
653 def c_struct(self, name):
655 Exported function that handles structure declarations.
657 _c_type_setup(self, name, ())
659 _c_accessors(self, name, name)
660 _c_iterator(self, name)
662 def c_union(self, name):
664 Exported function that handles union declarations.
666 _c_type_setup(self, name, ())
668 _c_iterator(self, name)
670 def _c_request_helper(self, name, cookie_type, void, regular):
672 Declares a request function.
675 # Four stunningly confusing possibilities here:
678 # ------------------------------
680 # 0 flag CHECKED flag Normal Mode
681 # void_cookie req_cookie
682 # ------------------------------
683 # "req_checked" "req_unchecked"
684 # CHECKED flag 0 flag Abnormal Mode
685 # void_cookie req_cookie
686 # ------------------------------
689 # Whether we are _checked or _unchecked
690 checked = void and not regular
691 unchecked = not void and not regular
693 # What kind of cookie we return
694 func_cookie = 'xcb_void_cookie_t' if void else self.c_cookie_type
696 # What flag is passed to xcb_request
697 func_flags = '0' if (void and regular) or (not void and not regular) else 'XCB_REQUEST_CHECKED'
699 # Global extension id variable or NULL for xproto
700 func_ext_global = '&' + _ns.c_ext_global_name if _ns.is_ext else '0'
702 # What our function name is
703 func_name = self.c_request_name
705 func_name = self.c_checked_name
707 func_name = self.c_unchecked_name
711 maxtypelen = len('xcb_connection_t')
713 for field in self.fields:
715 # The field should appear as a call parameter
716 param_fields.append(field)
717 if field.wire and not field.auto:
718 # We need to set the field up in the structure
719 wire_fields.append(field)
721 for field in param_fields:
722 if len(field.c_field_const_type) > maxtypelen:
723 maxtypelen = len(field.c_field_const_type)
729 _h(' * Delivers a request to the X server')
730 _h(' * @param c The connection')
731 _h(' * @return A cookie')
733 _h(' * Delivers a request to the X server.')
736 _h(' * This form can be used only if the request will not cause')
737 _h(' * a reply to be generated. Any returned error will be')
738 _h(' * saved for handling by xcb_request_check().')
740 _h(' * This form can be used only if the request will cause')
741 _h(' * a reply to be generated. Any returned error will be')
742 _h(' * placed in the event queue.')
746 _hc('/*****************************************************************************')
748 _hc(' ** %s %s', cookie_type, func_name)
751 spacing = ' ' * (maxtypelen - len('xcb_connection_t'))
752 _hc(' ** @param xcb_connection_t%s *c', spacing)
754 for field in param_fields:
755 spacing = ' ' * (maxtypelen - len(field.c_field_const_type))
756 _hc(' ** @param %s%s %s%s', field.c_field_const_type, spacing, field.c_pointer, field.c_field_name)
758 _hc(' ** @returns %s', cookie_type)
760 _hc(' *****************************************************************************/')
762 _hc('%s', cookie_type)
764 spacing = ' ' * (maxtypelen - len('xcb_connection_t'))
765 comma = ',' if len(param_fields) else ');'
766 _h('%s (xcb_connection_t%s *c /**< */%s', func_name, spacing, comma)
767 comma = ',' if len(param_fields) else ')'
768 _c('%s (xcb_connection_t%s *c /**< */%s', func_name, spacing, comma)
770 func_spacing = ' ' * (len(func_name) + 2)
771 count = len(param_fields)
772 for field in param_fields:
774 spacing = ' ' * (maxtypelen - len(field.c_field_const_type))
775 comma = ',' if count else ');'
776 _h('%s%s%s %s%s /**< */%s', func_spacing, field.c_field_const_type, spacing, field.c_pointer, field.c_field_name, comma)
777 comma = ',' if count else ')'
778 _c('%s%s%s %s%s /**< */%s', func_spacing, field.c_field_const_type, spacing, field.c_pointer, field.c_field_name, comma)
781 for field in param_fields:
782 if not field.type.fixed_size():
786 _c(' static const xcb_protocol_request_t xcb_req = {')
787 _c(' /* count */ %d,', count)
788 _c(' /* ext */ %s,', func_ext_global)
789 _c(' /* opcode */ %s,', self.c_request_name.upper())
790 _c(' /* isvoid */ %d', 1 if void else 0)
793 _c(' struct iovec xcb_parts[%d];', count + 2)
794 _c(' %s xcb_ret;', func_cookie)
795 _c(' %s xcb_out;', self.c_type)
798 for field in wire_fields:
799 if field.type.fixed_size():
800 if field.type.is_expr:
801 _c(' xcb_out.%s = %s;', field.c_field_name, _c_accessor_get_expr(field.type.expr))
803 elif field.type.is_pad:
804 if field.type.nmemb == 1:
805 _c(' xcb_out.%s = 0;', field.c_field_name)
807 _c(' memset(xcb_out.%s, 0, %d);', field.c_field_name, field.type.nmemb)
809 if field.type.nmemb == 1:
810 _c(' xcb_out.%s = %s;', field.c_field_name, field.c_field_name)
812 _c(' memcpy(xcb_out.%s, %s, %d);', field.c_field_name, field.c_field_name, field.type.nmemb)
815 _c(' xcb_parts[2].iov_base = (char *) &xcb_out;')
816 _c(' xcb_parts[2].iov_len = sizeof(xcb_out);')
817 _c(' xcb_parts[3].iov_base = 0;')
818 _c(' xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;')
821 for field in param_fields:
822 if not field.type.fixed_size():
823 _c(' xcb_parts[%d].iov_base = (char *) %s;', count, field.c_field_name)
824 if field.type.is_list:
825 _c(' xcb_parts[%d].iov_len = %s * sizeof(%s);', count, _c_accessor_get_expr(field.type.expr), field.type.member.c_wiretype)
827 _c(' xcb_parts[%d].iov_len = %s * sizeof(%s);', count, 'Uh oh', field.type.c_wiretype)
828 _c(' xcb_parts[%d].iov_base = 0;', count + 1)
829 _c(' xcb_parts[%d].iov_len = -xcb_parts[%d].iov_len & 3;', count + 1, count)
832 _c(' xcb_ret.sequence = xcb_send_request(c, %s, xcb_parts + 2, &xcb_req);', func_flags)
833 _c(' return xcb_ret;')
836 def _c_reply(self, name):
838 Declares the function that returns the reply structure.
840 spacing1 = ' ' * (len(self.c_cookie_type) - len('xcb_connection_t'))
841 spacing2 = ' ' * (len(self.c_cookie_type) - len('xcb_generic_error_t'))
842 spacing3 = ' ' * (len(self.c_reply_name) + 2)
846 _h(' * Return the reply')
847 _h(' * @param c The connection')
848 _h(' * @param cookie The cookie')
849 _h(' * @param e The xcb_generic_error_t supplied')
851 _h(' * Returns the reply of the request asked by')
853 _h(' * The parameter @p e supplied to this function must be NULL if')
854 _h(' * %s(). is used.', self.c_unchecked_name)
855 _h(' * Otherwise, it stores the error if any.')
857 _h(' * The returned value must be freed by the caller using free().')
861 _hc('/*****************************************************************************')
863 _hc(' ** %s * %s', self.c_reply_type, self.c_reply_name)
865 _hc(' ** @param xcb_connection_t%s *c', spacing1)
866 _hc(' ** @param %s cookie', self.c_cookie_type)
867 _hc(' ** @param xcb_generic_error_t%s **e', spacing2)
868 _hc(' ** @returns %s *', self.c_reply_type)
870 _hc(' *****************************************************************************/')
872 _hc('%s *', self.c_reply_type)
873 _hc('%s (xcb_connection_t%s *c /**< */,', self.c_reply_name, spacing1)
874 _hc('%s%s cookie /**< */,', spacing3, self.c_cookie_type)
875 _h('%sxcb_generic_error_t%s **e /**< */);', spacing3, spacing2)
876 _c('%sxcb_generic_error_t%s **e /**< */)', spacing3, spacing2)
878 _c(' return (%s *) xcb_wait_for_reply(c, cookie.sequence, e);', self.c_reply_type)
881 def _c_opcode(name, opcode):
883 Declares the opcode define for requests, events, and errors.
887 _h('/** Opcode for %s. */', _n(name))
888 _h('#define %s %s', _n(name).upper(), opcode)
890 def _c_cookie(self, name):
892 Declares the cookie type for a non-void request.
897 _h(' * @brief %s', self.c_cookie_type)
899 _h('typedef struct %s {', self.c_cookie_type)
900 _h(' unsigned int sequence; /**< */')
901 _h('} %s;', self.c_cookie_type)
903 def c_request(self, name):
905 Exported function that handles request declarations.
907 _c_type_setup(self, name, ('request',))
910 # Cookie type declaration
911 _c_cookie(self, name)
914 _c_opcode(name, self.opcode)
916 # Request structure declaration
920 _c_type_setup(self.reply, name, ('reply',))
921 # Reply structure definition
922 _c_complex(self.reply)
924 _c_request_helper(self, name, self.c_cookie_type, False, True)
925 _c_request_helper(self, name, self.c_cookie_type, False, False)
927 _c_accessors(self.reply, name + ('reply',), name)
931 _c_request_helper(self, name, 'xcb_void_cookie_t', True, False)
932 _c_request_helper(self, name, 'xcb_void_cookie_t', True, True)
934 def c_event(self, name):
936 Exported function that handles event declarations.
938 _c_type_setup(self, name, ('event',))
941 _c_opcode(name, self.opcodes[name])
943 if self.name == name:
944 # Structure definition
949 _h('typedef %s %s;', _t(self.name + ('event',)), _t(name + ('event',)))
951 def c_error(self, name):
953 Exported function that handles error declarations.
955 _c_type_setup(self, name, ('error',))
958 _c_opcode(name, self.opcodes[name])
960 if self.name == name:
961 # Structure definition
966 _h('typedef %s %s;', _t(self.name + ('error',)), _t(name + ('error',)))
969 # Main routine starts here
971 # Must create an "output" dictionary before any xcbgen imports.
972 output = {'open' : c_open,
978 'request' : c_request,
983 # Boilerplate below this point
985 # Import the module class
987 from xcbgen.state import Module
990 print 'Failed to load the xcbgen Python package!'
991 print 'Make sure that xcb/proto installed it on your Python path.'
992 print 'If not, you will need to create a .pth file or define $PYTHONPATH'
993 print 'to extend the path.'
994 print 'Refer to the README file in xcb/proto for more info.'
998 # Parse the xml header
999 module = Module(argv[1], output)
1001 # Build type-registry and resolve type dependencies