def py_reply(self, name): ''' Handles reply declarations. ''' setup_type(self, name, 'Reply') cls = PyClass(self.py_reply_name) cls.base = 'ooxcb.Reply' init = cls.new_method('__init__') init.arguments.extend(['conn']) init.code.append('ooxcb.Reply.__init__(self, conn)') py_complex(self, name, cls) ALL[cls.name] = cls # TODO: to WRAPPERS, too?
def py_simple(self, name): ''' Exported function that handles cardinal declarations. These are types which are typedef'd to one of the CARDx's char, float, etc. ''' setup_type(self, name, '') if not is_ignored(name): # create a class ... clsname = pythonize_classname(strip_ns(name)) cls = PyClass(clsname) cls.base = 'ooxcb.Resource' init = cls.new_method('__init__') init.arguments.extend(['conn', 'xid']) init.code.append('ooxcb.Resource.__init__(self, conn, xid)') WRAPPERS[strip_ns(name)] = cls ALL[clsname] = cls
def py_enum(self, name): ''' Exported function that handles enum declarations. ''' if is_ignored(name): return cls = PyClass(strip_ns(name)) count = 0 for (enam, evalue) in self.values: cls.new_attribute(prefix_if_needed(enam), evalue if evalue != '' else count) count += 1 ALL[cls.name] = cls cls.is_enum = True
def py_error(self, name): setup_type(self, name, 'Error') struct = PyClass(self.py_error_name) struct.base = 'ooxcb.Error' init = struct.new_method('__init__') init.arguments.extend(['conn']) init.code.append('ooxcb.Error.__init__(self, conn)') ALL[self.py_error_name] = WRAPPERS[self.py_error_name] = struct py_complex(self, name, struct) # Exception definition exc = PyClass(self.py_except_name) exc.base = 'ooxcb.ProtocolException' ALL[self.py_except_name] = exc # Opcode define ERRORS[self.opcodes[name]] = '(%s, %s)' % (self.py_error_name, self.py_except_name)
def py_request(self, name): ''' Exported function that handles request declarations. ''' setup_type(self, name, 'Request') if self.reply: # Cookie class declaration cookiecls = PyClass(self.py_cookie_name) cookiecls.base = 'ooxcb.Cookie' ALL[self.py_cookie_name] = cookiecls if self.reply: # Reply class definition py_reply(self.reply, name) # Request prototypes request_helper(self, name, False, True) request_helper(self, name, False, False) else: # Request prototypes request_helper(self, name, True, False) request_helper(self, name, True, True)
def py_struct(self, oldname): name = (oldname[-2], pythonize_classname(oldname[-1])) setup_type(self, name) cls = PyClass(self.py_type) cls.base = 'ooxcb.Struct' init = cls.new_method('__init__') if self.fixed_size(): init.arguments += ['conn'] init.code.append('ooxcb.Struct.__init__(self, conn)') else: init.arguments += ['conn'] init.code.append('ooxcb.Struct.__init__(self, conn)') py_complex(self, name, cls) if not self.fixed_size(): cls.get_member_by_name('read').code.append('self.size = stream.tell() - root') ALL[strip_ns(name)] = cls WRAPPERS[strip_ns(oldname)] = cls
def py_event(self, name): setup_type(self, name, 'Event') entry = INTERFACE.get('Events', {}).get(strip_ns(name), {}) clsname = entry.get('classname', self.py_event_name) # Opcode define EVENTS[self.opcodes[name]] = clsname eventname = ('"%s"' % entry.get('eventname', 'on_%s' % pythonize_camelcase_name(strip_ns(name)))) struct = PyClass(clsname) struct.base = 'ooxcb.Event' struct.new_attribute('event_name', eventname) # each event class has an `opcode` attribute struct.new_attribute('opcode', self.opcodes[name]) if not entry: clsname, membername = ('ooxcb.Connection', 'conn') else: membername = entry['member'] # here we want to register the events to the original class. # TODO: The way I am doing that here is dirty. clsname = '"%s"' % entry.get('class', get_wrapped(get_field_by_name(self.fields, membername).py_type).replace('Mixin', '')) # the classnames are resolved later. see generate_all. struct.new_attribute('event_target_class', clsname) init = struct.new_method('__init__') init.arguments.extend(['conn']) init.code.append('ooxcb.Event.__init__(self, conn)') ALL[self.py_event_name] = WRAPPERS[self.py_event_name] = struct py_complex(self, name, struct) struct.get_member_by_name('read').code.append('self.event_target = self.%s' % membername)
def py_union(self, name): ''' Exported function that handles union declarations. ''' setup_type(self, name) cls = PyClass(self.py_type) cls.base = 'ooxcb.Union' init = cls.new_method('__init__') if self.fixed_size(): init.arguments += ['conn'] init.code.append('ooxcb.Union.__init__(self, conn)') else: init.arguments += ['conn'] init.code.append('ooxcb.Union.__init__(self, conn)') read = cls.new_method('read') read.arguments.append('stream') build = cls.new_method('build') build.arguments.append('stream') read.code.append('count = 0') read.code.append('root = stream.tell()') build.code.append('root = stream.tell()') kw = 'if' # the first iteration has an if! for field in self.fields: # TODO: is it possible to have wrapped objects in unions? if yes, what to do? # TODO: we should check against None. What if we send the int 0 in an union? build.code.append('%s self.%s:' % (kw, prefix_if_needed(field.field_name))) build.code.append(INDENT) if field.type.is_simple: read.code.append('self.%s = unpack_from_stream("=%s", stream)' % \ (prefix_if_needed(field.field_name), field.type.py_format_str)) read.code.append('count = max(count, %s)', field.type.size) read.code.append('stream.seek(root)') build.code.append( 'stream.write(pack("=%s", %s))' % (field.py_format_str, prefix_if_needed(field.field_name)) ) # add a simple default value. init.code.append('self.%s = None' % (prefix_if_needed(field.field_name))) elif field.type.is_list: read.code.append('self.%s = ooxcb.List(self.conn, stream, %s, %s, %s)' % \ (prefix_if_needed(field.field_name), get_expr(field.type.expr), field.py_listtype, field.py_listsize)) read.code.append('count = max(count, self.%s.size)' % prefix_if_needed(field.field_name)) read.code.append('stream.seek(root)') build.code.append( 'build_list(self.conn, stream, self.%s, %s)' % (prefix_if_needed(field.field_name), field.py_listtype) ) init.code.append('self.%s = []' % (prefix_if_needed(field.field_name))) elif field.type.is_container and field.type.fixed_size(): read.code.append('self.%s = %s.create_from_stream(self.conn, stream)' % (prefix_if_needed(field.field_name), field.py_type, field.type.size)) read.code.append('count = max(count, %s)' % field.type.size) read.code.append('stream.seek(root)') build.code.append('self.%s.build(stream)' % prefix_if_needed(field.field_name)) init.code.append('self.%s = None' % (prefix_if_needed(field.field_name))) else: read.code.append('self.%s = %s.create_from_stream(self.conn, stream)' % (prefix_if_needed(field.field_name), field.py_type)) read.code.append('count = max(count, self.%s.size)' % prefix_if_needed(field.field_name)) read.code.append('stream.seek(root)') build.code.append('self.%s.build(stream)' % prefix_if_needed(field.field_name)) init.code.append('self.%s = None' % (prefix_if_needed(field.field_name))) kw = 'elif' # all further iterations have an elif. build.code.append(DEDENT) # using this dirty stuff to get the total length # of the union. TODO: what for not-fixed-size unions? assert self.fixed_size() size = self.fields[0].type.py_format_len build.code.extend(['else:', INDENT, 'raise ooxcb.XcbException("No value set in the union!")', DEDENT, # check if the union has the correct size. if not, append dummy bytes. 'if stream.tell() - root < %d:' % size, INDENT, 'stream.write(pack("=" + "x" * (%d - (stream.tell() - root))))' % size, DEDENT, ]) if not self.fixed_size(): read.code.append('ooxcb._resize_obj(self, count)') ALL[cls.name] = cls WRAPPERS[strip_ns(name)] = cls
print 'If not, you will need to create a .pth file or define $PYTHONPATH' print 'to extend the path.' print 'Refer to the README file in xcb/proto for more info.' print '' raise import xcbgen if len(sys.argv) > 1: # provided with a module name MODNAME = sys.argv[1] else: MODNAME = 'xproto' print >>sys.stderr, 'Wrapping %s ...' % MODNAME EXTCLS = PyClass('%sExtension' % MODNAME) EXTCLS.new_attribute('header', '"%s"' % MODNAME) EXTCLS.base = 'ooxcb.Extension' ALL['%sExtension' % MODNAME] = EXTCLS try: ifile = open('%s.i' % MODNAME, 'r') INTERFACE = yaml.load(ifile.read()) finally: ifile.close() module = Module('%s.xml' % MODNAME, output)