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',
28 Writes the given line to the header file.
30 _hlines[_hlevel].append(fmt % args)
34 Writes the given line to the source file.
36 _clines[_clevel].append(fmt % args)
40 Writes the given line to both the header and source files.
45 # XXX See if this level thing is really necessary.
48 Changes the array that header lines are written to.
49 Supports writing different sections of the header file.
52 while len(_hlines) <= idx:
58 Changes the array that source lines are written to.
59 Supports writing to different sections of the source file.
62 while len(_clines) <= idx:
68 Does C-name conversion on a single string fragment.
69 Uses a regexp with some hard-coded special cases.
71 if str in _cname_special_cases:
72 return _cname_special_cases[str]
74 split = _cname_re.finditer(str)
75 name_parts = [match.group(0) for match in split]
76 return '_'.join(name_parts)
80 Checks for certain C++ reserved words and fixes them.
82 if str in _cplusplus_annoyances:
83 return _cplusplus_annoyances[str]
89 Does C-name conversion on an extension name.
90 Has some additional special cases on top of _n_item.
92 if str in _extension_special_cases:
93 return _n_item(str).lower()
99 Does C-name conversion on a tuple of strings.
100 Different behavior depending on length of tuple, extension/not extension, etc.
101 Basically C-name converts the individual pieces, then joins with underscores.
106 parts = [list[0], _n_item(list[1])]
108 parts = [list[0], _ext(list[1])] + [_n_item(i) for i in list[2:]]
110 parts = [list[0]] + [_n_item(i) for i in list[1:]]
111 return '_'.join(parts).lower()
115 Does C-name conversion on a tuple of strings representing a type.
116 Same as _n but adds a "_t" on the end.
121 parts = [list[0], _n_item(list[1]), 't']
123 parts = [list[0], _ext(list[1])] + [_n_item(i) for i in list[2:]] + ['t']
125 parts = [list[0]] + [_n_item(i) for i in list[1:]] + ['t']
126 return '_'.join(parts).lower()
131 Exported function that handles module open.
132 Opens the files and writes out the auto-generated comment, header file includes, etc.
136 _ns.c_ext_global_name = _n(_ns.prefix + ('id',))
142 _hc(' * This file generated automatically from %s by c_client.py.', _ns.file)
143 _hc(' * Edit at your peril.')
148 _h(' * @defgroup XCB_%s_API XCB %s API', _ns.ext_name, _ns.ext_name)
149 _h(' * @brief %s XCB Protocol Implementation.', _ns.ext_name)
153 _h('#ifndef __%s_H', _ns.header.upper())
154 _h('#define __%s_H', _ns.header.upper())
156 _h('#include "xcb.h"')
158 _c('#include <string.h>')
159 _c('#include <assert.h>')
160 _c('#include "xcbext.h"')
161 _c('#include "%s.h"', _ns.header)
164 for (n, h) in self.imports:
165 _hc('#include "%s.h"', h)
168 _h('#ifdef __cplusplus')
174 _h('#define XCB_%s_MAJOR_VERSION %s', _ns.ext_name.upper(), _ns.major_version)
175 _h('#define XCB_%s_MINOR_VERSION %s', _ns.ext_name.upper(), _ns.minor_version)
177 _h('extern xcb_extension_t %s;', _ns.c_ext_global_name)
180 _c('xcb_extension_t %s = { "%s", 0 };', _ns.c_ext_global_name, _ns.ext_xname)
184 Exported function that handles module close.
185 Writes out all the stored content lines, then closes the files.
192 _h('#ifdef __cplusplus')
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.
228 for (enam, eval) in self.values:
233 _h('static const uint32_t %s = %d;', _n(name + (enam,)).upper(), next)
235 def _c_type_setup(self, name, postfix):
237 Sets up all the C-related state by adding additional data fields to
238 all Field and Type objects. Here is where we figure out most of our
239 variable and function names.
241 Recurses into child fields and list member types.
243 # Do all the various names in advance
244 self.c_type = _t(name + postfix)
245 self.c_wiretype = 'char' if self.c_type == 'void' else self.c_type
247 self.c_iterator_type = _t(name + ('iterator',))
248 self.c_next_name = _n(name + ('next',))
249 self.c_end_name = _n(name + ('end',))
251 self.c_request_name = _n(name)
252 self.c_checked_name = _n(name + ('checked',))
253 self.c_unchecked_name = _n(name + ('unchecked',))
254 self.c_reply_name = _n(name + ('reply',))
255 self.c_reply_type = _t(name + ('reply',))
256 self.c_cookie_type = _t(name + ('cookie',))
258 if self.is_container:
260 self.c_container = 'union' if self.is_union else 'struct'
261 prev_varsized_field = None
262 prev_varsized_offset = 0
263 first_field_after_varsized = None
265 for field in self.fields:
266 _c_type_setup(field.type, field.field_type, ())
267 if field.type.is_list:
268 _c_type_setup(field.type.member, field.field_type, ())
270 field.c_field_type = _t(field.field_type)
271 field.c_field_const_type = ('' if field.type.nmemb == 1 else 'const ') + field.c_field_type
272 field.c_field_name = _cpp(field.field_name)
273 field.c_subscript = '[%d]' % field.type.nmemb if (field.type.nmemb > 1) else ''
274 field.c_pointer = ' ' if field.type.nmemb == 1 else '*'
276 field.c_iterator_type = _t(field.field_type + ('iterator',)) # xcb_fieldtype_iterator_t
277 field.c_iterator_name = _n(name + (field.field_name, 'iterator')) # xcb_container_field_iterator
278 field.c_accessor_name = _n(name + (field.field_name,)) # xcb_container_field
279 field.c_length_name = _n(name + (field.field_name, 'length')) # xcb_container_field_length
280 field.c_end_name = _n(name + (field.field_name, 'end')) # xcb_container_field_end
282 field.prev_varsized_field = prev_varsized_field
283 field.prev_varsized_offset = prev_varsized_offset
285 if prev_varsized_offset == 0:
286 first_field_after_varsized = field
287 field.first_field_after_varsized = first_field_after_varsized
289 if field.type.fixed_size():
290 prev_varsized_offset += field.type.size
292 self.last_varsized_field = field
293 prev_varsized_field = field
294 prev_varsized_offset = 0
296 def _c_iterator_get_end(field, accum):
298 Figures out what C code is needed to find the end of a variable-length structure field.
299 For nested structures, recurses into its last variable-sized field.
300 For lists, calls the end function
302 if field.type.is_container:
303 accum = field.c_accessor_name + '(' + accum + ')'
304 # XXX there could be fixed-length fields at the end
305 return _c_iterator_get_end(field.type.last_varsized_field, accum)
306 if field.type.is_list:
307 # XXX we can always use the first way
308 if field.type.member.is_simple:
309 return field.c_end_name + '(' + accum + ')'
311 return field.type.member.c_end_name + '(' + field.c_iterator_name + '(' + accum + '))'
313 def _c_iterator(self, name):
315 Declares the iterator structure and next/end functions for a given type.
320 _h(' * @brief %s', self.c_iterator_type)
322 _h('typedef struct %s {', self.c_iterator_type)
323 _h(' %s *data; /**< */', self.c_type)
324 _h(' int%s rem; /**< */', ' ' * (len(self.c_type) - 2))
325 _h(' int%s index; /**< */', ' ' * (len(self.c_type) - 2))
326 _h('} %s;', self.c_iterator_type)
332 _h(' * Get the next element of the iterator')
333 _h(' * @param i Pointer to a %s', self.c_iterator_type)
335 _h(' * Get the next element in the iterator. The member rem is')
336 _h(' * decreased by one. The member data points to the next')
337 _h(' * element. The member index is increased by sizeof(%s)', self.c_type)
341 _hc('/*****************************************************************************')
343 _hc(' ** void %s', self.c_next_name)
345 _hc(' ** @param %s *i', self.c_iterator_type)
346 _hc(' ** @returns void')
348 _hc(' *****************************************************************************/')
351 _h('%s (%s *i /**< */);', self.c_next_name, self.c_iterator_type)
352 _c('%s (%s *i /**< */)', self.c_next_name, self.c_iterator_type)
355 if not self.fixed_size():
356 _c(' %s *R = i->data;', self.c_type)
357 _c(' xcb_generic_iterator_t child = %s;', _c_iterator_get_end(self.last_varsized_field, 'R'))
359 _c(' i->data = (%s *) child.data;', self.c_type)
360 _c(' i->index = child.index;')
364 _c(' i->index += sizeof(%s);', self.c_type)
370 _h(' * Return the iterator pointing to the last element')
371 _h(' * @param i An %s', self.c_iterator_type)
372 _h(' * @return The iterator pointing to the last element')
374 _h(' * Set the current element in the iterator to the last element.')
375 _h(' * The member rem is set to 0. The member data points to the')
376 _h(' * last element.')
380 _hc('/*****************************************************************************')
382 _hc(' ** xcb_generic_iterator_t %s', self.c_end_name)
384 _hc(' ** @param %s i', self.c_iterator_type)
385 _hc(' ** @returns xcb_generic_iterator_t')
387 _hc(' *****************************************************************************/')
389 _hc('xcb_generic_iterator_t')
390 _h('%s (%s i /**< */);', self.c_end_name, self.c_iterator_type)
391 _c('%s (%s i /**< */)', self.c_end_name, self.c_iterator_type)
393 _c(' xcb_generic_iterator_t ret;')
395 if self.fixed_size():
396 _c(' ret.data = i.data + i.rem;')
397 _c(' ret.index = i.index + ((char *) ret.data - (char *) i.data);')
400 _c(' while(i.rem > 0)')
401 _c(' %s(&i);', self.c_next_name)
402 _c(' ret.data = i.data;')
403 _c(' ret.rem = i.rem;')
404 _c(' ret.index = i.index;')
409 def _c_accessor_get_length(expr, prefix=''):
411 Figures out what C code is needed to get a length field.
412 For fields that follow a variable-length field, use the accessor.
413 Otherwise, just reference the structure field directly.
415 prefarrow = '' if prefix == '' else prefix + '->'
417 if expr.lenfield != None and expr.lenfield.prev_varsized_field != None:
418 return expr.lenfield.c_accessor_name + '(' + prefix + ')'
419 elif expr.lenfield_name != None:
420 return prefarrow + expr.lenfield_name
422 return str(expr.nmemb)
424 def _c_accessor_get_expr(expr, prefix=''):
426 Figures out what C code is needed to get the length of a list field.
427 Recurses for math operations.
428 Returns bitcount for value-mask fields.
429 Otherwise, uses the value of the length field.
431 lenexp = _c_accessor_get_length(expr, prefix)
434 return '(' + _c_accessor_get_expr(expr.lhs, prefix) + ' ' + expr.op + ' ' + _c_accessor_get_expr(expr.rhs, prefix) + ')'
436 return 'xcb_popcount(' + lenexp + ')'
440 def _c_accessors_field(self, field):
442 Declares the accessor functions for a non-list field that follows a variable-length field.
444 if field.type.is_simple:
447 _hc('/*****************************************************************************')
449 _hc(' ** %s %s', field.c_field_type, field.c_accessor_name)
451 _hc(' ** @param const %s *R', self.c_type)
452 _hc(' ** @returns %s', field.c_field_type)
454 _hc(' *****************************************************************************/')
456 _hc('%s', field.c_field_type)
457 _h('%s (const %s *R /**< */);', field.c_accessor_name, self.c_type)
458 _c('%s (const %s *R /**< */)', field.c_accessor_name, self.c_type)
460 _c(' xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
461 _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)
466 _hc('/*****************************************************************************')
468 _hc(' ** %s * %s', field.c_field_type, field.c_accessor_name)
470 _hc(' ** @param const %s *R', self.c_type)
471 _hc(' ** @returns %s *', field.c_field_type)
473 _hc(' *****************************************************************************/')
475 _hc('%s *', field.c_field_type)
476 _h('%s (const %s *R /**< */);', field.c_accessor_name, self.c_type)
477 _c('%s (const %s *R /**< */)', field.c_accessor_name, self.c_type)
479 _c(' xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
480 _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)
483 def _c_accessors_list(self, field):
485 Declares the accessor functions for a list field.
486 Declares a direct-accessor function only if the list members are fixed size.
487 Declares length and get-iterator functions always.
493 if list.member.fixed_size():
496 _hc('/*****************************************************************************')
498 _hc(' ** %s * %s', field.c_field_type, field.c_accessor_name)
500 _hc(' ** @param const %s *R', self.c_type)
501 _hc(' ** @returns %s *', field.c_field_type)
503 _hc(' *****************************************************************************/')
505 _hc('%s *', field.c_field_type)
506 _h('%s (const %s *R /**< */);', field.c_accessor_name, self.c_type)
507 _c('%s (const %s *R /**< */)', field.c_accessor_name, self.c_type)
510 if field.prev_varsized_field == None:
511 _c(' return (%s *) (R + 1);', field.c_field_type)
513 _c(' xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
514 _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)
520 _hc('/*****************************************************************************')
522 _hc(' ** int %s', field.c_length_name)
524 _hc(' ** @param const %s *R', self.c_type)
525 _hc(' ** @returns int')
527 _hc(' *****************************************************************************/')
530 _h('%s (const %s *R /**< */);', field.c_length_name, self.c_type)
531 _c('%s (const %s *R /**< */)', field.c_length_name, self.c_type)
533 _c(' return %s;', _c_accessor_get_expr(field.type.expr, 'R'))
536 if field.type.member.is_simple:
539 _hc('/*****************************************************************************')
541 _hc(' ** xcb_generic_iterator_t %s', field.c_end_name)
543 _hc(' ** @param const %s *R', self.c_type)
544 _hc(' ** @returns xcb_generic_iterator_t')
546 _hc(' *****************************************************************************/')
548 _hc('xcb_generic_iterator_t')
549 _h('%s (const %s *R /**< */);', field.c_end_name, self.c_type)
550 _c('%s (const %s *R /**< */)', field.c_end_name, self.c_type)
552 _c(' xcb_generic_iterator_t i;')
554 if field.prev_varsized_field == None:
555 _c(' i.data = ((%s *) (R + 1)) + (%s);', field.type.c_wiretype, _c_accessor_get_expr(field.type.expr, 'R'))
557 _c(' xcb_generic_iterator_t child = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
558 _c(' i.data = ((%s *) child.data) + (%s);', field.type.c_wiretype, _c_accessor_get_expr(field.type.expr, 'R'))
561 _c(' i.index = (char *) i.data - (char *) R;')
568 _hc('/*****************************************************************************')
570 _hc(' ** %s %s', field.c_iterator_type, field.c_iterator_name)
572 _hc(' ** @param const %s *R', self.c_type)
573 _hc(' ** @returns %s', field.c_iterator_type)
575 _hc(' *****************************************************************************/')
577 _hc('%s', field.c_iterator_type)
578 _h('%s (const %s *R /**< */);', field.c_iterator_name, self.c_type)
579 _c('%s (const %s *R /**< */)', field.c_iterator_name, self.c_type)
581 _c(' %s i;', field.c_iterator_type)
583 if field.prev_varsized_field == None:
584 _c(' i.data = (%s *) (R + 1);', field.c_field_type)
586 _c(' xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
587 _c(' i.data = (%s *) ((char *) prev.data + XCB_TYPE_PAD(%s, prev.index));', field.c_field_type, field.c_field_type)
589 _c(' i.rem = %s;', _c_accessor_get_expr(field.type.expr, 'R'))
590 _c(' i.index = (char *) i.data - (char *) R;')
594 def _c_accessors(self, name, base):
596 Declares the accessor functions for the fields of a structure.
598 for field in self.fields:
599 if field.type.is_list and not field.type.fixed_size():
600 _c_accessors_list(self, field)
601 elif field.prev_varsized_field != None:
602 _c_accessors_field(self, field)
604 def c_simple(self, name):
606 Exported function that handles cardinal type declarations.
607 These are types which are typedef'd to one of the CARDx's, char, float, etc.
609 _c_type_setup(self, name, ())
611 if (self.name != name):
616 _h('typedef %s %s;', _t(self.name), my_name)
619 _c_iterator(self, name)
621 def _c_complex(self):
623 Helper function for handling all structure types.
624 Called for all structs, requests, replies, events, errors.
629 _h(' * @brief %s', self.c_type)
631 _h('typedef %s %s {', self.c_container, self.c_type)
637 for field in self.fields:
638 if not field.type.fixed_size():
639 varfield = field.c_field_name
641 if varfield != None and not field.type.is_pad and field.wire:
642 errmsg = '%s: warning: variable field %s followed by fixed field %s\n' % (self.c_type, varfield, field.c_field_name)
643 sys.stderr.write(errmsg)
646 struct_fields.append(field)
648 for field in struct_fields:
649 if len(field.c_field_type) > maxtypelen:
650 maxtypelen = len(field.c_field_type)
652 for field in struct_fields:
653 spacing = ' ' * (maxtypelen - len(field.c_field_type))
654 _h(' %s%s %s%s; /**< */', field.c_field_type, spacing, field.c_field_name, field.c_subscript)
656 _h('} %s;', self.c_type)
658 def c_struct(self, name):
660 Exported function that handles structure declarations.
662 _c_type_setup(self, name, ())
664 _c_accessors(self, name, name)
665 _c_iterator(self, name)
667 def c_union(self, name):
669 Exported function that handles union declarations.
671 _c_type_setup(self, name, ())
673 _c_iterator(self, name)
675 def _c_request_helper(self, name, cookie_type, void, regular):
677 Declares a request function.
680 # Four stunningly confusing possibilities here:
683 # ------------------------------
685 # 0 flag CHECKED flag Normal Mode
686 # void_cookie req_cookie
687 # ------------------------------
688 # "req_checked" "req_unchecked"
689 # CHECKED flag 0 flag Abnormal Mode
690 # void_cookie req_cookie
691 # ------------------------------
694 # Whether we are _checked or _unchecked
695 checked = void and not regular
696 unchecked = not void and not regular
698 # What kind of cookie we return
699 func_cookie = 'xcb_void_cookie_t' if void else self.c_cookie_type
701 # What flag is passed to xcb_request
702 func_flags = '0' if (void and regular) or (not void and not regular) else 'XCB_REQUEST_CHECKED'
704 # Global extension id variable or NULL for xproto
705 func_ext_global = '&' + _ns.c_ext_global_name if _ns.is_ext else '0'
707 # What our function name is
708 func_name = self.c_request_name
710 func_name = self.c_checked_name
712 func_name = self.c_unchecked_name
716 maxtypelen = len('xcb_connection_t')
718 for field in self.fields:
720 # The field should appear as a call parameter
721 param_fields.append(field)
722 if field.wire and not field.auto:
723 # We need to set the field up in the structure
724 wire_fields.append(field)
726 for field in param_fields:
727 if len(field.c_field_const_type) > maxtypelen:
728 maxtypelen = len(field.c_field_const_type)
734 _h(' * Delivers a request to the X server')
735 _h(' * @param c The connection')
736 _h(' * @return A cookie')
738 _h(' * Delivers a request to the X server.')
741 _h(' * This form can be used only if the request will not cause')
742 _h(' * a reply to be generated. Any returned error will be')
743 _h(' * saved for handling by xcb_request_check().')
745 _h(' * This form can be used only if the request will cause')
746 _h(' * a reply to be generated. Any returned error will be')
747 _h(' * placed in the event queue.')
751 _hc('/*****************************************************************************')
753 _hc(' ** %s %s', cookie_type, func_name)
756 spacing = ' ' * (maxtypelen - len('xcb_connection_t'))
757 _hc(' ** @param xcb_connection_t%s *c', spacing)
759 for field in param_fields:
760 spacing = ' ' * (maxtypelen - len(field.c_field_const_type))
761 _hc(' ** @param %s%s %s%s', field.c_field_const_type, spacing, field.c_pointer, field.c_field_name)
763 _hc(' ** @returns %s', cookie_type)
765 _hc(' *****************************************************************************/')
767 _hc('%s', cookie_type)
769 spacing = ' ' * (maxtypelen - len('xcb_connection_t'))
770 comma = ',' if len(param_fields) else ');'
771 _h('%s (xcb_connection_t%s *c /**< */%s', func_name, spacing, comma)
772 comma = ',' if len(param_fields) else ')'
773 _c('%s (xcb_connection_t%s *c /**< */%s', func_name, spacing, comma)
775 func_spacing = ' ' * (len(func_name) + 2)
776 count = len(param_fields)
777 for field in param_fields:
779 spacing = ' ' * (maxtypelen - len(field.c_field_const_type))
780 comma = ',' if count else ');'
781 _h('%s%s%s %s%s /**< */%s', func_spacing, field.c_field_const_type, spacing, field.c_pointer, field.c_field_name, comma)
782 comma = ',' if count else ')'
783 _c('%s%s%s %s%s /**< */%s', func_spacing, field.c_field_const_type, spacing, field.c_pointer, field.c_field_name, comma)
786 for field in param_fields:
787 if not field.type.fixed_size():
791 _c(' static const xcb_protocol_request_t xcb_req = {')
792 _c(' /* count */ %d,', count)
793 _c(' /* ext */ %s,', func_ext_global)
794 _c(' /* opcode */ %s,', self.c_request_name.upper())
795 _c(' /* isvoid */ %d', 1 if void else 0)
798 _c(' struct iovec xcb_parts[%d];', count + 2)
799 _c(' %s xcb_ret;', func_cookie)
800 _c(' %s xcb_out;', self.c_type)
803 for field in wire_fields:
804 if field.type.fixed_size():
805 if field.type.is_expr:
806 _c(' xcb_out.%s = %s;', field.c_field_name, _c_accessor_get_expr(field.type.expr))
808 elif field.type.is_pad:
809 if field.type.nmemb == 1:
810 _c(' xcb_out.%s = 0;', field.c_field_name)
812 _c(' memset(xcb_out.%s, 0, %d);', field.c_field_name, field.type.nmemb)
814 if field.type.nmemb == 1:
815 _c(' xcb_out.%s = %s;', field.c_field_name, field.c_field_name)
817 _c(' memcpy(xcb_out.%s, %s, %d);', field.c_field_name, field.c_field_name, field.type.nmemb)
820 _c(' xcb_parts[2].iov_base = (char *) &xcb_out;')
821 _c(' xcb_parts[2].iov_len = sizeof(xcb_out);')
822 _c(' xcb_parts[3].iov_base = 0;')
823 _c(' xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;')
826 for field in param_fields:
827 if not field.type.fixed_size():
828 _c(' xcb_parts[%d].iov_base = (char *) %s;', count, field.c_field_name)
829 if field.type.is_list:
830 _c(' xcb_parts[%d].iov_len = %s * sizeof(%s);', count, _c_accessor_get_expr(field.type.expr), field.type.member.c_wiretype)
832 _c(' xcb_parts[%d].iov_len = %s * sizeof(%s);', count, 'Uh oh', field.type.c_wiretype)
833 _c(' xcb_parts[%d].iov_base = 0;', count + 1)
834 _c(' xcb_parts[%d].iov_len = -xcb_parts[%d].iov_len & 3;', count + 1, count)
837 _c(' xcb_ret.sequence = xcb_send_request(c, %s, xcb_parts + 2, &xcb_req);', func_flags)
838 _c(' return xcb_ret;')
841 def _c_reply(self, name):
843 Declares the function that returns the reply structure.
845 spacing1 = ' ' * (len(self.c_cookie_type) - len('xcb_connection_t'))
846 spacing2 = ' ' * (len(self.c_cookie_type) - len('xcb_generic_error_t'))
847 spacing3 = ' ' * (len(self.c_reply_name) + 2)
851 _h(' * Return the reply')
852 _h(' * @param c The connection')
853 _h(' * @param cookie The cookie')
854 _h(' * @param e The xcb_generic_error_t supplied')
856 _h(' * Returns the reply of the request asked by')
858 _h(' * The parameter @p e supplied to this function must be NULL if')
859 _h(' * %s(). is used.', self.c_unchecked_name)
860 _h(' * Otherwise, it stores the error if any.')
862 _h(' * The returned value must be freed by the caller using free().')
866 _hc('/*****************************************************************************')
868 _hc(' ** %s * %s', self.c_reply_type, self.c_reply_name)
870 _hc(' ** @param xcb_connection_t%s *c', spacing1)
871 _hc(' ** @param %s cookie', self.c_cookie_type)
872 _hc(' ** @param xcb_generic_error_t%s **e', spacing2)
873 _hc(' ** @returns %s *', self.c_reply_type)
875 _hc(' *****************************************************************************/')
877 _hc('%s *', self.c_reply_type)
878 _hc('%s (xcb_connection_t%s *c /**< */,', self.c_reply_name, spacing1)
879 _hc('%s%s cookie /**< */,', spacing3, self.c_cookie_type)
880 _h('%sxcb_generic_error_t%s **e /**< */);', spacing3, spacing2)
881 _c('%sxcb_generic_error_t%s **e /**< */)', spacing3, spacing2)
883 _c(' return (%s *) xcb_wait_for_reply(c, cookie.sequence, e);', self.c_reply_type)
886 def _c_opcode(name, opcode):
888 Declares the opcode define for requests, events, and errors.
892 _h('/** Opcode for %s. */', _n(name))
893 _h('#define %s %s', _n(name).upper(), opcode)
895 def _c_cookie(self, name):
897 Declares the cookie type for a non-void request.
902 _h(' * @brief %s', self.c_cookie_type)
904 _h('typedef struct %s {', self.c_cookie_type)
905 _h(' unsigned int sequence; /**< */')
906 _h('} %s;', self.c_cookie_type)
908 def c_request(self, name):
910 Exported function that handles request declarations.
912 _c_type_setup(self, name, ('request',))
915 # Cookie type declaration
916 _c_cookie(self, name)
919 _c_opcode(name, self.opcode)
921 # Request structure declaration
925 _c_type_setup(self.reply, name, ('reply',))
926 # Reply structure definition
927 _c_complex(self.reply)
929 _c_request_helper(self, name, self.c_cookie_type, False, True)
930 _c_request_helper(self, name, self.c_cookie_type, False, False)
932 _c_accessors(self.reply, name + ('reply',), name)
936 _c_request_helper(self, name, 'xcb_void_cookie_t', True, False)
937 _c_request_helper(self, name, 'xcb_void_cookie_t', True, True)
939 def c_event(self, name):
941 Exported function that handles event declarations.
943 _c_type_setup(self, name, ('event',))
946 _c_opcode(name, self.opcodes[name])
948 if self.name == name:
949 # Structure definition
954 _h('typedef %s %s;', _t(self.name + ('event',)), _t(name + ('event',)))
956 def c_error(self, name):
958 Exported function that handles error declarations.
960 _c_type_setup(self, name, ('error',))
963 _c_opcode(name, self.opcodes[name])
965 if self.name == name:
966 # Structure definition
971 _h('typedef %s %s;', _t(self.name + ('error',)), _t(name + ('error',)))
974 # Main routine starts here
976 # Must create an "output" dictionary before any xcbgen imports.
977 output = {'open' : c_open,
983 'request' : c_request,
988 # Boilerplate below this point
990 # Check for the argument that specifies path to the xcbgen python package.
992 opts, args = getopt.getopt(sys.argv[1:], 'p:')
993 except getopt.GetoptError, err:
995 print 'Usage: c_client.py [-p path] file.xml'
998 for (opt, arg) in opts:
1000 sys.path.append(arg)
1002 # Import the module class
1004 from xcbgen.state import Module
1007 print 'Failed to load the xcbgen Python package!'
1008 print 'Make sure that xcb/proto installed it on your Python path.'
1009 print 'If not, you will need to create a .pth file or define $PYTHONPATH'
1010 print 'to extend the path.'
1011 print 'Refer to the README file in xcb/proto for more info.'
1015 # Parse the xml header
1016 module = Module(args[0], output)
1018 # Build type-registry and resolve type dependencies