def all_devices(cls, display, master_only=False): """ Iterate over all input devices registered on the given ``display``. ``display`` is a :class:`~synaptiks.x11.Display` object. If ``master_only`` is ``True``, only master devices are returned. In this case, the returned iterator yields only two devices in most cases, a master keyboard and a master slave (the exact order is undefined). Return an iterator over :class:`InputDevice` objects. Raise :exc:`XInputVersionError`, if the XInput version isn't sufficient to support input device management. .. seealso:: :attr:`is_master` """ assert_xinput_version(display) if master_only: device_id = xinput.ALL_MASTER_DEVICES else: device_id = xinput.ALL_DEVICES number_of_devices, devices = xinput.query_device(display, device_id) with scoped_pointer(devices, xinput.free_device_info) as devices: if not devices: raise EnvironmentError('Failed to query devices') for i in xrange(number_of_devices): yield cls(display, devices[i].deviceid)
def handle_event(_, data): with scoped_pointer(data, xrecord.free_data): if data.contents.category != xrecord.FROM_SERVER: return event_type, keycode = data.contents.event event_name = EVENT_NAMES[event_type] print('{0}: {1}'.format(event_name, keycode))
def __len__(self): """ Return the amount of all properties defined on this device. """ number_of_properties, property_atoms = xinput.list_properties( self.display, self.id) with scoped_pointer(property_atoms, xlib.free): return number_of_properties
def _handle_event(self, _, data): with scoped_pointer(data, xrecord.free_data): if data.contents.category == xrecord.START_OF_DATA: # the recorder has started self._started.set() elif data.contents.category == xrecord.FROM_SERVER: event_type, keycode = data.contents.event signal = self._event_signal_map.get(event_type) if signal is not None: signal.emit(keycode)
def get_property(display, deviceid, property): """ Get the given ``property`` from the device with the given id. ``display`` is a :class:`~synaptiks._bindings.xlib.Display_p` providing the server connection, ``deviceid`` is an integer with a device id. ``property`` is a :class:`~synaptiks._bindings.xlib.Atom` with the X11 atom of the property to get. Return a tuple ``(type, format, data)``. ``type`` and ``format`` are integers, ``data`` is a byte string. If the property exists on the device, ``type`` contains the type atom, ``format`` the format of the property (on of ``8``, ``16`` or ``32``) and ``data`` the property contents as bytes. Otherwise ``type`` is :data:`~synaptiks._bindings.xlib.NONE` and ``format`` is ``0``. ``data`` contains an empty string. """ length = 1 while True: type_return = xlib.Atom(0) format_return = c_int(0) num_items_return = c_ulong(0) bytes_after_return = c_ulong(0) data = c_byte_p() state = libXi.XIGetProperty(display, deviceid, property, 0, length, False, ANY_PROPERTY_TYPE, byref(type_return), byref(format_return), byref(num_items_return), byref(bytes_after_return), byref(data)) with scoped_pointer(data, xlib.free): if state != xlib.SUCCESS: # XXX: better diagnostics raise EnvironmentError() if bytes_after_return.value == 0: # got all bytes now, handle them format = format_return.value type = type_return.value number_of_items = num_items_return.value byte_length = number_of_items * format // 8 return (type, format, string_at(data, byte_length)) else: # get some more bytes and try again length += 1
def get_modifier_mapping(display): """ Get the modifier mapping. ``display`` is a :class:`Display_p` providing the server connection. Return a :class:`ModifierMap` tuple, where each element is another plain tuple which contains :data:`KeyCode` objects (which are basically just bytes). Zero keycodes are meaningless in all these tuples. """ modifier_map = libX11.XGetModifierMapping(display) with scoped_pointer(modifier_map, libX11.XFreeModifiermap): keys_per_modifier = modifier_map.contents.max_keypermod keycodes = [modifier_map.contents.modifiermap[i] for i in xrange(8 * keys_per_modifier)] modifier_keys = izip(*[islice(keycodes, i, None, keys_per_modifier) for i in xrange(keys_per_modifier)]) return ModifierMap(*modifier_keys)
def record_range(device_events=None): """ Create a recording range for the given ``device_events`` and wrap it into a context manager. ``device_events`` is a two-component tuple ``(first, last)``, where ``first`` is the first event to be recorded, and ``last`` is the last event. Return a :class:`XRecordRange_p` object containing the record range. """ with scoped_pointer(alloc_range(), xlib.free) as record_range_p: record_range = record_range_p.contents if device_events: first, last = device_events record_range.device_events.first = first record_range.device_events.last = last yield record_range_p
def get_property(display, deviceid, property): """ Get the given ``property`` from the device with the given id. ``display`` is a :class:`~synaptiks._bindings.xlib.Display_p` providing the server connection, ``deviceid`` is an integer with a device id. ``property`` is a :class:`~synaptiks._bindings.xlib.Atom` with the X11 atom of the property to get. Return a tuple ``(type, format, data)``. ``type`` and ``format`` are integers, ``data`` is a byte string. If the property exists on the device, ``type`` contains the type atom, ``format`` the format of the property (on of ``8``, ``16`` or ``32``) and ``data`` the property contents as bytes. Otherwise ``type`` is :data:`~synaptiks._bindings.xlib.NONE` and ``format`` is ``0``. ``data`` contains an empty string. """ length = 1 while True: type_return = xlib.Atom(0) format_return = c_int(0) num_items_return = c_ulong(0) bytes_after_return = c_ulong(0) data = c_byte_p() state = libXi.XIGetProperty( display, deviceid, property, 0, length, False, ANY_PROPERTY_TYPE, byref(type_return), byref(format_return), byref(num_items_return), byref(bytes_after_return), byref(data)) with scoped_pointer(data, xlib.free): if state != xlib.SUCCESS: # XXX: better diagnostics raise EnvironmentError() if bytes_after_return.value == 0: # got all bytes now, handle them format = format_return.value type = type_return.value number_of_items = num_items_return.value byte_length = number_of_items * format // 8 return (type, format, string_at(data, byte_length)) else: # get some more bytes and try again length += 1
def get_modifier_mapping(display): """ Get the modifier mapping. ``display`` is a :class:`Display_p` providing the server connection. Return a :class:`ModifierMap` tuple, where each element is another plain tuple which contains :data:`KeyCode` objects (which are basically just bytes). Zero keycodes are meaningless in all these tuples. """ modifier_map = libX11.XGetModifierMapping(display) with scoped_pointer(modifier_map, libX11.XFreeModifiermap): keys_per_modifier = modifier_map.contents.max_keypermod keycodes = [ modifier_map.contents.modifiermap[i] for i in xrange(8 * keys_per_modifier) ] modifier_keys = izip(*[ islice(keycodes, i, None, keys_per_modifier) for i in xrange(keys_per_modifier) ]) return ModifierMap(*modifier_keys)
def _iter_property_atoms(self): number_of_properties, property_atoms = xinput.list_properties( self.display, self.id) with scoped_pointer(property_atoms, xlib.free): for i in xrange(number_of_properties): yield Atom(self.display, property_atoms[i])
def test_scoped_pointer(): deleter = mock.Mock() with util.scoped_pointer(mock.sentinel.pointer, deleter) as pointer: assert pointer is mock.sentinel.pointer deleter.assert_called_with(mock.sentinel.pointer)