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('#ifdef __cplusplus')
186 _h('#define XCB_%s_MAJOR_VERSION %s', _ns.ext_name.upper(), _ns.major_version)
187 _h('#define XCB_%s_MINOR_VERSION %s', _ns.ext_name.upper(), _ns.minor_version)
189 _h('extern xcb_extension_t %s;', _ns.c_ext_global_name)
192 _c('xcb_extension_t %s = { "%s", 0 };', _ns.c_ext_global_name, _ns.ext_xname)
196 Exported function that handles module close.
197 Writes out all the stored content lines, then closes the files.
204 _h('#ifdef __cplusplus')
216 hfile = open('%s.h' % _ns.header, 'w')
224 cfile = open('%s.c' % _ns.header, 'w')
231 def c_enum(self, name):
233 Exported function that handles enum declarations.
237 _h('typedef enum %s {', _t(name))
239 count = len(self.values)
241 for (enam, eval) in self.values:
243 equals = ' = ' if eval != '' else ''
244 comma = ',' if count > 0 else ''
245 _h(' %s%s%s%s', _n(name + (enam,)).upper(), equals, eval, comma)
247 _h('} %s;', _t(name))
249 def _c_type_setup(self, name, postfix):
251 Sets up all the C-related state by adding additional data fields to
252 all Field and Type objects. Here is where we figure out most of our
253 variable and function names.
255 Recurses into child fields and list member types.
257 # Do all the various names in advance
258 self.c_type = _t(name + postfix)
259 self.c_wiretype = 'char' if self.c_type == 'void' else self.c_type
261 self.c_iterator_type = _t(name + ('iterator',))
262 self.c_next_name = _n(name + ('next',))
263 self.c_end_name = _n(name + ('end',))
265 self.c_request_name = _n(name)
266 self.c_checked_name = _n(name + ('checked',))
267 self.c_unchecked_name = _n(name + ('unchecked',))
268 self.c_reply_name = _n(name + ('reply',))
269 self.c_reply_type = _t(name + ('reply',))
270 self.c_cookie_type = _t(name + ('cookie',))
272 if self.is_container:
274 self.c_container = 'union' if self.is_union else 'struct'
275 prev_varsized_field = None
276 prev_varsized_offset = 0
277 first_field_after_varsized = None
279 for field in self.fields:
280 _c_type_setup(field.type, field.field_type, ())
281 if field.type.is_list:
282 _c_type_setup(field.type.member, field.field_type, ())
284 field.c_field_type = _t(field.field_type)
285 field.c_field_const_type = ('' if field.type.nmemb == 1 else 'const ') + field.c_field_type
286 field.c_field_name = _cpp(field.field_name)
287 field.c_subscript = '[%d]' % field.type.nmemb if (field.type.nmemb > 1) else ''
288 field.c_pointer = ' ' if field.type.nmemb == 1 else '*'
290 field.c_iterator_type = _t(field.field_type + ('iterator',)) # xcb_fieldtype_iterator_t
291 field.c_iterator_name = _n(name + (field.field_name, 'iterator')) # xcb_container_field_iterator
292 field.c_accessor_name = _n(name + (field.field_name,)) # xcb_container_field
293 field.c_length_name = _n(name + (field.field_name, 'length')) # xcb_container_field_length
294 field.c_end_name = _n(name + (field.field_name, 'end')) # xcb_container_field_end
296 field.prev_varsized_field = prev_varsized_field
297 field.prev_varsized_offset = prev_varsized_offset
299 if prev_varsized_offset == 0:
300 first_field_after_varsized = field
301 field.first_field_after_varsized = first_field_after_varsized
303 if field.type.fixed_size():
304 prev_varsized_offset += field.type.size
306 self.last_varsized_field = field
307 prev_varsized_field = field
308 prev_varsized_offset = 0
310 def _c_iterator_get_end(field, accum):
312 Figures out what C code is needed to find the end of a variable-length structure field.
313 For nested structures, recurses into its last variable-sized field.
314 For lists, calls the end function
316 if field.type.is_container:
317 accum = field.c_accessor_name + '(' + accum + ')'
318 # XXX there could be fixed-length fields at the end
319 return _c_iterator_get_end(field.type.last_varsized_field, accum)
320 if field.type.is_list:
321 # XXX we can always use the first way
322 if field.type.c_type in _cardinal_types:
323 return field.c_end_name + '(' + accum + ')'
325 return field.type.member.c_end_name + '(' + field.c_iterator_name + '(' + accum + '))'
327 def _c_iterator(self, name):
329 Declares the iterator structure and next/end functions for a given type.
334 _h(' * @brief %s', self.c_iterator_type)
336 _h('typedef struct %s {', self.c_iterator_type)
337 _h(' %s *data; /**< */', self.c_type)
338 _h(' int%s rem; /**< */', ' ' * (len(self.c_type) - 2))
339 _h(' int%s index; /**< */', ' ' * (len(self.c_type) - 2))
340 _h('} %s;', self.c_iterator_type)
346 _h(' * Get the next element of the iterator')
347 _h(' * @param i Pointer to a %s', self.c_iterator_type)
349 _h(' * Get the next element in the iterator. The member rem is')
350 _h(' * decreased by one. The member data points to the next')
351 _h(' * element. The member index is increased by sizeof(%s)', self.c_type)
355 _hc('/*****************************************************************************')
357 _hc(' ** void %s', self.c_next_name)
359 _hc(' ** @param %s *i', self.c_iterator_type)
360 _hc(' ** @returns void')
362 _hc(' *****************************************************************************/')
365 _h('%s (%s *i /**< */);', self.c_next_name, self.c_iterator_type)
366 _c('%s (%s *i /**< */)', self.c_next_name, self.c_iterator_type)
369 if not self.fixed_size():
370 _c(' %s *R = i->data;', self.c_type)
371 _c(' xcb_generic_iterator_t child = %s;', _c_iterator_get_end(self.last_varsized_field, 'R'))
373 _c(' i->data = (%s *) child.data;', self.c_type)
374 _c(' i->index = child.index;')
378 _c(' i->index += sizeof(%s);', self.c_type)
384 _h(' * Return the iterator pointing to the last element')
385 _h(' * @param i An %s', self.c_iterator_type)
386 _h(' * @return The iterator pointing to the last element')
388 _h(' * Set the current element in the iterator to the last element.')
389 _h(' * The member rem is set to 0. The member data points to the')
390 _h(' * last element.')
394 _hc('/*****************************************************************************')
396 _hc(' ** xcb_generic_iterator_t %s', self.c_end_name)
398 _hc(' ** @param %s i', self.c_iterator_type)
399 _hc(' ** @returns xcb_generic_iterator_t')
401 _hc(' *****************************************************************************/')
403 _hc('xcb_generic_iterator_t')
404 _h('%s (%s i /**< */);', self.c_end_name, self.c_iterator_type)
405 _c('%s (%s i /**< */)', self.c_end_name, self.c_iterator_type)
407 _c(' xcb_generic_iterator_t ret;')
409 if self.fixed_size():
410 _c(' ret.data = i.data + i.rem;')
411 _c(' ret.index = i.index + ((char *) ret.data - (char *) i.data);')
414 _c(' while(i.rem > 0)')
415 _c(' %s(&i);', self.c_next_name)
416 _c(' ret.data = i.data;')
417 _c(' ret.rem = i.rem;')
418 _c(' ret.index = i.index;')
423 def _c_accessor_get_length(expr, prefix=''):
425 Figures out what C code is needed to get a length field.
426 For fields that follow a variable-length field, use the accessor.
427 Otherwise, just reference the structure field directly.
429 prefarrow = '' if prefix == '' else prefix + '->'
431 if expr.lenfield != None and expr.lenfield.prev_varsized_field != None:
432 return expr.lenfield.c_accessor_name + '(' + prefix + ')'
433 elif expr.lenfield_name != None:
434 return prefarrow + expr.lenfield_name
436 return str(expr.nmemb)
438 def _c_accessor_get_expr(expr, prefix=''):
440 Figures out what C code is needed to get the length of a list field.
441 Recurses for math operations.
442 Returns bitcount for value-mask fields.
443 Otherwise, uses the value of the length field.
445 lenexp = _c_accessor_get_length(expr, prefix)
448 return '(' + _c_accessor_get_expr(expr.lhs, prefix) + ' ' + expr.op + ' ' + _c_accessor_get_expr(expr.rhs, prefix) + ')'
450 return 'xcb_popcount(' + lenexp + ')'
454 def _c_accessors_field(self, field):
456 Declares the accessor functions for a non-list field that follows a variable-length field.
458 if field.field_type[0] in _cardinal_types:
461 _hc('/*****************************************************************************')
463 _hc(' ** %s %s', field.c_field_type, field.c_accessor_name)
465 _hc(' ** @param const %s *R', self.c_type)
466 _hc(' ** @returns %s', field.c_field_type)
468 _hc(' *****************************************************************************/')
470 _hc('%s', field.c_field_type)
471 _h('%s (const %s *R /**< */);', field.c_accessor_name, self.c_type)
472 _c('%s (const %s *R /**< */)', field.c_accessor_name, self.c_type)
474 _c(' xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
475 _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)
480 _hc('/*****************************************************************************')
482 _hc(' ** %s * %s', field.c_field_type, field.c_accessor_name)
484 _hc(' ** @param const %s *R', self.c_type)
485 _hc(' ** @returns %s *', field.c_field_type)
487 _hc(' *****************************************************************************/')
489 _hc('%s *', field.c_field_type)
490 _h('%s (const %s *R /**< */);', field.c_accessor_name, self.c_type)
491 _c('%s (const %s *R /**< */)', field.c_accessor_name, self.c_type)
493 _c(' xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
494 _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)
497 def _c_accessors_list(self, field):
499 Declares the accessor functions for a list field.
500 Declares a direct-accessor function only if the list members are fixed size.
501 Declares length and get-iterator functions always.
507 if list.member.fixed_size():
510 _hc('/*****************************************************************************')
512 _hc(' ** %s * %s', field.c_field_type, field.c_accessor_name)
514 _hc(' ** @param const %s *R', self.c_type)
515 _hc(' ** @returns %s *', field.c_field_type)
517 _hc(' *****************************************************************************/')
519 _hc('%s *', field.c_field_type)
520 _h('%s (const %s *R /**< */);', field.c_accessor_name, self.c_type)
521 _c('%s (const %s *R /**< */)', field.c_accessor_name, self.c_type)
524 if field.prev_varsized_field == None:
525 _c(' return (%s *) (R + 1);', field.c_field_type)
527 _c(' xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
528 _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)
534 _hc('/*****************************************************************************')
536 _hc(' ** int %s', field.c_length_name)
538 _hc(' ** @param const %s *R', self.c_type)
539 _hc(' ** @returns int')
541 _hc(' *****************************************************************************/')
544 _h('%s (const %s *R /**< */);', field.c_length_name, self.c_type)
545 _c('%s (const %s *R /**< */)', field.c_length_name, self.c_type)
547 _c(' return %s;', _c_accessor_get_expr(field.type.expr, 'R'))
550 if field.field_type[0] in _cardinal_types:
553 _hc('/*****************************************************************************')
555 _hc(' ** xcb_generic_iterator_t %s', field.c_end_name)
557 _hc(' ** @param const %s *R', self.c_type)
558 _hc(' ** @returns xcb_generic_iterator_t')
560 _hc(' *****************************************************************************/')
562 _hc('xcb_generic_iterator_t')
563 _h('%s (const %s *R /**< */);', field.c_end_name, self.c_type)
564 _c('%s (const %s *R /**< */)', field.c_end_name, self.c_type)
566 _c(' xcb_generic_iterator_t i;')
568 if field.prev_varsized_field == None:
569 _c(' i.data = ((%s *) (R + 1)) + (%s);', field.type.c_wiretype, _c_accessor_get_expr(field.type.expr, 'R'))
571 _c(' xcb_generic_iterator_t child = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
572 _c(' i.data = ((%s *) child.data) + (%s);', field.type.c_wiretype, _c_accessor_get_expr(field.type.expr, 'R'))
575 _c(' i.index = (char *) i.data - (char *) R;')
582 _hc('/*****************************************************************************')
584 _hc(' ** %s %s', field.c_iterator_type, field.c_iterator_name)
586 _hc(' ** @param const %s *R', self.c_type)
587 _hc(' ** @returns %s', field.c_iterator_type)
589 _hc(' *****************************************************************************/')
591 _hc('%s', field.c_iterator_type)
592 _h('%s (const %s *R /**< */);', field.c_iterator_name, self.c_type)
593 _c('%s (const %s *R /**< */)', field.c_iterator_name, self.c_type)
595 _c(' %s i;', field.c_iterator_type)
597 if field.prev_varsized_field == None:
598 _c(' i.data = (%s *) (R + 1);', field.c_field_type)
600 _c(' xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
601 _c(' i.data = (%s *) ((char *) prev.data + XCB_TYPE_PAD(%s, prev.index));', field.c_field_type, field.c_field_type)
603 _c(' i.rem = %s;', _c_accessor_get_expr(field.type.expr, 'R'))
604 _c(' i.index = (char *) i.data - (char *) R;')
608 def _c_accessors(self, name, base):
610 Declares the accessor functions for the fields of a structure.
612 for field in self.fields:
613 if field.type.is_list and not field.type.fixed_size():
614 _c_accessors_list(self, field)
615 elif field.prev_varsized_field != None:
616 _c_accessors_field(self, field)
618 def c_simple(self, name):
620 Exported function that handles cardinal type declarations.
621 These are types which are typedef'd to one of the CARDx's, char, float, etc.
623 _c_type_setup(self, name, ())
625 if (self.name != name):
630 _h('typedef %s %s;', _t(self.name), my_name)
633 _c_iterator(self, name)
635 def _c_complex(self):
637 Helper function for handling all structure types.
638 Called for all structs, requests, replies, events, errors.
643 _h(' * @brief %s', self.c_type)
645 _h('typedef %s %s {', self.c_container, self.c_type)
651 for field in self.fields:
652 if not field.type.fixed_size():
653 varfield = field.c_field_name
655 if varfield != None and not field.type.is_pad and field.wire:
656 errmsg = '%s: warning: variable field %s followed by fixed field %s\n' % (self.c_type, varfield, field.c_field_name)
657 sys.stderr.write(errmsg)
660 struct_fields.append(field)
662 for field in struct_fields:
663 if len(field.c_field_type) > maxtypelen:
664 maxtypelen = len(field.c_field_type)
666 for field in struct_fields:
667 spacing = ' ' * (maxtypelen - len(field.c_field_type))
668 _h(' %s%s %s%s; /**< */', field.c_field_type, spacing, field.c_field_name, field.c_subscript)
670 _h('} %s;', self.c_type)
672 def c_struct(self, name):
674 Exported function that handles structure declarations.
676 _c_type_setup(self, name, ())
678 _c_accessors(self, name, name)
679 _c_iterator(self, name)
681 def c_union(self, name):
683 Exported function that handles union declarations.
685 _c_type_setup(self, name, ())
687 _c_iterator(self, name)
689 def _c_request_helper(self, name, cookie_type, void, regular):
691 Declares a request function.
694 # Four stunningly confusing possibilities here:
697 # ------------------------------
699 # 0 flag CHECKED flag Normal Mode
700 # void_cookie req_cookie
701 # ------------------------------
702 # "req_checked" "req_unchecked"
703 # CHECKED flag 0 flag Abnormal Mode
704 # void_cookie req_cookie
705 # ------------------------------
708 # Whether we are _checked or _unchecked
709 checked = void and not regular
710 unchecked = not void and not regular
712 # What kind of cookie we return
713 func_cookie = 'xcb_void_cookie_t' if void else self.c_cookie_type
715 # What flag is passed to xcb_request
716 func_flags = '0' if (void and regular) or (not void and not regular) else 'XCB_REQUEST_CHECKED'
718 # Global extension id variable or NULL for xproto
719 func_ext_global = '&' + _ns.c_ext_global_name if _ns.is_ext else '0'
721 # What our function name is
722 func_name = self.c_request_name
724 func_name = self.c_checked_name
726 func_name = self.c_unchecked_name
730 maxtypelen = len('xcb_connection_t')
732 for field in self.fields:
734 # The field should appear as a call parameter
735 param_fields.append(field)
736 if field.wire and not field.auto:
737 # We need to set the field up in the structure
738 wire_fields.append(field)
740 for field in param_fields:
741 if len(field.c_field_const_type) > maxtypelen:
742 maxtypelen = len(field.c_field_const_type)
748 _h(' * Delivers a request to the X server')
749 _h(' * @param c The connection')
750 _h(' * @return A cookie')
752 _h(' * Delivers a request to the X server.')
755 _h(' * This form can be used only if the request will not cause')
756 _h(' * a reply to be generated. Any returned error will be')
757 _h(' * saved for handling by xcb_request_check().')
759 _h(' * This form can be used only if the request will cause')
760 _h(' * a reply to be generated. Any returned error will be')
761 _h(' * placed in the event queue.')
765 _hc('/*****************************************************************************')
767 _hc(' ** %s %s', cookie_type, func_name)
770 spacing = ' ' * (maxtypelen - len('xcb_connection_t'))
771 _hc(' ** @param xcb_connection_t%s *c', spacing)
773 for field in param_fields:
774 spacing = ' ' * (maxtypelen - len(field.c_field_const_type))
775 _hc(' ** @param %s%s %s%s', field.c_field_const_type, spacing, field.c_pointer, field.c_field_name)
777 _hc(' ** @returns %s', cookie_type)
779 _hc(' *****************************************************************************/')
781 _hc('%s', cookie_type)
783 spacing = ' ' * (maxtypelen - len('xcb_connection_t'))
784 comma = ',' if len(param_fields) else ');'
785 _h('%s (xcb_connection_t%s *c /**< */%s', func_name, spacing, comma)
786 comma = ',' if len(param_fields) else ')'
787 _c('%s (xcb_connection_t%s *c /**< */%s', func_name, spacing, comma)
789 func_spacing = ' ' * (len(func_name) + 2)
790 count = len(param_fields)
791 for field in param_fields:
793 spacing = ' ' * (maxtypelen - len(field.c_field_const_type))
794 comma = ',' if count else ');'
795 _h('%s%s%s %s%s /**< */%s', func_spacing, field.c_field_const_type, spacing, field.c_pointer, field.c_field_name, comma)
796 comma = ',' if count else ')'
797 _c('%s%s%s %s%s /**< */%s', func_spacing, field.c_field_const_type, spacing, field.c_pointer, field.c_field_name, comma)
800 for field in param_fields:
801 if not field.type.fixed_size():
805 _c(' static const xcb_protocol_request_t xcb_req = {')
806 _c(' /* count */ %d,', count)
807 _c(' /* ext */ %s,', func_ext_global)
808 _c(' /* opcode */ %s,', self.c_request_name.upper())
809 _c(' /* isvoid */ %d', 1 if void else 0)
812 _c(' struct iovec xcb_parts[%d];', count + 2)
813 _c(' %s xcb_ret;', func_cookie)
814 _c(' %s xcb_out;', self.c_type)
817 for field in wire_fields:
818 if field.type.fixed_size():
819 if field.type.is_expr:
820 _c(' xcb_out.%s = %s;', field.c_field_name, _c_accessor_get_expr(field.type.expr))
822 elif field.type.is_pad:
823 if field.type.nmemb == 1:
824 _c(' xcb_out.%s = 0;', field.c_field_name)
826 _c(' memset(xcb_out.%s, 0, %d);', field.c_field_name, field.type.nmemb)
828 if field.type.nmemb == 1:
829 _c(' xcb_out.%s = %s;', field.c_field_name, field.c_field_name)
831 _c(' memcpy(xcb_out.%s, %s, %d);', field.c_field_name, field.c_field_name, field.type.nmemb)
834 _c(' xcb_parts[2].iov_base = (char *) &xcb_out;')
835 _c(' xcb_parts[2].iov_len = sizeof(xcb_out);')
836 _c(' xcb_parts[3].iov_base = 0;')
837 _c(' xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;')
840 for field in param_fields:
841 if not field.type.fixed_size():
842 _c(' xcb_parts[%d].iov_base = (char *) %s;', count, field.c_field_name)
843 if field.type.is_list:
844 _c(' xcb_parts[%d].iov_len = %s * sizeof(%s);', count, _c_accessor_get_expr(field.type.expr), field.type.member.c_wiretype)
846 _c(' xcb_parts[%d].iov_len = %s * sizeof(%s);', count, 'Uh oh', field.type.c_wiretype)
847 _c(' xcb_parts[%d].iov_base = 0;', count + 1)
848 _c(' xcb_parts[%d].iov_len = -xcb_parts[%d].iov_len & 3;', count + 1, count)
851 _c(' xcb_ret.sequence = xcb_send_request(c, %s, xcb_parts + 2, &xcb_req);', func_flags)
852 _c(' return xcb_ret;')
855 def _c_reply(self, name):
857 Declares the function that returns the reply structure.
859 spacing1 = ' ' * (len(self.c_cookie_type) - len('xcb_connection_t'))
860 spacing2 = ' ' * (len(self.c_cookie_type) - len('xcb_generic_error_t'))
861 spacing3 = ' ' * (len(self.c_reply_name) + 2)
865 _h(' * Return the reply')
866 _h(' * @param c The connection')
867 _h(' * @param cookie The cookie')
868 _h(' * @param e The xcb_generic_error_t supplied')
870 _h(' * Returns the reply of the request asked by')
872 _h(' * The parameter @p e supplied to this function must be NULL if')
873 _h(' * %s(). is used.', self.c_unchecked_name)
874 _h(' * Otherwise, it stores the error if any.')
876 _h(' * The returned value must be freed by the caller using free().')
880 _hc('/*****************************************************************************')
882 _hc(' ** %s * %s', self.c_reply_type, self.c_reply_name)
884 _hc(' ** @param xcb_connection_t%s *c', spacing1)
885 _hc(' ** @param %s cookie', self.c_cookie_type)
886 _hc(' ** @param xcb_generic_error_t%s **e', spacing2)
887 _hc(' ** @returns %s *', self.c_reply_type)
889 _hc(' *****************************************************************************/')
891 _hc('%s *', self.c_reply_type)
892 _hc('%s (xcb_connection_t%s *c /**< */,', self.c_reply_name, spacing1)
893 _hc('%s%s cookie /**< */,', spacing3, self.c_cookie_type)
894 _h('%sxcb_generic_error_t%s **e /**< */);', spacing3, spacing2)
895 _c('%sxcb_generic_error_t%s **e /**< */)', spacing3, spacing2)
897 _c(' return (%s *) xcb_wait_for_reply(c, cookie.sequence, e);', self.c_reply_type)
900 def _c_opcode(name, opcode):
902 Declares the opcode define for requests, events, and errors.
906 _h('/** Opcode for %s. */', _n(name))
907 _h('#define %s %s', _n(name).upper(), opcode)
909 def _c_cookie(self, name):
911 Declares the cookie type for a non-void request.
916 _h(' * @brief %s', self.c_cookie_type)
918 _h('typedef struct %s {', self.c_cookie_type)
919 _h(' unsigned int sequence; /**< */')
920 _h('} %s;', self.c_cookie_type)
922 def c_request(self, name):
924 Exported function that handles request declarations.
926 _c_type_setup(self, name, ('request',))
929 # Cookie type declaration
930 _c_cookie(self, name)
933 _c_opcode(name, self.opcode)
935 # Request structure declaration
939 _c_type_setup(self.reply, name, ('reply',))
940 # Reply structure definition
941 _c_complex(self.reply)
943 _c_request_helper(self, name, self.c_cookie_type, False, True)
944 _c_request_helper(self, name, self.c_cookie_type, False, False)
946 _c_accessors(self.reply, name + ('reply',), name)
950 _c_request_helper(self, name, 'xcb_void_cookie_t', True, False)
951 _c_request_helper(self, name, 'xcb_void_cookie_t', True, True)
953 def c_event(self, name):
955 Exported function that handles event declarations.
957 _c_type_setup(self, name, ('event',))
960 _c_opcode(name, self.opcodes[name])
962 if self.name == name:
963 # Structure definition
968 _h('typedef %s %s;', _t(self.name + ('event',)), _t(name + ('event',)))
970 def c_error(self, name):
972 Exported function that handles error declarations.
974 _c_type_setup(self, name, ('error',))
977 _c_opcode(name, self.opcodes[name])
979 if self.name == name:
980 # Structure definition
985 _h('typedef %s %s;', _t(self.name + ('error',)), _t(name + ('error',)))
988 # Main routine starts here
990 # Must create an "output" dictionary before any xcbgen imports.
991 output = {'open' : c_open,
997 'request' : c_request,
1002 # Boilerplate below this point
1004 # Check for the argument that specifies path to the xcbgen python package.
1006 opts, args = getopt.getopt(sys.argv[1:], 'p:')
1007 except getopt.GetoptError, err:
1009 print 'Usage: c_client.py [-p path] file.xml'
1012 for (opt, arg) in opts:
1014 sys.path.append(arg)
1016 # Import the module class
1018 from xcbgen.state import Module
1021 print 'Failed to load the xcbgen Python package!'
1022 print 'Make sure that xcb/proto installed it on your Python path.'
1023 print 'If not, you will need to create a .pth file or define $PYTHONPATH'
1024 print 'to extend the path.'
1025 print 'Refer to the README file in xcb/proto for more info.'
1029 # Parse the xml header
1030 module = Module(args[0], output)
1032 # Build type-registry and resolve type dependencies