Example #1
0
    def _gen_c(cls):
        """Creates the wl_interface C struct

        Generates the CFFI cdata for the wl_interface struct given by the
        interface.
        """
        # Initialize the interface cdata
        cls._ptr.name = name = ffi.new('char[]', cls.name.encode())
        cls._ptr.version = cls.version

        # Determine the number of methods to assign and assign them
        cls._ptr.method_count = len(cls.requests)
        cls._ptr.methods = methods_ptr = ffi.new("struct wl_message[]", len(cls.requests))
        # Iterate over the methods
        for i, message in enumerate(cls.requests):
            # First, generate the wl_message cdata
            msg_buf = ffi.buffer(message._ptr)
            methods_buf = ffi.buffer(methods_ptr + i)
            # Copy the contents of the cdata into the allocated cdata
            methods_buf[:] = msg_buf

        cls._ptr.event_count = len(cls.events)
        cls._ptr.events = events_ptr = ffi.new("struct wl_message[]", len(cls.events))
        # Iterate over the methods
        for i, message in enumerate(cls.events):
            # First, generate the wl_message cdata
            msg_buf = ffi.buffer(message._ptr)
            events_buf = ffi.buffer(events_ptr + i)
            # Copy the contents of the cdata into the allocated cdata
            events_buf[:] = msg_buf

        weakkeydict[cls._ptr] = (name, methods_ptr, events_ptr)
Example #2
0
    def c_to_arguments(self, args_ptr):
        """Create a list of arguments

        Generate the arguments of the method from a CFFI cdata array of
        `wl_argument` structs that correspond to the arguments of the method as
        specified by the method signature.

        :param args_ptr: Input arguments
        :type args_ptr: cdata `union wl_argument []`
        :returns: list of args
        """
        args = []
        for i, argument in enumerate(self.arguments):
            arg_ptr = args_ptr[i]

            # Match numbers (int, unsigned, float, file descriptor)
            if argument.argument_type == ArgumentType.Int:
                args.append(arg_ptr.i)
            elif argument.argument_type == ArgumentType.Uint:
                args.append(arg_ptr.u)
            elif argument.argument_type == ArgumentType.Fixed:
                f = lib.wl_fixed_to_double(arg_ptr.f)
                args.append(f)
            elif argument.argument_type == ArgumentType.FileDescriptor:
                args.append(arg_ptr.h)
            elif argument.argument_type == ArgumentType.String:
                if arg_ptr == ffi.NULL:
                    if not argument.nullable:
                        raise Exception
                    args.append(None)
                else:
                    args.append(ffi.string(arg_ptr.s).decode())
            elif argument.argument_type == ArgumentType.Object:
                if arg_ptr.o == ffi.NULL:
                    if not argument.nullable:
                        message = "Got null object parsing arguments for '{}' message, may already be destroyed".format(
                            self.name)
                        raise RuntimeError(message)
                    args.append(None)
                else:
                    iface = self.types[i]
                    proxy_ptr = ffi.cast('struct wl_proxy *', arg_ptr.o)
                    obj = iface.proxy_class.registry.get(proxy_ptr)
                    if obj is None:
                        raise RuntimeError(
                            "Unable to get object for {}, was it garbage collected?"
                            .format(proxy_ptr))
                    args.append(obj)
            elif argument.argument_type == ArgumentType.NewId:
                # TODO
                raise NotImplementedError
            elif argument.argument_type == ArgumentType.Array:
                array_ptr = arg_ptr.a
                args.append(ffi.buffer(array_ptr.data, array_ptr.size)[:])
            else:
                raise Exception(f"Bad argument: {argument}")

        return args
Example #3
0
    def arguments_to_c(self, *args):
        """Create an array of `wl_argument` C structs

        Generate the CFFI cdata array of `wl_argument` structs that correspond
        to the arguments of the method as specified by the method signature.

        :param args: Input arguments
        :type args: `list`
        :returns: cdata `union wl_argument []` of args
        """
        nargs = len(list(self._marshaled_arguments))
        args_ptr = ffi.new('union wl_argument []', nargs)

        arg_iter = iter(args)
        refs = []
        for i, argument in enumerate(self._marshaled_arguments):
            # New id (set to null for now, will be assigned on marshal)
            # Then, continue so we don't consume an arg
            if argument.argument_type == ArgumentType.NewId:
                args_ptr[i].o = ffi.NULL
                continue

            arg = next(arg_iter)
            # Match numbers (int, unsigned, float, file descriptor)
            if argument.argument_type == ArgumentType.Int:
                args_ptr[i].i = arg
            elif argument.argument_type == ArgumentType.Uint:
                args_ptr[i].u = arg
            elif argument.argument_type == ArgumentType.Fixed:
                if isinstance(arg, int):
                    f = lib.wl_fixed_from_int(arg)
                else:
                    f = lib.wl_fixed_from_double(arg)
                args_ptr[i].f = f
            elif argument.argument_type == ArgumentType.FileDescriptor:
                args_ptr[i].h = arg
            elif argument.argument_type == ArgumentType.String:
                if arg is None:
                    if not argument.nullable:
                        raise Exception
                    new_arg = ffi.NULL
                else:
                    new_arg = ffi.new('char []', arg.encode())
                    refs.append(new_arg)
                args_ptr[i].s = new_arg
            elif argument.argument_type == ArgumentType.Object:
                if arg is None:
                    if not argument.nullable:
                        raise Exception
                    new_arg = ffi.NULL
                else:
                    new_arg = ffi.cast('struct wl_object *', arg._ptr)
                    refs.append(new_arg)
                args_ptr[i].o = new_arg
            elif argument.argument_type == ArgumentType.Array:
                # TODO: this is a bit messy, we probably don't want to put everything in one buffer like this
                new_arg = ffi.new('struct wl_array *')
                new_data = ffi.new('void []', len(arg))
                new_arg.alloc = new_arg.size = len(arg)
                ffi.buffer(new_data)[:] = arg
                refs.append(new_arg)
                refs.append(new_data)

        if len(refs) > 0:
            weakkeydict[args_ptr] = tuple(refs)

        return args_ptr
Example #4
0
    def arguments_to_c(self, *args):
        """Create an array of `wl_argument` C structs

        Generate the CFFI cdata array of `wl_argument` structs that correspond
        to the arguments of the method as specified by the method signature.

        :param args: Input arguments
        :type args: `list`
        :returns: cdata `union wl_argument []` of args
        """
        nargs = len(re_arg.findall(self.signature))
        args_ptr = ffi.new('union wl_argument []', nargs)

        arg_iter = iter(args)
        refs = []
        for i, sig_match in enumerate(re_arg.finditer(self.signature)):
            null, sig = sig_match.groups()

            # New id (set to null for now, will be assigned on marshal)
            # Then, continue so we don't consume an arg
            if sig == 'n':
                args_ptr[i].o = ffi.NULL
                continue
            arg = next(arg_iter)
            # Match numbers (int, unsigned, float, file descriptor)
            if sig == 'i':
                args_ptr[i].i = arg
            elif sig == 'u':
                args_ptr[i].u = arg
            elif sig == 'f':
                if isinstance(arg, int):
                    f = lib.wl_fixed_from_int(arg)
                else:
                    f = lib.wl_fixed_from_double(arg)
                args_ptr[i].f = f
            elif sig == 'h':
                args_ptr[i].h = arg
            # Match string
            elif sig == 's':
                if arg is None:
                    if not null:
                        raise Exception
                    new_arg = ffi.NULL
                else:
                    new_arg = ffi.new('char []', arg.encode())
                    refs.append(new_arg)
                args_ptr[i].s = new_arg
            # Object
            elif sig == 'o':
                if arg is None:
                    if not null:
                        raise Exception
                    new_arg = ffi.NULL
                else:
                    new_arg = ffi.cast('struct wl_object *', arg._ptr)
                    refs.append(new_arg)
                args_ptr[i].o = new_arg
            # Array (i.e. buffer of bytes)
            elif sig == 'a':
                new_arg = ffi.new('struct wl_array *')
                new_data = ffi.new('void []', len(arg))
                new_arg.alloc = new_arg.size = len(arg)
                ffi.buffer(new_data)[:] = arg
                refs.append(new_arg)
                refs.append(new_data)

        if refs:
            weakkeydict[args_ptr] = refs

        return args_ptr