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", 0 };', _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)
639 for field in self.fields:
640 if not field.type.fixed_size():
641 varfield = field.c_field_name
643 if varfield != None and not field.type.is_pad and field.wire:
644 errmsg = '%s: warning: variable field %s followed by fixed field %s\n' % (self.c_type, varfield, field.c_field_name)
645 sys.stderr.write(errmsg)
648 struct_fields.append(field)
650 for field in struct_fields:
651 if len(field.c_field_type) > maxtypelen:
652 maxtypelen = len(field.c_field_type)
654 for field in struct_fields:
655 spacing = ' ' * (maxtypelen - len(field.c_field_type))
656 _h(' %s%s %s%s; /**< */', field.c_field_type, spacing, field.c_field_name, field.c_subscript)
658 _h('} %s;', self.c_type)
660 def c_struct(self, name):
662 Exported function that handles structure declarations.
664 _c_type_setup(self, name, ())
666 _c_accessors(self, name, name)
667 _c_iterator(self, name)
669 def c_union(self, name):
671 Exported function that handles union declarations.
673 _c_type_setup(self, name, ())
675 _c_iterator(self, name)
677 def _c_request_helper(self, name, cookie_type, void, regular):
679 Declares a request function.
682 # Four stunningly confusing possibilities here:
685 # ------------------------------
687 # 0 flag CHECKED flag Normal Mode
688 # void_cookie req_cookie
689 # ------------------------------
690 # "req_checked" "req_unchecked"
691 # CHECKED flag 0 flag Abnormal Mode
692 # void_cookie req_cookie
693 # ------------------------------
696 # Whether we are _checked or _unchecked
697 checked = void and not regular
698 unchecked = not void and not regular
700 # What kind of cookie we return
701 func_cookie = 'xcb_void_cookie_t' if void else self.c_cookie_type
703 # What flag is passed to xcb_request
704 func_flags = '0' if (void and regular) or (not void and not regular) else 'XCB_REQUEST_CHECKED'
706 # Global extension id variable or NULL for xproto
707 func_ext_global = '&' + _ns.c_ext_global_name if _ns.is_ext else '0'
709 # What our function name is
710 func_name = self.c_request_name
712 func_name = self.c_checked_name
714 func_name = self.c_unchecked_name
718 maxtypelen = len('xcb_connection_t')
720 for field in self.fields:
722 # The field should appear as a call parameter
723 param_fields.append(field)
724 if field.wire and not field.auto:
725 # We need to set the field up in the structure
726 wire_fields.append(field)
728 for field in param_fields:
729 if len(field.c_field_const_type) > maxtypelen:
730 maxtypelen = len(field.c_field_const_type)
736 _h(' * Delivers a request to the X server')
737 _h(' * @param c The connection')
738 _h(' * @return A cookie')
740 _h(' * Delivers a request to the X server.')
743 _h(' * This form can be used only if the request will not cause')
744 _h(' * a reply to be generated. Any returned error will be')
745 _h(' * saved for handling by xcb_request_check().')
747 _h(' * This form can be used only if the request will cause')
748 _h(' * a reply to be generated. Any returned error will be')
749 _h(' * placed in the event queue.')
753 _hc('/*****************************************************************************')
755 _hc(' ** %s %s', cookie_type, func_name)
758 spacing = ' ' * (maxtypelen - len('xcb_connection_t'))
759 _hc(' ** @param xcb_connection_t%s *c', spacing)
761 for field in param_fields:
762 spacing = ' ' * (maxtypelen - len(field.c_field_const_type))
763 _hc(' ** @param %s%s %s%s', field.c_field_const_type, spacing, field.c_pointer, field.c_field_name)
765 _hc(' ** @returns %s', cookie_type)
767 _hc(' *****************************************************************************/')
769 _hc('%s', cookie_type)
771 spacing = ' ' * (maxtypelen - len('xcb_connection_t'))
772 comma = ',' if len(param_fields) else ');'
773 _h('%s (xcb_connection_t%s *c /**< */%s', func_name, spacing, comma)
774 comma = ',' if len(param_fields) else ')'
775 _c('%s (xcb_connection_t%s *c /**< */%s', func_name, spacing, comma)
777 func_spacing = ' ' * (len(func_name) + 2)
778 count = len(param_fields)
779 for field in param_fields:
781 spacing = ' ' * (maxtypelen - len(field.c_field_const_type))
782 comma = ',' if count else ');'
783 _h('%s%s%s %s%s /**< */%s', func_spacing, field.c_field_const_type, spacing, field.c_pointer, field.c_field_name, comma)
784 comma = ',' if count else ')'
785 _c('%s%s%s %s%s /**< */%s', func_spacing, field.c_field_const_type, spacing, field.c_pointer, field.c_field_name, comma)
788 for field in param_fields:
789 if not field.type.fixed_size():
793 _c(' static const xcb_protocol_request_t xcb_req = {')
794 _c(' /* count */ %d,', count)
795 _c(' /* ext */ %s,', func_ext_global)
796 _c(' /* opcode */ %s,', self.c_request_name.upper())
797 _c(' /* isvoid */ %d', 1 if void else 0)
800 _c(' struct iovec xcb_parts[%d];', count + 2)
801 _c(' %s xcb_ret;', func_cookie)
802 _c(' %s xcb_out;', self.c_type)
805 for field in wire_fields:
806 if field.type.fixed_size():
807 if field.type.is_expr:
808 _c(' xcb_out.%s = %s;', field.c_field_name, _c_accessor_get_expr(field.type.expr))
810 elif field.type.is_pad:
811 if field.type.nmemb == 1:
812 _c(' xcb_out.%s = 0;', field.c_field_name)
814 _c(' memset(xcb_out.%s, 0, %d);', field.c_field_name, field.type.nmemb)
816 if field.type.nmemb == 1:
817 _c(' xcb_out.%s = %s;', field.c_field_name, field.c_field_name)
819 _c(' memcpy(xcb_out.%s, %s, %d);', field.c_field_name, field.c_field_name, field.type.nmemb)
822 _c(' xcb_parts[2].iov_base = (char *) &xcb_out;')
823 _c(' xcb_parts[2].iov_len = sizeof(xcb_out);')
824 _c(' xcb_parts[3].iov_base = 0;')
825 _c(' xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3;')
828 for field in param_fields:
829 if not field.type.fixed_size():
830 _c(' xcb_parts[%d].iov_base = (char *) %s;', count, field.c_field_name)
831 if field.type.is_list:
832 _c(' xcb_parts[%d].iov_len = %s * sizeof(%s);', count, _c_accessor_get_expr(field.type.expr), field.type.member.c_wiretype)
834 _c(' xcb_parts[%d].iov_len = %s * sizeof(%s);', count, 'Uh oh', field.type.c_wiretype)
835 _c(' xcb_parts[%d].iov_base = 0;', count + 1)
836 _c(' xcb_parts[%d].iov_len = -xcb_parts[%d].iov_len & 3;', count + 1, count)
839 _c(' xcb_ret.sequence = xcb_send_request(c, %s, xcb_parts + 2, &xcb_req);', func_flags)
840 _c(' return xcb_ret;')
843 def _c_reply(self, name):
845 Declares the function that returns the reply structure.
847 spacing1 = ' ' * (len(self.c_cookie_type) - len('xcb_connection_t'))
848 spacing2 = ' ' * (len(self.c_cookie_type) - len('xcb_generic_error_t'))
849 spacing3 = ' ' * (len(self.c_reply_name) + 2)
853 _h(' * Return the reply')
854 _h(' * @param c The connection')
855 _h(' * @param cookie The cookie')
856 _h(' * @param e The xcb_generic_error_t supplied')
858 _h(' * Returns the reply of the request asked by')
860 _h(' * The parameter @p e supplied to this function must be NULL if')
861 _h(' * %s(). is used.', self.c_unchecked_name)
862 _h(' * Otherwise, it stores the error if any.')
864 _h(' * The returned value must be freed by the caller using free().')
868 _hc('/*****************************************************************************')
870 _hc(' ** %s * %s', self.c_reply_type, self.c_reply_name)
872 _hc(' ** @param xcb_connection_t%s *c', spacing1)
873 _hc(' ** @param %s cookie', self.c_cookie_type)
874 _hc(' ** @param xcb_generic_error_t%s **e', spacing2)
875 _hc(' ** @returns %s *', self.c_reply_type)
877 _hc(' *****************************************************************************/')
879 _hc('%s *', self.c_reply_type)
880 _hc('%s (xcb_connection_t%s *c /**< */,', self.c_reply_name, spacing1)
881 _hc('%s%s cookie /**< */,', spacing3, self.c_cookie_type)
882 _h('%sxcb_generic_error_t%s **e /**< */);', spacing3, spacing2)
883 _c('%sxcb_generic_error_t%s **e /**< */)', spacing3, spacing2)
885 _c(' return (%s *) xcb_wait_for_reply(c, cookie.sequence, e);', self.c_reply_type)
888 def _c_opcode(name, opcode):
890 Declares the opcode define for requests, events, and errors.
894 _h('/** Opcode for %s. */', _n(name))
895 _h('#define %s %s', _n(name).upper(), opcode)
897 def _c_cookie(self, name):
899 Declares the cookie type for a non-void request.
904 _h(' * @brief %s', self.c_cookie_type)
906 _h('typedef struct %s {', self.c_cookie_type)
907 _h(' unsigned int sequence; /**< */')
908 _h('} %s;', self.c_cookie_type)
910 def c_request(self, name):
912 Exported function that handles request declarations.
914 _c_type_setup(self, name, ('request',))
917 # Cookie type declaration
918 _c_cookie(self, name)
921 _c_opcode(name, self.opcode)
923 # Request structure declaration
927 _c_type_setup(self.reply, name, ('reply',))
928 # Reply structure definition
929 _c_complex(self.reply)
931 _c_request_helper(self, name, self.c_cookie_type, False, True)
932 _c_request_helper(self, name, self.c_cookie_type, False, False)
934 _c_accessors(self.reply, name + ('reply',), name)
938 _c_request_helper(self, name, 'xcb_void_cookie_t', True, False)
939 _c_request_helper(self, name, 'xcb_void_cookie_t', True, True)
941 def c_event(self, name):
943 Exported function that handles event declarations.
945 _c_type_setup(self, name, ('event',))
948 _c_opcode(name, self.opcodes[name])
950 if self.name == name:
951 # Structure definition
956 _h('typedef %s %s;', _t(self.name + ('event',)), _t(name + ('event',)))
958 def c_error(self, name):
960 Exported function that handles error declarations.
962 _c_type_setup(self, name, ('error',))
965 _c_opcode(name, self.opcodes[name])
967 if self.name == name:
968 # Structure definition
973 _h('typedef %s %s;', _t(self.name + ('error',)), _t(name + ('error',)))
976 # Main routine starts here
978 # Must create an "output" dictionary before any xcbgen imports.
979 output = {'open' : c_open,
985 'request' : c_request,
990 # Boilerplate below this point
992 # Check for the argument that specifies path to the xcbgen python package.
994 opts, args = getopt.getopt(sys.argv[1:], 'p:')
995 except getopt.GetoptError, err:
997 print 'Usage: c_client.py [-p path] file.xml'
1000 for (opt, arg) in opts:
1002 sys.path.append(arg)
1004 # Import the module class
1006 from xcbgen.state import Module
1009 print 'Failed to load the xcbgen Python package!'
1010 print 'Make sure that xcb/proto installed it on your Python path.'
1011 print 'If not, you will need to create a .pth file or define $PYTHONPATH'
1012 print 'to extend the path.'
1013 print 'Refer to the README file in xcb/proto for more info.'
1017 # Parse the xml header
1018 module = Module(args[0], output)
1020 # Build type-registry and resolve type dependencies