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',))
138 # Build the type-name collision avoidance table used by c_enum
139 build_collision_table()
145 _hc(' * This file generated automatically from %s by c_client.py.', _ns.file)
146 _hc(' * Edit at your peril.')
151 _h(' * @defgroup XCB_%s_API XCB %s API', _ns.ext_name, _ns.ext_name)
152 _h(' * @brief %s XCB Protocol Implementation.', _ns.ext_name)
156 _h('#ifndef __%s_H', _ns.header.upper())
157 _h('#define __%s_H', _ns.header.upper())
159 _h('#include "xcb.h"')
161 _c('#include <string.h>')
162 _c('#include <assert.h>')
163 _c('#include "xcbext.h"')
164 _c('#include "%s.h"', _ns.header)
167 for (n, h) in self.imports:
168 _hc('#include "%s.h"', h)
171 _h('#ifdef __cplusplus')
177 _h('#define XCB_%s_MAJOR_VERSION %s', _ns.ext_name.upper(), _ns.major_version)
178 _h('#define XCB_%s_MINOR_VERSION %s', _ns.ext_name.upper(), _ns.minor_version)
180 _h('extern xcb_extension_t %s;', _ns.c_ext_global_name)
183 _c('xcb_extension_t %s = { "%s", 0 };', _ns.c_ext_global_name, _ns.ext_xname)
187 Exported function that handles module close.
188 Writes out all the stored content lines, then closes the files.
195 _h('#ifdef __cplusplus')
207 hfile = open('%s.h' % _ns.header, 'w')
215 cfile = open('%s.c' % _ns.header, 'w')
222 def build_collision_table():
226 for v in module.types.values():
228 namecount[name] = (namecount.get(name) or 0) + 1
230 def c_enum(self, name):
232 Exported function that handles enum declarations.
236 if namecount[tname] > 1:
237 tname = _t(name + ('enum',))
241 _h('typedef enum %s {', tname)
243 count = len(self.values)
245 for (enam, eval) in self.values:
247 equals = ' = ' if eval != '' else ''
248 comma = ',' if count > 0 else ''
249 _h(' %s%s%s%s', _n(name + (enam,)).upper(), equals, eval, comma)
253 def _c_type_setup(self, name, postfix):
255 Sets up all the C-related state by adding additional data fields to
256 all Field and Type objects. Here is where we figure out most of our
257 variable and function names.
259 Recurses into child fields and list member types.
261 # Do all the various names in advance
262 self.c_type = _t(name + postfix)
263 self.c_wiretype = 'char' if self.c_type == 'void' else self.c_type
265 self.c_iterator_type = _t(name + ('iterator',))
266 self.c_next_name = _n(name + ('next',))
267 self.c_end_name = _n(name + ('end',))
269 self.c_request_name = _n(name)
270 self.c_checked_name = _n(name + ('checked',))
271 self.c_unchecked_name = _n(name + ('unchecked',))
272 self.c_reply_name = _n(name + ('reply',))
273 self.c_reply_type = _t(name + ('reply',))
274 self.c_cookie_type = _t(name + ('cookie',))
276 if self.is_container:
278 self.c_container = 'union' if self.is_union else 'struct'
279 prev_varsized_field = None
280 prev_varsized_offset = 0
281 first_field_after_varsized = None
283 for field in self.fields:
284 _c_type_setup(field.type, field.field_type, ())
285 if field.type.is_list:
286 _c_type_setup(field.type.member, field.field_type, ())
288 field.c_field_type = _t(field.field_type)
289 field.c_field_const_type = ('' if field.type.nmemb == 1 else 'const ') + field.c_field_type
290 field.c_field_name = _cpp(field.field_name)
291 field.c_subscript = '[%d]' % field.type.nmemb if (field.type.nmemb > 1) else ''
292 field.c_pointer = ' ' if field.type.nmemb == 1 else '*'
294 field.c_iterator_type = _t(field.field_type + ('iterator',)) # xcb_fieldtype_iterator_t
295 field.c_iterator_name = _n(name + (field.field_name, 'iterator')) # xcb_container_field_iterator
296 field.c_accessor_name = _n(name + (field.field_name,)) # xcb_container_field
297 field.c_length_name = _n(name + (field.field_name, 'length')) # xcb_container_field_length
298 field.c_end_name = _n(name + (field.field_name, 'end')) # xcb_container_field_end
300 field.prev_varsized_field = prev_varsized_field
301 field.prev_varsized_offset = prev_varsized_offset
303 if prev_varsized_offset == 0:
304 first_field_after_varsized = field
305 field.first_field_after_varsized = first_field_after_varsized
307 if field.type.fixed_size():
308 prev_varsized_offset += field.type.size
310 self.last_varsized_field = field
311 prev_varsized_field = field
312 prev_varsized_offset = 0
314 def _c_iterator_get_end(field, accum):
316 Figures out what C code is needed to find the end of a variable-length structure field.
317 For nested structures, recurses into its last variable-sized field.
318 For lists, calls the end function
320 if field.type.is_container:
321 accum = field.c_accessor_name + '(' + accum + ')'
322 # XXX there could be fixed-length fields at the end
323 return _c_iterator_get_end(field.type.last_varsized_field, accum)
324 if field.type.is_list:
325 # XXX we can always use the first way
326 if field.type.member.is_simple:
327 return field.c_end_name + '(' + accum + ')'
329 return field.type.member.c_end_name + '(' + field.c_iterator_name + '(' + accum + '))'
331 def _c_iterator(self, name):
333 Declares the iterator structure and next/end functions for a given type.
338 _h(' * @brief %s', self.c_iterator_type)
340 _h('typedef struct %s {', self.c_iterator_type)
341 _h(' %s *data; /**< */', self.c_type)
342 _h(' int%s rem; /**< */', ' ' * (len(self.c_type) - 2))
343 _h(' int%s index; /**< */', ' ' * (len(self.c_type) - 2))
344 _h('} %s;', self.c_iterator_type)
350 _h(' * Get the next element of the iterator')
351 _h(' * @param i Pointer to a %s', self.c_iterator_type)
353 _h(' * Get the next element in the iterator. The member rem is')
354 _h(' * decreased by one. The member data points to the next')
355 _h(' * element. The member index is increased by sizeof(%s)', self.c_type)
359 _hc('/*****************************************************************************')
361 _hc(' ** void %s', self.c_next_name)
363 _hc(' ** @param %s *i', self.c_iterator_type)
364 _hc(' ** @returns void')
366 _hc(' *****************************************************************************/')
369 _h('%s (%s *i /**< */);', self.c_next_name, self.c_iterator_type)
370 _c('%s (%s *i /**< */)', self.c_next_name, self.c_iterator_type)
373 if not self.fixed_size():
374 _c(' %s *R = i->data;', self.c_type)
375 _c(' xcb_generic_iterator_t child = %s;', _c_iterator_get_end(self.last_varsized_field, 'R'))
377 _c(' i->data = (%s *) child.data;', self.c_type)
378 _c(' i->index = child.index;')
382 _c(' i->index += sizeof(%s);', self.c_type)
388 _h(' * Return the iterator pointing to the last element')
389 _h(' * @param i An %s', self.c_iterator_type)
390 _h(' * @return The iterator pointing to the last element')
392 _h(' * Set the current element in the iterator to the last element.')
393 _h(' * The member rem is set to 0. The member data points to the')
394 _h(' * last element.')
398 _hc('/*****************************************************************************')
400 _hc(' ** xcb_generic_iterator_t %s', self.c_end_name)
402 _hc(' ** @param %s i', self.c_iterator_type)
403 _hc(' ** @returns xcb_generic_iterator_t')
405 _hc(' *****************************************************************************/')
407 _hc('xcb_generic_iterator_t')
408 _h('%s (%s i /**< */);', self.c_end_name, self.c_iterator_type)
409 _c('%s (%s i /**< */)', self.c_end_name, self.c_iterator_type)
411 _c(' xcb_generic_iterator_t ret;')
413 if self.fixed_size():
414 _c(' ret.data = i.data + i.rem;')
415 _c(' ret.index = i.index + ((char *) ret.data - (char *) i.data);')
418 _c(' while(i.rem > 0)')
419 _c(' %s(&i);', self.c_next_name)
420 _c(' ret.data = i.data;')
421 _c(' ret.rem = i.rem;')
422 _c(' ret.index = i.index;')
427 def _c_accessor_get_length(expr, prefix=''):
429 Figures out what C code is needed to get a length field.
430 For fields that follow a variable-length field, use the accessor.
431 Otherwise, just reference the structure field directly.
433 prefarrow = '' if prefix == '' else prefix + '->'
435 if expr.lenfield != None and expr.lenfield.prev_varsized_field != None:
436 return expr.lenfield.c_accessor_name + '(' + prefix + ')'
437 elif expr.lenfield_name != None:
438 return prefarrow + expr.lenfield_name
440 return str(expr.nmemb)
442 def _c_accessor_get_expr(expr, prefix=''):
444 Figures out what C code is needed to get the length of a list field.
445 Recurses for math operations.
446 Returns bitcount for value-mask fields.
447 Otherwise, uses the value of the length field.
449 lenexp = _c_accessor_get_length(expr, prefix)
452 return '(' + _c_accessor_get_expr(expr.lhs, prefix) + ' ' + expr.op + ' ' + _c_accessor_get_expr(expr.rhs, prefix) + ')'
454 return 'xcb_popcount(' + lenexp + ')'
458 def _c_accessors_field(self, field):
460 Declares the accessor functions for a non-list field that follows a variable-length field.
462 if field.type.is_simple:
465 _hc('/*****************************************************************************')
467 _hc(' ** %s %s', field.c_field_type, field.c_accessor_name)
469 _hc(' ** @param const %s *R', self.c_type)
470 _hc(' ** @returns %s', field.c_field_type)
472 _hc(' *****************************************************************************/')
474 _hc('%s', field.c_field_type)
475 _h('%s (const %s *R /**< */);', field.c_accessor_name, self.c_type)
476 _c('%s (const %s *R /**< */)', field.c_accessor_name, self.c_type)
478 _c(' xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
479 _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 _hc('/*****************************************************************************')
486 _hc(' ** %s * %s', field.c_field_type, field.c_accessor_name)
488 _hc(' ** @param const %s *R', self.c_type)
489 _hc(' ** @returns %s *', field.c_field_type)
491 _hc(' *****************************************************************************/')
493 _hc('%s *', field.c_field_type)
494 _h('%s (const %s *R /**< */);', field.c_accessor_name, self.c_type)
495 _c('%s (const %s *R /**< */)', field.c_accessor_name, self.c_type)
497 _c(' xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
498 _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)
501 def _c_accessors_list(self, field):
503 Declares the accessor functions for a list field.
504 Declares a direct-accessor function only if the list members are fixed size.
505 Declares length and get-iterator functions always.
511 if list.member.fixed_size():
514 _hc('/*****************************************************************************')
516 _hc(' ** %s * %s', field.c_field_type, field.c_accessor_name)
518 _hc(' ** @param const %s *R', self.c_type)
519 _hc(' ** @returns %s *', field.c_field_type)
521 _hc(' *****************************************************************************/')
523 _hc('%s *', field.c_field_type)
524 _h('%s (const %s *R /**< */);', field.c_accessor_name, self.c_type)
525 _c('%s (const %s *R /**< */)', field.c_accessor_name, self.c_type)
528 if field.prev_varsized_field == None:
529 _c(' return (%s *) (R + 1);', field.c_field_type)
531 _c(' xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
532 _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)
538 _hc('/*****************************************************************************')
540 _hc(' ** int %s', field.c_length_name)
542 _hc(' ** @param const %s *R', self.c_type)
543 _hc(' ** @returns int')
545 _hc(' *****************************************************************************/')
548 _h('%s (const %s *R /**< */);', field.c_length_name, self.c_type)
549 _c('%s (const %s *R /**< */)', field.c_length_name, self.c_type)
551 _c(' return %s;', _c_accessor_get_expr(field.type.expr, 'R'))
554 if field.type.member.is_simple:
557 _hc('/*****************************************************************************')
559 _hc(' ** xcb_generic_iterator_t %s', field.c_end_name)
561 _hc(' ** @param const %s *R', self.c_type)
562 _hc(' ** @returns xcb_generic_iterator_t')
564 _hc(' *****************************************************************************/')
566 _hc('xcb_generic_iterator_t')
567 _h('%s (const %s *R /**< */);', field.c_end_name, self.c_type)
568 _c('%s (const %s *R /**< */)', field.c_end_name, self.c_type)
570 _c(' xcb_generic_iterator_t i;')
572 if field.prev_varsized_field == None:
573 _c(' i.data = ((%s *) (R + 1)) + (%s);', field.type.c_wiretype, _c_accessor_get_expr(field.type.expr, 'R'))
575 _c(' xcb_generic_iterator_t child = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
576 _c(' i.data = ((%s *) child.data) + (%s);', field.type.c_wiretype, _c_accessor_get_expr(field.type.expr, 'R'))
579 _c(' i.index = (char *) i.data - (char *) R;')
586 _hc('/*****************************************************************************')
588 _hc(' ** %s %s', field.c_iterator_type, field.c_iterator_name)
590 _hc(' ** @param const %s *R', self.c_type)
591 _hc(' ** @returns %s', field.c_iterator_type)
593 _hc(' *****************************************************************************/')
595 _hc('%s', field.c_iterator_type)
596 _h('%s (const %s *R /**< */);', field.c_iterator_name, self.c_type)
597 _c('%s (const %s *R /**< */)', field.c_iterator_name, self.c_type)
599 _c(' %s i;', field.c_iterator_type)
601 if field.prev_varsized_field == None:
602 _c(' i.data = (%s *) (R + 1);', field.c_field_type)
604 _c(' xcb_generic_iterator_t prev = %s;', _c_iterator_get_end(field.prev_varsized_field, 'R'))
605 _c(' i.data = (%s *) ((char *) prev.data + XCB_TYPE_PAD(%s, prev.index));', field.c_field_type, field.c_field_type)
607 _c(' i.rem = %s;', _c_accessor_get_expr(field.type.expr, 'R'))
608 _c(' i.index = (char *) i.data - (char *) R;')
612 def _c_accessors(self, name, base):
614 Declares the accessor functions for the fields of a structure.
616 for field in self.fields:
617 if field.type.is_list and not field.type.fixed_size():
618 _c_accessors_list(self, field)
619 elif field.prev_varsized_field != None:
620 _c_accessors_field(self, field)
622 def c_simple(self, name):
624 Exported function that handles cardinal type declarations.
625 These are types which are typedef'd to one of the CARDx's, char, float, etc.
627 _c_type_setup(self, name, ())
629 if (self.name != name):
634 _h('typedef %s %s;', _t(self.name), my_name)
637 _c_iterator(self, name)
639 def _c_complex(self):
641 Helper function for handling all structure types.
642 Called for all structs, requests, replies, events, errors.
647 _h(' * @brief %s', self.c_type)
649 _h('typedef %s %s {', self.c_container, self.c_type)
655 for field in self.fields:
656 if not field.type.fixed_size():
657 varfield = field.c_field_name
659 if varfield != None and not field.type.is_pad and field.wire:
660 errmsg = '%s: warning: variable field %s followed by fixed field %s\n' % (self.c_type, varfield, field.c_field_name)
661 sys.stderr.write(errmsg)
664 struct_fields.append(field)
666 for field in struct_fields:
667 if len(field.c_field_type) > maxtypelen:
668 maxtypelen = len(field.c_field_type)
670 for field in struct_fields:
671 spacing = ' ' * (maxtypelen - len(field.c_field_type))
672 _h(' %s%s %s%s; /**< */', field.c_field_type, spacing, field.c_field_name, field.c_subscript)
674 _h('} %s;', self.c_type)
676 def c_struct(self, name):
678 Exported function that handles structure declarations.
680 _c_type_setup(self, name, ())
682 _c_accessors(self, name, name)
683 _c_iterator(self, name)
685 def c_union(self, name):
687 Exported function that handles union declarations.
689 _c_type_setup(self, name, ())
691 _c_iterator(self, name)
693 def _c_request_helper(self, name, cookie_type, void, regular):
695 Declares a request function.
698 # Four stunningly confusing possibilities here:
701 # ------------------------------
703 # 0 flag CHECKED flag Normal Mode
704 # void_cookie req_cookie
705 # ------------------------------
706 # "req_checked" "req_unchecked"
707 # CHECKED flag 0 flag Abnormal Mode
708 # void_cookie req_cookie
709 # ------------------------------
712 # Whether we are _checked or _unchecked
713 checked = void and not regular
714 unchecked = not void and not regular
716 # What kind of cookie we return
717 func_cookie = 'xcb_void_cookie_t' if void else self.c_cookie_type
719 # What flag is passed to xcb_request
720 func_flags = '0' if (void and regular) or (not void and not regular) else 'XCB_REQUEST_CHECKED'
722 # Global extension id variable or NULL for xproto
723 func_ext_global = '&' + _ns.c_ext_global_name if _ns.is_ext else '0'
725 # What our function name is
726 func_name = self.c_request_name
728 func_name = self.c_checked_name
730 func_name = self.c_unchecked_name
734 maxtypelen = len('xcb_connection_t')
736 for field in self.fields:
738 # The field should appear as a call parameter
739 param_fields.append(field)
740 if field.wire and not field.auto:
741 # We need to set the field up in the structure
742 wire_fields.append(field)
744 for field in param_fields:
745 if len(field.c_field_const_type) > maxtypelen:
746 maxtypelen = len(field.c_field_const_type)
752 _h(' * Delivers a request to the X server')
753 _h(' * @param c The connection')
754 _h(' * @return A cookie')
756 _h(' * Delivers a request to the X server.')
759 _h(' * This form can be used only if the request will not cause')
760 _h(' * a reply to be generated. Any returned error will be')
761 _h(' * saved for handling by xcb_request_check().')
763 _h(' * This form can be used only if the request will cause')
764 _h(' * a reply to be generated. Any returned error will be')
765 _h(' * placed in the event queue.')
769 _hc('/*****************************************************************************')
771 _hc(' ** %s %s', cookie_type, func_name)
774 spacing = ' ' * (maxtypelen - len('xcb_connection_t'))
775 _hc(' ** @param xcb_connection_t%s *c', spacing)
777 for field in param_fields:
778 spacing = ' ' * (maxtypelen - len(field.c_field_const_type))
779 _hc(' ** @param %s%s %s%s', field.c_field_const_type, spacing, field.c_pointer, field.c_field_name)
781 _hc(' ** @returns %s', cookie_type)
783 _hc(' *****************************************************************************/')
785 _hc('%s', cookie_type)
787 spacing = ' ' * (maxtypelen - len('xcb_connection_t'))
788 comma = ',' if len(param_fields) else ');'
789 _h('%s (xcb_connection_t%s *c /**< */%s', func_name, spacing, comma)
790 comma = ',' if len(param_fields) else ')'
791 _c('%s (xcb_connection_t%s *c /**< */%s', func_name, spacing, comma)
793 func_spacing = ' ' * (len(func_name) + 2)
794 count = len(param_fields)
795 for field in param_fields:
797 spacing = ' ' * (maxtypelen - len(field.c_field_const_type))
798 comma = ',' if count else ');'
799 _h('%s%s%s %s%s /**< */%s', func_spacing, field.c_field_const_type, spacing, field.c_pointer, field.c_field_name, comma)
800 comma = ',' if count else ')'
801 _c('%s%s%s %s%s /**< */%s', func_spacing, field.c_field_const_type, spacing, field.c_pointer, field.c_field_name, comma)
804 for field in param_fields:
805 if not field.type.fixed_size():
809 _c(' static const xcb_protocol_request_t xcb_req = {')
810 _c(' /* count */ %d,', count)
811 _c(' /* ext */ %s,', func_ext_global)
812 _c(' /* opcode */ %s,', self.c_request_name.upper())
813 _c(' /* isvoid */ %d', 1 if void else 0)
816 _c(' struct iovec xcb_parts[%d];', count + 2)
817 _c(' %s xcb_ret;', func_cookie)
818 _c(' %s xcb_out;', self.c_type)
821 for field in wire_fields:
822 if field.type.fixed_size():
823 if field.type.is_expr:
824 _c(' xcb_out.%s = %s;', field.c_field_name, _c_accessor_get_expr(field.type.expr))
826 elif field.type.is_pad:
827 if field.type.nmemb == 1:
828 _c(' xcb_out.%s = 0;', field.c_field_name)
830 _c(' memset(xcb_out.%s, 0, %d);', field.c_field_name, field.type.nmemb)
832 if field.type.nmemb == 1:
833 _c(' xcb_out.%s = %s;', field.c_field_name, field.c_field_name)
835 _c(' memcpy(xcb_out.%s, %s, %d);', field.c_field_name, field.c_field_name, field.type.nmemb)
838 _c(' xcb_parts[2].iov_base = (char *) &xcb_out;')
839 _c(' xcb_parts[2].iov_len = sizeof(xcb_out);')
840 _c(' xcb_parts[3].iov_base = 0;')
841 _c(' xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;')
844 for field in param_fields:
845 if not field.type.fixed_size():
846 _c(' xcb_parts[%d].iov_base = (char *) %s;', count, field.c_field_name)
847 if field.type.is_list:
848 _c(' xcb_parts[%d].iov_len = %s * sizeof(%s);', count, _c_accessor_get_expr(field.type.expr), field.type.member.c_wiretype)
850 _c(' xcb_parts[%d].iov_len = %s * sizeof(%s);', count, 'Uh oh', field.type.c_wiretype)
851 _c(' xcb_parts[%d].iov_base = 0;', count + 1)
852 _c(' xcb_parts[%d].iov_len = -xcb_parts[%d].iov_len & 3;', count + 1, count)
855 _c(' xcb_ret.sequence = xcb_send_request(c, %s, xcb_parts + 2, &xcb_req);', func_flags)
856 _c(' return xcb_ret;')
859 def _c_reply(self, name):
861 Declares the function that returns the reply structure.
863 spacing1 = ' ' * (len(self.c_cookie_type) - len('xcb_connection_t'))
864 spacing2 = ' ' * (len(self.c_cookie_type) - len('xcb_generic_error_t'))
865 spacing3 = ' ' * (len(self.c_reply_name) + 2)
869 _h(' * Return the reply')
870 _h(' * @param c The connection')
871 _h(' * @param cookie The cookie')
872 _h(' * @param e The xcb_generic_error_t supplied')
874 _h(' * Returns the reply of the request asked by')
876 _h(' * The parameter @p e supplied to this function must be NULL if')
877 _h(' * %s(). is used.', self.c_unchecked_name)
878 _h(' * Otherwise, it stores the error if any.')
880 _h(' * The returned value must be freed by the caller using free().')
884 _hc('/*****************************************************************************')
886 _hc(' ** %s * %s', self.c_reply_type, self.c_reply_name)
888 _hc(' ** @param xcb_connection_t%s *c', spacing1)
889 _hc(' ** @param %s cookie', self.c_cookie_type)
890 _hc(' ** @param xcb_generic_error_t%s **e', spacing2)
891 _hc(' ** @returns %s *', self.c_reply_type)
893 _hc(' *****************************************************************************/')
895 _hc('%s *', self.c_reply_type)
896 _hc('%s (xcb_connection_t%s *c /**< */,', self.c_reply_name, spacing1)
897 _hc('%s%s cookie /**< */,', spacing3, self.c_cookie_type)
898 _h('%sxcb_generic_error_t%s **e /**< */);', spacing3, spacing2)
899 _c('%sxcb_generic_error_t%s **e /**< */)', spacing3, spacing2)
901 _c(' return (%s *) xcb_wait_for_reply(c, cookie.sequence, e);', self.c_reply_type)
904 def _c_opcode(name, opcode):
906 Declares the opcode define for requests, events, and errors.
910 _h('/** Opcode for %s. */', _n(name))
911 _h('#define %s %s', _n(name).upper(), opcode)
913 def _c_cookie(self, name):
915 Declares the cookie type for a non-void request.
920 _h(' * @brief %s', self.c_cookie_type)
922 _h('typedef struct %s {', self.c_cookie_type)
923 _h(' unsigned int sequence; /**< */')
924 _h('} %s;', self.c_cookie_type)
926 def c_request(self, name):
928 Exported function that handles request declarations.
930 _c_type_setup(self, name, ('request',))
933 # Cookie type declaration
934 _c_cookie(self, name)
937 _c_opcode(name, self.opcode)
939 # Request structure declaration
943 _c_type_setup(self.reply, name, ('reply',))
944 # Reply structure definition
945 _c_complex(self.reply)
947 _c_request_helper(self, name, self.c_cookie_type, False, True)
948 _c_request_helper(self, name, self.c_cookie_type, False, False)
950 _c_accessors(self.reply, name + ('reply',), name)
954 _c_request_helper(self, name, 'xcb_void_cookie_t', True, False)
955 _c_request_helper(self, name, 'xcb_void_cookie_t', True, True)
957 def c_event(self, name):
959 Exported function that handles event declarations.
961 _c_type_setup(self, name, ('event',))
964 _c_opcode(name, self.opcodes[name])
966 if self.name == name:
967 # Structure definition
972 _h('typedef %s %s;', _t(self.name + ('event',)), _t(name + ('event',)))
974 def c_error(self, name):
976 Exported function that handles error declarations.
978 _c_type_setup(self, name, ('error',))
981 _c_opcode(name, self.opcodes[name])
983 if self.name == name:
984 # Structure definition
989 _h('typedef %s %s;', _t(self.name + ('error',)), _t(name + ('error',)))
992 # Main routine starts here
994 # Must create an "output" dictionary before any xcbgen imports.
995 output = {'open' : c_open,
1001 'request' : c_request,
1006 # Boilerplate below this point
1008 # Check for the argument that specifies path to the xcbgen python package.
1010 opts, args = getopt.getopt(sys.argv[1:], 'p:')
1011 except getopt.GetoptError, err:
1013 print 'Usage: c_client.py [-p path] file.xml'
1016 for (opt, arg) in opts:
1018 sys.path.append(arg)
1020 # Import the module class
1022 from xcbgen.state import Module
1025 print 'Failed to load the xcbgen Python package!'
1026 print 'Make sure that xcb/proto installed it on your Python path.'
1027 print 'If not, you will need to create a .pth file or define $PYTHONPATH'
1028 print 'to extend the path.'
1029 print 'Refer to the README file in xcb/proto for more info.'
1033 # Parse the xml header
1034 module = Module(args[0], output)
1036 # Build type-registry and resolve type dependencies