2 from xml.etree.cElementTree import *
3 from os.path import basename
8 # Jump to the bottom of this file for the main routine
10 # Some hacks to make the API more readable, and to keep backwards compability
11 _cname_re = re.compile('([A-Z0-9][a-z]+|[A-Z0-9]+(?![a-z])|[a-z]+)')
12 _cname_special_cases = {'DECnet':'decnet'}
14 _extension_special_cases = ['XPrint', 'XCMisc', 'BigRequests']
16 _cplusplus_annoyances = {'class' : '_class',
20 _cardinal_types = ['CARD8', 'uint8_t',
40 Writes the given line to the header file.
42 _hlines[_hlevel].append(fmt % args)
46 Writes the given line to the source file.
48 _clines[_clevel].append(fmt % args)
52 Writes the given line to both the header and source files.
57 # XXX See if this level thing is really necessary.
60 Changes the array that header lines are written to.
61 Supports writing different sections of the header file.
64 while len(_hlines) <= idx:
70 Changes the array that source lines are written to.
71 Supports writing to different sections of the source file.
74 while len(_clines) <= idx:
80 Does C-name conversion on a single string fragment.
81 Uses a regexp with some hard-coded special cases.
83 if str in _cname_special_cases:
84 return _cname_special_cases[str]
86 split = _cname_re.finditer(str)
87 name_parts = [match.group(0) for match in split]
88 return '_'.join(name_parts)
92 Checks for certain C++ reserved words and fixes them.
94 if str in _cplusplus_annoyances:
95 return _cplusplus_annoyances[str]
101 Does C-name conversion on an extension name.
102 Has some additional special cases on top of _n_item.
104 if str in _extension_special_cases:
105 return _n_item(str).lower()
111 Does C-name conversion on a tuple of strings.
112 Different behavior depending on length of tuple, extension/not extension, etc.
113 Basically C-name converts the individual pieces, then joins with underscores.
118 parts = [list[0], _n_item(list[1])]
120 parts = [list[0], _ext(list[1])] + [_n_item(i) for i in list[2:]]
122 parts = [list[0]] + [_n_item(i) for i in list[1:]]
123 return '_'.join(parts).lower()
127 Does C-name conversion on a tuple of strings representing a type.
128 Same as _n but adds a "_t" on the end.
133 parts = [list[0], _n_item(list[1]), 't']
135 parts = [list[0], _ext(list[1])] + [_n_item(i) for i in list[2:]] + ['t']
137 parts = [list[0]] + [_n_item(i) for i in list[1:]] + ['t']
138 return '_'.join(parts).lower()
143 Exported function that handles module open.
144 Opens the files and writes out the auto-generated comment, header file includes, etc.
148 _ns.c_ext_global_name = _n(_ns.prefix + ('id',))
154 _hc(' * This file generated automatically from %s by c_client.py.', _ns.file)
155 _hc(' * Edit at your peril.')
160 _h(' * @defgroup XCB_%s_API XCB %s API', _ns.ext_name, _ns.ext_name)
161 _h(' * @brief %s XCB Protocol Implementation.', _ns.ext_name)
165 _h('#ifndef __%s_H', _ns.header.upper())
166 _h('#define __%s_H', _ns.header.upper())
168 _h('#include "xcb.h"')
170 _c('#include <string.h>')
171 _c('#include <assert.h>')
172 _c('#include "xcbext.h"')
173 _c('#include "%s.h"', _ns.header)
176 for (n, h) in self.imports:
177 _hc('#include "%s.h"', h)
180 _h('#define XCB_%s_MAJOR_VERSION %s', _ns.ext_name.upper(), _ns.major_version)
181 _h('#define XCB_%s_MINOR_VERSION %s', _ns.ext_name.upper(), _ns.minor_version)
183 _h('extern xcb_extension_t %s;', _ns.c_ext_global_name)
186 _c('xcb_extension_t %s = { "%s" };', _ns.c_ext_global_name, _ns.ext_xname)
190 Exported function that handles module close.
191 Writes out all the stored content lines, then closes the files.
204 hfile = open('%s.h' % _ns.header, 'w')
212 cfile = open('%s.c' % _ns.header, 'w')
219 def c_enum(self, name):
221 Exported function that handles enum declarations.
225 _h('typedef enum %s {', _t(name))
227 count = len(self.values)
229 for (enam, eval) in self.values:
231 equals = ' = ' if eval != '' else ''
232 comma = ',' if count > 0 else ''
233 _h(' %s%s%s%s', _n(name + (enam,)).upper(), equals, eval, comma)
235 _h('} %s;', _t(name))
237 def _c_type_setup(self, name, postfix):
239 Sets up all the C-related state by adding additional data fields to
240 all Field and Type objects. Here is where we figure out most of our
241 variable and function names.
243 Recurses into child fields and list member types.
245 # Do all the various names in advance
246 self.c_type = _t(name + postfix)
247 self.c_wiretype = 'char' if self.c_type == 'void' else self.c_type
249 self.c_iterator_type = _t(name + ('iterator',))
250 self.c_next_name = _n(name + ('next',))
251 self.c_end_name = _n(name + ('end',))
253 self.c_request_name = _n(name)
254 self.c_checked_name = _n(name + ('checked',))
255 self.c_unchecked_name = _n(name + ('unchecked',))
256 self.c_reply_name = _n(name + ('reply',))
257 self.c_reply_type = _t(name + ('reply',))
258 self.c_cookie_type = _t(name + ('cookie',))
260 if self.is_container:
262 self.c_container = 'union' if self.is_union else 'struct'
263 prev_varsized_field = None
264 prev_varsized_offset = 0
265 first_field_after_varsized = None
267 for field in self.fields:
268 _c_type_setup(field.type, field.field_type, ())
269 if field.type.is_list:
270 _c_type_setup(field.type.member, field.field_type, ())
272 field.c_field_type = _t(field.field_type)
273 field.c_field_const_type = ('' if field.type.nmemb == 1 else 'const ') + field.c_field_type
274 field.c_field_name = _cpp(field.field_name)
275 field.c_subscript = '[%d]' % field.type.nmemb if (field.type.nmemb > 1) else ''
276 field.c_pointer = ' ' if field.type.nmemb == 1 else '*'
278 field.c_iterator_type = _t(field.field_type + ('iterator',)) # xcb_fieldtype_iterator_t
279 field.c_iterator_name = _n(name + (field.field_name, 'iterator')) # xcb_container_field_iterator
280 field.c_accessor_name = _n(name + (field.field_name,)) # xcb_container_field
281 field.c_length_name = _n(name + (field.field_name, 'length')) # xcb_container_field_length
282 field.c_end_name = _n(name + (field.field_name, 'end')) # xcb_container_field_end
284 field.prev_varsized_field = prev_varsized_field
285 field.prev_varsized_offset = prev_varsized_offset
287 if prev_varsized_offset == 0:
288 first_field_after_varsized = field
289 field.first_field_after_varsized = first_field_after_varsized
291 if field.type.fixed_size():
292 prev_varsized_offset += field.type.size
294 self.last_varsized_field = field
295 prev_varsized_field = field
296 prev_varsized_offset = 0
298 def _c_iterator_get_end(field, accum):
300 Figures out what C code is needed to find the end of a variable-length structure field.
301 For nested structures, recurses into its last variable-sized field.
302 For lists, calls the end function
304 if field.type.is_container:
305 accum = field.c_accessor_name + '(' + accum + ')'
306 # XXX there could be fixed-length fields at the end
307 return _c_iterator_get_end(field.type.last_varsized_field, accum)
308 if field.type.is_list:
309 # XXX we can always use the first way
310 if field.type.c_type in _cardinal_types:
311 return field.c_end_name + '(' + accum + ')'
313 return field.type.member.c_end_name + '(' + field.c_iterator_name + '(' + accum + '))'
315 def _c_iterator(self, name):
317 Declares the iterator structure and next/end functions for a given type.
322 _h(' * @brief %s', self.c_iterator_type)
324 _h('typedef struct %s {', self.c_iterator_type)
325 _h(' %s *data; /**< */', self.c_type)
326 _h(' int%s rem; /**< */', ' ' * (len(self.c_type) - 2))
327 _h(' int%s index; /**< */', ' ' * (len(self.c_type) - 2))
328 _h('} %s;', self.c_iterator_type)
334 _h(' * Get the next element of the iterator')
335 _h(' * @param i Pointer to a %s', self.c_iterator_type)
337 _h(' * Get the next element in the iterator. The member rem is')
338 _h(' * decreased by one. The member data points to the next')
339 _h(' * element. The member index is increased by sizeof(%s)', self.c_type)
343 _hc('/*****************************************************************************')
345 _hc(' ** void %s', self.c_next_name)
347 _hc(' ** @param %s *i', self.c_iterator_type)
348 _hc(' ** @returns void')
350 _hc(' *****************************************************************************/')
353 _h('%s (%s *i /**< */);', self.c_next_name, self.c_iterator_type)
354 _c('%s (%s *i /**< */)', self.c_next_name, self.c_iterator_type)
357 if not self.fixed_size():
358 _c(' %s *R = i->data;', self.c_type)
359 _c(' xcb_generic_iterator_t child = %s;', _c_iterator_get_end(self.last_varsized_field, 'R'))
361 _c(' i->data = (%s *) child.data;', self.c_type)
362 _c(' i->index = child.index;')
366 _c(' i->index += sizeof(%s);', self.c_type)
372 _h(' * Return the iterator pointing to the last element')
373 _h(' * @param i An %s', self.c_iterator_type)
374 _h(' * @return The iterator pointing to the last element')
376 _h(' * Set the current element in the iterator to the last element.')
377 _h(' * The member rem is set to 0. The member data points to the')
378 _h(' * last element.')
382 _hc('/*****************************************************************************')
384 _hc(' ** xcb_generic_iterator_t %s', self.c_end_name)
386 _hc(' ** @param %s i', self.c_iterator_type)
387 _hc(' ** @returns xcb_generic_iterator_t')
389 _hc(' *****************************************************************************/')
391 _hc('xcb_generic_iterator_t')
392 _h('%s (%s i /**< */);', self.c_end_name, self.c_iterator_type)
393 _c('%s (%s i /**< */)', self.c_end_name, self.c_iterator_type)
395 _c(' xcb_generic_iterator_t ret;')
397 if self.fixed_size():
398 _c(' ret.data = i.data + i.rem;')
399 _c(' ret.index = i.index + ((char *) ret.data - (char *) i.data);')
402 _c(' while(i.rem > 0)')
403 _c(' %s(&i);', self.c_next_name)
404 _c(' ret.data = i.data;')
405 _c(' ret.rem = i.rem;')
406 _c(' ret.index = i.index;')
411 def _c_accessor_get_length(expr, prefix=''):
413 Figures out what C code is needed to get a length field.
414 For fields that follow a variable-length field, use the accessor.
415 Otherwise, just reference the structure field directly.
417 prefarrow = '' if prefix == '' else prefix + '->'
419 if expr.lenfield != None and expr.lenfield.prev_varsized_field != None:
420 return expr.lenfield.c_accessor_name + '(' + prefix + ')'
421 elif expr.lenfield_name != None:
422 return prefarrow + expr.lenfield_name
424 return str(expr.nmemb)
426 def _c_accessor_get_expr(expr, prefix=''):
428 Figures out what C code is needed to get the length of a list field.
429 Recurses for math operations.
430 Returns bitcount for value-mask fields.
431 Otherwise, uses the value of the length field.
433 lenexp = _c_accessor_get_length(expr, prefix)
436 return '(' + _c_accessor_get_expr(expr.lhs, prefix) + ' ' + expr.op + ' ' + _c_accessor_get_expr(expr.rhs, prefix) + ')'
438 return 'xcb_popcount(' + lenexp + ')'
442 def _c_accessors_field(self, field):
444 Declares the accessor functions for a non-list field that follows a variable-length field.
446 if field.field_type[0] in _cardinal_types:
449 _hc('/*****************************************************************************')
451 _hc(' ** %s %s', field.c_field_type, field.c_accessor_name)
453 _hc(' ** @param const %s *R', self.c_type)
454 _hc(' ** @returns %s', field.c_field_type)
456 _hc(' *****************************************************************************/')
458 _hc('%s', field.c_field_type)
459 _h('%s (const %s *R /**< */);', field.c_accessor_name, self.c_type)
460 _c('%s (const %s *R /**< */)', field.c_accessor_name, self.c_type)
462 _c(' xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
463 _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)
468 _hc('/*****************************************************************************')
470 _hc(' ** %s * %s', field.c_field_type, field.c_accessor_name)
472 _hc(' ** @param const %s *R', self.c_type)
473 _hc(' ** @returns %s *', field.c_field_type)
475 _hc(' *****************************************************************************/')
477 _hc('%s *', field.c_field_type)
478 _h('%s (const %s *R /**< */);', field.c_accessor_name, self.c_type)
479 _c('%s (const %s *R /**< */)', field.c_accessor_name, self.c_type)
481 _c(' xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
482 _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)
485 def _c_accessors_list(self, field):
487 Declares the accessor functions for a list field.
488 Declares a direct-accessor function only if the list members are fixed size.
489 Declares length and get-iterator functions always.
495 if list.member.fixed_size():
498 _hc('/*****************************************************************************')
500 _hc(' ** %s * %s', field.c_field_type, field.c_accessor_name)
502 _hc(' ** @param const %s *R', self.c_type)
503 _hc(' ** @returns %s *', field.c_field_type)
505 _hc(' *****************************************************************************/')
507 _hc('%s *', field.c_field_type)
508 _h('%s (const %s *R /**< */);', field.c_accessor_name, self.c_type)
509 _c('%s (const %s *R /**< */)', field.c_accessor_name, self.c_type)
512 if field.prev_varsized_field == None:
513 _c(' return (%s *) (R + 1);', field.c_field_type)
515 _c(' xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
516 _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)
522 _hc('/*****************************************************************************')
524 _hc(' ** int %s', field.c_length_name)
526 _hc(' ** @param const %s *R', self.c_type)
527 _hc(' ** @returns int')
529 _hc(' *****************************************************************************/')
532 _h('%s (const %s *R /**< */);', field.c_length_name, self.c_type)
533 _c('%s (const %s *R /**< */)', field.c_length_name, self.c_type)
535 _c(' return %s;', _c_accessor_get_expr(field.type.expr, 'R'))
538 if field.field_type[0] in _cardinal_types:
541 _hc('/*****************************************************************************')
543 _hc(' ** xcb_generic_iterator_t %s', field.c_end_name)
545 _hc(' ** @param const %s *R', self.c_type)
546 _hc(' ** @returns xcb_generic_iterator_t')
548 _hc(' *****************************************************************************/')
550 _hc('xcb_generic_iterator_t')
551 _h('%s (const %s *R /**< */);', field.c_end_name, self.c_type)
552 _c('%s (const %s *R /**< */)', field.c_end_name, self.c_type)
554 _c(' xcb_generic_iterator_t i;')
556 if field.prev_varsized_field == None:
557 _c(' i.data = ((%s *) (R + 1)) + (%s);', field.type.c_wiretype, _c_accessor_get_expr(field.type.expr, 'R'))
559 _c(' xcb_generic_iterator_t child = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
560 _c(' i.data = ((%s *) child.data) + (%s);', field.type.c_wiretype, _c_accessor_get_expr(field.type.expr, 'R'))
563 _c(' i.index = (char *) i.data - (char *) R;')
570 _hc('/*****************************************************************************')
572 _hc(' ** %s %s', field.c_iterator_type, field.c_iterator_name)
574 _hc(' ** @param const %s *R', self.c_type)
575 _hc(' ** @returns %s', field.c_iterator_type)
577 _hc(' *****************************************************************************/')
579 _hc('%s', field.c_iterator_type)
580 _h('%s (const %s *R /**< */);', field.c_iterator_name, self.c_type)
581 _c('%s (const %s *R /**< */)', field.c_iterator_name, self.c_type)
583 _c(' %s i;', field.c_iterator_type)
585 if field.prev_varsized_field == None:
586 _c(' i.data = (%s *) (R + 1);', field.c_field_type)
588 _c(' xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
589 _c(' i.data = (%s *) ((char *) prev.data + XCB_TYPE_PAD(%s, prev.index));', field.c_field_type, field.c_field_type)
591 _c(' i.rem = %s;', _c_accessor_get_expr(field.type.expr, 'R'))
592 _c(' i.index = (char *) i.data - (char *) R;')
596 def _c_accessors(self, name, base):
598 Declares the accessor functions for the fields of a structure.
600 for field in self.fields:
601 if field.type.is_list and not field.type.fixed_size():
602 _c_accessors_list(self, field)
603 elif field.prev_varsized_field != None:
604 _c_accessors_field(self, field)
606 def c_simple(self, name):
608 Exported function that handles cardinal type declarations.
609 These are types which are typedef'd to one of the CARDx's, char, float, etc.
611 _c_type_setup(self, name, ())
613 if (self.name != name):
618 _h('typedef %s %s;', _t(self.name), my_name)
621 _c_iterator(self, name)
623 def _c_complex(self):
625 Helper function for handling all structure types.
626 Called for all structs, requests, replies, events, errors.
631 _h(' * @brief %s', self.c_type)
633 _h('typedef %s %s {', self.c_container, self.c_type)
638 for field in self.fields:
639 if not field.type.fixed_size():
642 struct_fields.append(field)
644 for field in struct_fields:
645 if len(field.c_field_type) > maxtypelen:
646 maxtypelen = len(field.c_field_type)
648 for field in struct_fields:
649 spacing = ' ' * (maxtypelen - len(field.c_field_type))
650 _h(' %s%s %s%s; /**< */', field.c_field_type, spacing, field.c_field_name, field.c_subscript)
652 _h('} %s;', self.c_type)
654 def c_struct(self, name):
656 Exported function that handles structure declarations.
658 _c_type_setup(self, name, ())
660 _c_accessors(self, name, name)
661 _c_iterator(self, name)
663 def c_union(self, name):
665 Exported function that handles union declarations.
667 _c_type_setup(self, name, ())
669 _c_iterator(self, name)
671 def _c_request_helper(self, name, cookie_type, void, regular):
673 Declares a request function.
676 # Four stunningly confusing possibilities here:
679 # ------------------------------
681 # 0 flag CHECKED flag Normal Mode
682 # void_cookie req_cookie
683 # ------------------------------
684 # "req_checked" "req_unchecked"
685 # CHECKED flag 0 flag Abnormal Mode
686 # void_cookie req_cookie
687 # ------------------------------
690 # Whether we are _checked or _unchecked
691 checked = void and not regular
692 unchecked = not void and not regular
694 # What kind of cookie we return
695 func_cookie = 'xcb_void_cookie_t' if void else self.c_cookie_type
697 # What flag is passed to xcb_request
698 func_flags = '0' if (void and regular) or (not void and not regular) else 'XCB_REQUEST_CHECKED'
700 # Global extension id variable or NULL for xproto
701 func_ext_global = '&' + _ns.c_ext_global_name if _ns.is_ext else '0'
703 # What our function name is
704 func_name = self.c_request_name
706 func_name = self.c_checked_name
708 func_name = self.c_unchecked_name
712 maxtypelen = len('xcb_connection_t')
714 for field in self.fields:
716 # The field should appear as a call parameter
717 param_fields.append(field)
718 if field.wire and not field.auto:
719 # We need to set the field up in the structure
720 wire_fields.append(field)
722 for field in param_fields:
723 if len(field.c_field_const_type) > maxtypelen:
724 maxtypelen = len(field.c_field_const_type)
730 _h(' * Delivers a request to the X server')
731 _h(' * @param c The connection')
732 _h(' * @return A cookie')
734 _h(' * Delivers a request to the X server.')
737 _h(' * This form can be used only if the request will not cause')
738 _h(' * a reply to be generated. Any returned error will be')
739 _h(' * saved for handling by xcb_request_check().')
741 _h(' * This form can be used only if the request will cause')
742 _h(' * a reply to be generated. Any returned error will be')
743 _h(' * placed in the event queue.')
747 _hc('/*****************************************************************************')
749 _hc(' ** %s %s', cookie_type, func_name)
752 spacing = ' ' * (maxtypelen - len('xcb_connection_t'))
753 _hc(' ** @param xcb_connection_t%s *c', spacing)
755 for field in param_fields:
756 spacing = ' ' * (maxtypelen - len(field.c_field_const_type))
757 _hc(' ** @param %s%s %s%s', field.c_field_const_type, spacing, field.c_pointer, field.c_field_name)
759 _hc(' ** @returns %s', cookie_type)
761 _hc(' *****************************************************************************/')
763 _hc('%s', cookie_type)
765 spacing = ' ' * (maxtypelen - len('xcb_connection_t'))
766 comma = ',' if len(param_fields) else ');'
767 _h('%s (xcb_connection_t%s *c /**< */%s', func_name, spacing, comma)
768 comma = ',' if len(param_fields) else ')'
769 _c('%s (xcb_connection_t%s *c /**< */%s', func_name, spacing, comma)
771 func_spacing = ' ' * (len(func_name) + 2)
772 count = len(param_fields)
773 for field in param_fields:
775 spacing = ' ' * (maxtypelen - len(field.c_field_const_type))
776 comma = ',' if count else ');'
777 _h('%s%s%s %s%s /**< */%s', func_spacing, field.c_field_const_type, spacing, field.c_pointer, field.c_field_name, comma)
778 comma = ',' if count else ')'
779 _c('%s%s%s %s%s /**< */%s', func_spacing, field.c_field_const_type, spacing, field.c_pointer, field.c_field_name, comma)
782 for field in param_fields:
783 if not field.type.fixed_size():
787 _c(' static const xcb_protocol_request_t xcb_req = {')
788 _c(' /* count */ %d,', count)
789 _c(' /* ext */ %s,', func_ext_global)
790 _c(' /* opcode */ %s,', self.c_request_name.upper())
791 _c(' /* isvoid */ %d', 1 if void else 0)
794 _c(' struct iovec xcb_parts[%d];', count + 2)
795 _c(' %s xcb_ret;', func_cookie)
796 _c(' %s xcb_out;', self.c_type)
799 for field in wire_fields:
800 if field.type.fixed_size():
801 if field.type.is_expr:
802 _c(' xcb_out.%s = %s;', field.c_field_name, _c_accessor_get_expr(field.type.expr))
804 elif field.type.is_pad:
805 if field.type.nmemb == 1:
806 _c(' xcb_out.%s = 0;', field.c_field_name)
808 _c(' memset(xcb_out.%s, 0, %d);', field.c_field_name, field.type.nmemb)
810 if field.type.nmemb == 1:
811 _c(' xcb_out.%s = %s;', field.c_field_name, field.c_field_name)
813 _c(' memcpy(xcb_out.%s, %s, %d);', field.c_field_name, field.c_field_name, field.type.nmemb)
816 _c(' xcb_parts[2].iov_base = (char *) &xcb_out;')
817 _c(' xcb_parts[2].iov_len = sizeof(xcb_out);')
818 _c(' xcb_parts[3].iov_base = 0;')
819 _c(' xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;')
822 for field in param_fields:
823 if not field.type.fixed_size():
824 _c(' xcb_parts[%d].iov_base = (char *) %s;', count, field.c_field_name)
825 if field.type.is_list:
826 _c(' xcb_parts[%d].iov_len = %s * sizeof(%s);', count, _c_accessor_get_expr(field.type.expr), field.type.member.c_wiretype)
828 _c(' xcb_parts[%d].iov_len = %s * sizeof(%s);', count, 'Uh oh', field.type.c_wiretype)
829 _c(' xcb_parts[%d].iov_base = 0;', count + 1)
830 _c(' xcb_parts[%d].iov_len = -xcb_parts[%d].iov_len & 3;', count + 1, count)
833 _c(' xcb_ret.sequence = xcb_send_request(c, %s, xcb_parts + 2, &xcb_req);', func_flags)
834 _c(' return xcb_ret;')
837 def _c_reply(self, name):
839 Declares the function that returns the reply structure.
841 spacing1 = ' ' * (len(self.c_cookie_type) - len('xcb_connection_t'))
842 spacing2 = ' ' * (len(self.c_cookie_type) - len('xcb_generic_error_t'))
843 spacing3 = ' ' * (len(self.c_reply_name) + 2)
847 _h(' * Return the reply')
848 _h(' * @param c The connection')
849 _h(' * @param cookie The cookie')
850 _h(' * @param e The xcb_generic_error_t supplied')
852 _h(' * Returns the reply of the request asked by')
854 _h(' * The parameter @p e supplied to this function must be NULL if')
855 _h(' * %s(). is used.', self.c_unchecked_name)
856 _h(' * Otherwise, it stores the error if any.')
858 _h(' * The returned value must be freed by the caller using free().')
862 _hc('/*****************************************************************************')
864 _hc(' ** %s * %s', self.c_reply_type, self.c_reply_name)
866 _hc(' ** @param xcb_connection_t%s *c', spacing1)
867 _hc(' ** @param %s cookie', self.c_cookie_type)
868 _hc(' ** @param xcb_generic_error_t%s **e', spacing2)
869 _hc(' ** @returns %s *', self.c_reply_type)
871 _hc(' *****************************************************************************/')
873 _hc('%s *', self.c_reply_type)
874 _hc('%s (xcb_connection_t%s *c /**< */,', self.c_reply_name, spacing1)
875 _hc('%s%s cookie /**< */,', spacing3, self.c_cookie_type)
876 _h('%sxcb_generic_error_t%s **e /**< */);', spacing3, spacing2)
877 _c('%sxcb_generic_error_t%s **e /**< */)', spacing3, spacing2)
879 _c(' return (%s *) xcb_wait_for_reply(c, cookie.sequence, e);', self.c_reply_type)
882 def _c_opcode(name, opcode):
884 Declares the opcode define for requests, events, and errors.
888 _h('/** Opcode for %s. */', _n(name))
889 _h('#define %s %s', _n(name).upper(), opcode)
891 def _c_cookie(self, name):
893 Declares the cookie type for a non-void request.
898 _h(' * @brief %s', self.c_cookie_type)
900 _h('typedef struct %s {', self.c_cookie_type)
901 _h(' unsigned int sequence; /**< */')
902 _h('} %s;', self.c_cookie_type)
904 def c_request(self, name):
906 Exported function that handles request declarations.
908 _c_type_setup(self, name, ('request',))
911 # Cookie type declaration
912 _c_cookie(self, name)
915 _c_opcode(name, self.opcode)
917 # Request structure declaration
921 _c_type_setup(self.reply, name, ('reply',))
922 # Reply structure definition
923 _c_complex(self.reply)
925 _c_request_helper(self, name, self.c_cookie_type, False, True)
926 _c_request_helper(self, name, self.c_cookie_type, False, False)
928 _c_accessors(self.reply, name + ('reply',), name)
932 _c_request_helper(self, name, 'xcb_void_cookie_t', True, False)
933 _c_request_helper(self, name, 'xcb_void_cookie_t', True, True)
935 def c_event(self, name):
937 Exported function that handles event declarations.
939 _c_type_setup(self, name, ('event',))
942 _c_opcode(name, self.opcodes[name])
944 if self.name == name:
945 # Structure definition
950 _h('typedef %s %s;', _t(self.name + ('event',)), _t(name + ('event',)))
952 def c_error(self, name):
954 Exported function that handles error declarations.
956 _c_type_setup(self, name, ('error',))
959 _c_opcode(name, self.opcodes[name])
961 if self.name == name:
962 # Structure definition
967 _h('typedef %s %s;', _t(self.name + ('error',)), _t(name + ('error',)))
970 # Main routine starts here
972 # Must create an "output" dictionary before any xcbgen imports.
973 output = {'open' : c_open,
979 'request' : c_request,
984 # Boilerplate below this point
986 # Check for the argument that specifies path to the xcbgen python package.
988 opts, args = getopt.getopt(sys.argv[1:], 'p:')
989 except getopt.GetoptError, err:
991 print 'Usage: c_client.py [-p path] file.xml'
994 for (opt, arg) in opts:
998 # Import the module class
1000 from xcbgen.state import Module
1003 print 'Failed to load the xcbgen Python package!'
1004 print 'Make sure that xcb/proto installed it on your Python path.'
1005 print 'If not, you will need to create a .pth file or define $PYTHONPATH'
1006 print 'to extend the path.'
1007 print 'Refer to the README file in xcb/proto for more info.'
1011 # Parse the xml header
1012 module = Module(args[0], output)
1014 # Build type-registry and resolve type dependencies