Esempio n. 1
0
    def add_timer(self, callback, data=None):
        """Add timer callback

        Triggers function call after a specified time.

        The callback should take one argument:

            * `data` - any object

        :param callback: Callback function
        :type callback: function with callback `int(void *data)`
        :param data: User data to send to callback
        :type data: `object`
        :returns: :class:`EventSource` for specified callback

        .. seealso::

            :meth:`pywayland.server.eventloop.EventSource.timer_update()`
        """
        callback = CallbackInfo(callback=callback, data=data)
        handle = ffi.new_handle(callback)
        self.callbacks.append(handle)

        event_source_cdata = lib.wl_event_loop_add_timer(
            self._ptr, lib.event_loop_timer_func, handle)
        event_source = EventSource(self, event_source_cdata)
        self.event_sources.add(event_source)

        return event_source
Esempio n. 2
0
    def __init__(self, display, version=None):
        if display._ptr is None or display._ptr == ffi.NULL:
            raise ValueError(
                "Display has been destroyed or couldn't initialize")

        if version is None:
            version = self.interface.version

        # we can't keep alive a handle to self without creating a reference
        # loop, so use this dict as the handle to pass to the global_bind_func
        # callback
        self._callback_info = {"interface": self.interface, "bind_func": None}
        self._handle = ffi.new_handle(self._callback_info)

        ptr = lib.wl_global_create(
            display._ptr,
            self.interface._ptr,
            version,
            self._handle,
            lib.global_bind_func,
        )
        destructor = functools.partial(_global_destroy, display)
        self._ptr = ffi.gc(ptr, destructor)
        self._display = display

        # this c data should keep the display alive
        weakkeydict[self._ptr] = display
Esempio n. 3
0
    def add_signal(self, signal_number, callback, data=None):
        """Add signal callback

        Triggers function call signal is received.

        The callback should take three arguments:

            * `signal_number` - signal (int)
            * `data` - any object

        :param signal_number: Signal number to trigger on
        :type signal_number: `int`
        :param callback: Callback function
        :type fd: function with callback `int(int signal_number, void *data)`
        :param data: User data to send to callback
        :type data: `object`
        :returns: :class:`EventSource` for specified callback
        """
        callback = CallbackInfo(callback=callback, data=data)
        handle = ffi.new_handle(callback)
        self.callbacks.append(handle)

        event_source_cdata = lib.wl_event_loop_add_signal(
            self._ptr, signal_number, lib.event_loop_signal_func, handle)
        event_source = EventSource(self, event_source_cdata)
        self.event_sources.add(event_source)

        return event_source
Esempio n. 4
0
    def __init__(self, client, version=None, id=0):
        if version is None:
            version = self.interface.version

        self.version = version
        self.dispatcher = Dispatcher(self.interface.requests, destructor=True)

        if isinstance(client, Client):
            client_ptr = client._ptr
        else:
            client_ptr = client

        self._ptr = lib.wl_resource_create(client_ptr, self.interface._ptr,
                                           version, id)
        self.id = lib.wl_resource_get_id(self._ptr)

        if self.dispatcher is not None:
            self._handle = ffi.new_handle(self)
            lib.wl_resource_set_dispatcher(
                self._ptr,
                lib.dispatcher_func,
                ffi.NULL,
                self._handle,
                lib.resource_destroy_func,
            )
Esempio n. 5
0
    def add_timer(self, callback, data=None):
        """Add timer callback

        Triggers function call after a specified time.

        :param callback: Callback function
        :type fd: function with callback `int(void *data)`
        :param data: User data to send to callback
        :type data: `object`

        .. seealso::

            :meth:`pywayland.server.eventloop.EventSource.timer_update()`
        """
        if data is None:
            data_ptr = ffi.NULL
        else:
            data_ptr = ffi.new_handle(data)

        callback_ffi = _wrap_timer_callback(callback)
        weakkeydict[self].append(callback_ffi)

        event_source_cdata = lib.wl_event_loop_add_timer(self._ptr, callback_ffi, data_ptr)
        event_source = EventSource(event_source_cdata)
        self._sources.append(event_source)

        return event_source
Esempio n. 6
0
    def add_signal(self, signal_number, callback, data=None):
        """Add signal callback

        Triggers function call signal is received.

        :param signal_number: Signal number to trigger on
        :type signal_number: `int`
        :param callback: Callback function
        :type fd: function with callback `int(int signal_number, void *data)`
        :param data: User data to send to callback
        :type data: `object`
        :returns: :class:`EventSource` for specified callback
        """
        if data is None:
            data_ptr = ffi.NULL
        else:
            data_ptr = ffi.new_handle(data)
            weakkeydict[self].append(data_ptr)

        callback_ffi = _wrap_signal_callback(callback)
        weakkeydict[self].append(callback_ffi)

        event_source_cdata = lib.wl_event_loop_add_signal(self._ptr, signal_number, callback_ffi, data_ptr)
        event_source = EventSource(event_source_cdata)
        self._sources.append(event_source)

        return event_source
Esempio n. 7
0
    def __init__(self, display, version=None):
        if version is None:
            version = self._interface.version

        self._handle = ffi.new_handle(self)
        self._bind_dispatcher = _global_bind_func
        self._ptr = lib.wl_global_create(display._ptr, self._interface._ptr,
                                         version, self._handle, self._bind_dispatcher)

        self.bind_handler = None
Esempio n. 8
0
    def emit(self, data=None):
        """Emits this signal, notifying all registered listeners

        :param data: The data that will be emitted with the signal
        """
        if data is not None:
            data_ptr = ffi.new_handle(data)
        else:
            data_ptr = ffi.NULL
        lib.wl_signal.emit(self._ptr, data_ptr)
Esempio n. 9
0
    def __init__(self, function):
        self._handle = ffi.new_handle(self)

        # we need a way to get this Python object from the `struct
        # wl_listener*`, so we put the pointer in a container struct that
        # contains both the wl_listener and a pointer to our ffi handle
        self.container = ffi.new("struct wl_listener_container *")
        self.container.handle = self._handle

        self._ptr = ffi.addressof(self.container.destroy_listener)
        self._ptr.notify = lib.notify_func
        self._notify = function
        self._signal = None
Esempio n. 10
0
    def add_idle(self, callback, data=None):
        """Add idle callback

        :param callback: Callback function
        :type callback: function with callback `void(void *data)`
        :param data: User data to send to callback
        :returns: :class:`EventSource` for specified callback
        """
        callback = CallbackInfo(callback=callback, data=data)
        handle = ffi.new_handle(callback)
        self.callbacks.append(handle)

        event_source_cdata = lib.wl_event_loop_add_idle(
            self._ptr, lib.event_loop_idle_func, handle)
        event_source = EventSource(self, event_source_cdata)
        self.event_sources.add(event_source)

        return event_source
Esempio n. 11
0
    def __init__(self, client, version=None, id=0):
        if version is None:
            version = self._interface.version

        self._handle = ffi.new_handle(self)
        self.version = version
        self.destructor = None

        if isinstance(client, Client):
            ptr = client._ptr
        else:
            ptr = client

        self._ptr = lib.wl_resource_create(ptr, self._interface._ptr, version, id)
        self.id = lib.wl_resource_get_id(self._ptr)

        lib.wl_resource_set_dispatcher(self._ptr, self.dispatcher._ptr, ffi.NULL,
                                       self._handle, self.dispatcher._destroyed_ptr)
Esempio n. 12
0
    def __init__(self, ptr, display=None):
        """Represents a protocol object on the client side.

        A :class:`Proxy` acts as a client side proxy to an object existing in
        the compositor.  Events coming from the compositor are also handled by
        the proxy, which will in turn call the handler set with
        :func:`Proxy.add_listener`.
        """
        self.user_data = None
        self.dispatcher = Dispatcher(self.interface.events)

        # This should only be true for wl_display proxies, as they will
        # initialize its pointer on a `.connect()` call
        if ptr is None:
            self._ptr = ptr
            self._display = self
            return

        self._display = display

        # parent display is the root-most client Display object, all proxies
        # should keep the display alive
        if display is None:
            raise ValueError(
                "Non-Display Proxy objects must be associated to a Display")
        display._children.add(self)

        if ptr == ffi.NULL:
            raise RuntimeError("Got a null pointer for the proxy")

        # note that even though we cast to a proxy here, the ptr may be a
        # wl_display, so the methods must still cast to 'struct wl_proxy *'
        ptr = ffi.cast('struct wl_proxy *', ptr)
        self._ptr = ffi.gc(ptr, lib.wl_proxy_destroy)

        self._handle = ffi.new_handle(self)
        lib.wl_proxy_add_dispatcher(self._ptr, lib.dispatcher_func,
                                    self._handle, ffi.NULL)

        self.interface.registry[self._ptr] = self
Esempio n. 13
0
    def add_fd(self, fd, callback, mask=FdMask.WL_EVENT_READABLE, data=None):
        """Add file descriptor callback

        Triggers function call when file descriptor state matches the mask.

        The callback should take three arguments:

            * `fd` - file descriptor (int)
            * `mask` - file descriptor mask (uint)
            * `data` - any object

        :param fd: File descriptor
        :type fd: `int`
        :param callback: Callback function
        :type fd: function with callback `int(int fd, uint32_t mask, void
                  *data)`
        :param mask: File descriptor mask
        :type fd: `int`
        :param data: User data to send to callback
        :type data: `object`
        :returns: :class:`EventSource` for specified callback

        .. seealso::

            :meth:`pywayland.server.eventloop.EventSource.check()`
        """
        callback = CallbackInfo(callback=callback, data=data)
        handle = ffi.new_handle(callback)
        self.callbacks.append(handle)

        event_source_cdata = lib.wl_event_loop_add_fd(self._ptr, fd,
                                                      mask.value,
                                                      lib.event_loop_fd_func,
                                                      handle)
        event_source = EventSource(self, event_source_cdata)
        self.event_sources.add(event_source)

        return event_source
Esempio n. 14
0
    def add_fd(self, fd, callback, mask=[fd_mask.WL_EVENT_READABLE], data=None):
        """Add file descriptor callback

        Triggers function call when file descriptor state matches the mask.

        :param fd: File descriptor
        :type fd: `int`
        :param callback: Callback function
        :type fd: function with callback `int(int fd, uint32_t mask, void
                  *data)`
        :param mask: File descriptor mask
        :type fd: `int`
        :param data: User data to send to callback
        :type data: `object`
        :returns: :class:`EventSource` for specified callback

        .. seealso::

            :meth:`pywayland.server.eventloop.EventSource.check()`
        """
        if data is None:
            data_ptr = ffi.NULL
        else:
            data_ptr = ffi.new_handle(data)
            weakkeydict[self].append(data_ptr)

        self._callback_store = callback_ffi = _wrap_fd_callback(callback)
        # weakkeydict[self].append(callback_ffi)

        mask = [m.value for m in mask]
        mask = functools.reduce(lambda x, y: x | y, mask)

        event_source_cdata = lib.wl_event_loop_add_fd(self._ptr, fd, mask, callback_ffi, data_ptr)
        event_source = EventSource(event_source_cdata)
        self._sources.append(event_source)

        return event_source