Example #1
0
 def keymap_new_from_file(self, file, format=lib.XKB_KEYMAP_FORMAT_TEXT_V1):
     "Create a Keymap from an open file"
     try:
         fn = file.fileno()
     except:
         fn = None
     if fn:
         load_method = "mmap_file"
         mm = mmap.mmap(fn, 0)
         buf = ffi.from_buffer(mm)
         r = lib.xkb_keymap_new_from_buffer(self._context, buf, mm.size(),
                                            format,
                                            lib.XKB_KEYMAP_COMPILE_NO_FLAGS)
         del buf
         mm.close()
     else:
         load_method = "read_file"
         keymap = file.read()
         buf = ffi.new("char[]", keymap)
         r = lib.xkb_keymap_new_from_string(self._context, buf, format,
                                            lib.XKB_KEYMAP_COMPILE_NO_FLAGS)
     if r == ffi.NULL:
         raise XKBKeymapCreationFailure(
             "xkb_keymap_new_from_buffer or xkb_keymap_new_from_string "
             "returned NULL")
     return Keymap(self, r, load_method)
Example #2
0
    def keymap_new_from_names(self,
                              rules=None,
                              model=None,
                              layout=None,
                              variant=None,
                              options=None):
        """Create a keymap from RMLVO names.

        The primary keymap entry point: creates a new XKB keymap from
        a set of RMLVO (Rules + Model + Layouts + Variants + Options)
        names.

        Returns a Keymap compiled according to the RMLVO names, or
        None if the compilation failed.
        """
        names = ffi.new("struct xkb_rule_names *")
        if rules:
            names.rules = rules.encode()
        if model:
            names.model = model.encode()
        if layout:
            names.layout = layout.encode()
        if variant:
            names.variant = variant.encode()
        if options:
            names.options = options.encode()
        r = lib.xkb_keymap_new_from_names(self._context, names,
                                          lib.XKB_KEYMAP_COMPILE_NO_FLAGS)
        if r == ffi.NULL:
            raise XKBKeymapCreationFailure(
                "xkb_keymap_new_from_names returned NULL")
        return Keymap(self, r, "names")
Example #3
0
def keysym_to_string(keysym):
    buffer = ffi.new("char[64]")
    r = lib.xkb_keysym_to_utf8(keysym, buffer, len(buffer))
    if r == -1:
        raise XKBBufferTooSmall()
    if r == 0:
        return
    return ffi.string(buffer).decode('utf8')
Example #4
0
def keysym_get_name(keysym):
    "Get the name of a keysym."
    name = ffi.new("char[64]")
    r = lib.xkb_keysym_get_name(keysym, name, len(name))
    if r == -1:
        raise XKBInvalidKeysym()
    if r > len(name):
        raise XKBBufferTooSmall()
    return ffi.string(name).decode('ascii')
Example #5
0
    def led_get_index(self, name):
        """Get the index of a LED by name.

        Returns the index. If no LED with this name exists, returns
        lib.XKB_LED_INVALID.
        """
        r = lib.xkb_keymap_led_get_index(
            self._keymap, ffi.new("char []", name.encode('ascii')))
        if r == lib.XKB_LED_INVALID:
            raise XKBLEDDoesNotExist(name)
        return r
Example #6
0
    def mod_get_index(self, name):
        """Get the index of a modifier by name.

        Returns the index.  If no modifier with this name exists,
        raises XKBModifierDoesNotExist.
        """
        r = lib.xkb_keymap_mod_get_index(
            self._keymap, ffi.new("char []", name.encode('ascii')))
        if r == lib.XKB_MOD_INVALID:
            raise XKBModifierDoesNotExist(name)
        return r
Example #7
0
 def keymap_new_from_string(self,
                            string,
                            format=lib.XKB_KEYMAP_FORMAT_TEXT_V1):
     "Create a Keymap from a keymap string."
     buf = ffi.new("char[]", string.encode("ascii"))
     r = lib.xkb_keymap_new_from_string(self._context, buf, format,
                                        lib.XKB_KEYMAP_COMPILE_NO_FLAGS)
     if r == ffi.NULL:
         raise XKBKeymapCreationFailure(
             "xkb_keymap_new_from_string returned NULL")
     return Keymap(self, r, "string")
Example #8
0
    def layout_get_index(self, name):
        """Get the index of a layout by name.

        Returns the index.  If no layout exists with this name, raises
        XKBLayoutDoesNotExist. If more than one layout in the keymap
        has this name, returns the lowest index among them.
        """
        r = lib.xkb_keymap_layout_get_index(
            self._keymap, ffi.new("char []", name.encode('ascii')))
        if r == lib.XKB_LAYOUT_INVALID:
            raise XKBLayoutDoesNotExist(name)
        return r
Example #9
0
    def led_name_is_active(self, name):
        """Test whether a LED is active in a given keyboard state by name.

        Returns True if the LED is active, False if it is not.  If no
        LED with this name exists in the keymap, raises
        XKBLEDDoesNotExist.
        """
        buf = ffi.new("char []", name.encode('ascii'))
        r = lib.xkb_state_led_name_is_active(self._state, buf)
        if r == -1:
            raise XKBLEDDoesNotExist(name)
        return r == 1
Example #10
0
    def keymap_new_from_names(self,
                              rules=None,
                              model=None,
                              layout=None,
                              variant=None,
                              options=None):
        """Create a keymap from RMLVO names.

        The primary keymap entry point: creates a new XKB keymap from
        a set of RMLVO (Rules + Model + Layouts + Variants + Options)
        names.

        Returns a Keymap compiled according to the RMLVO names, or
        None if the compilation failed.
        """
        # CFFI memory management note:
        # The C strings allocated below using ffi.new("char[]", ...)
        # are automatically deallocated when there are no remaining
        # python references to them. Being assigned to members of the
        # 'names' struct does not count as a reference! We keep
        # references to them in the 'keep_alive' list until after the
        # call to xkb_keymap_new_from_names() to avoid problems with
        # use-after-free.
        names = ffi.new("struct xkb_rule_names *")
        keep_alive = []
        for x in ("rules", "model", "layout", "variant", "options"):
            if locals()[x]:
                c = ffi.new("char[]", locals()[x].encode())
                setattr(names, x, c)
                keep_alive.append(c)
        r = lib.xkb_keymap_new_from_names(self._context, names,
                                          lib.XKB_KEYMAP_COMPILE_NO_FLAGS)
        del keep_alive, names
        if r == ffi.NULL:
            raise XKBKeymapCreationFailure(
                "xkb_keymap_new_from_names returned NULL")
        return Keymap(self, r, "names")
Example #11
0
    def key_get_string(self, key):
        """Get the Unicode/UTF-8 string obtained from pressing a particular
        key in a given keyboard state.

        This function performs Capitalization and Control Keysym
        Transformations.

        Returns the string.  If there is nothing to return, returns
        the empty string.
        """
        buffer = ffi.new("char[64]")
        r = lib.xkb_state_key_get_utf8(self._state, key, buffer, len(buffer))
        if r + 1 > len(buffer):
            raise XKBBufferTooSmall()
        return ffi.string(buffer).decode('utf8')
Example #12
0
    def layout_name_is_active(self, name, type):
        """Test whether a layout is active in a given keyboard state by name.

        Returns True if the layout is active, False if it is not.  If
        no layout with this name exists in the keymap, raises
        XKBLayoutDoesNotExist.

        If multiple layouts in the keymap have this name, the one with
        the lowest index is tested.
        """
        buf = ffi.new("char []", name.encode('ascii'))
        r = lib.xkb_state_layout_name_is_active(self._state, buf, type)
        if r == -1:
            raise XKBLayoutDoesNotExist(name)
        return r == 1
Example #13
0
    def mod_name_is_active(self, name, type):
        """Test whether a modifier is active in a given keyboard state by
        name.

        type is the component of the state against which to match the
        given modifiers.

        Returns True if the modifier is active, False if it is not.
        If the modifier name does not exist in the keymap, raises
        XKBModifierDoesNotExist.
        """
        buf = ffi.new("char []", name.encode('ascii'))
        r = lib.xkb_state_mod_name_is_active(self._state, buf, type)
        if r == -1:
            raise XKBModifierDoesNotExist(name)
        return r == 1
Example #14
0
    def key_get_syms_by_level(self, key, layout, level):
        """Get the keysyms obtained from pressing a key in a given layout and
        shift level.

        This function is like State.key_get_syms(), only the layout
        and shift level are not derived from the keyboard state but
        are instead specified explicitly.

        Returns a list of keysyms.
        """
        syms_out = ffi.new("const xkb_keysym_t **")
        r = lib.xkb_keymap_key_get_syms_by_level(self._keymap, key, layout,
                                                 level, syms_out)
        syms = []
        if r > 0:
            assert syms_out[0] != ffi.NULL
        for i in range(0, r):
            syms.append(syms_out[0][i])
        return syms
Example #15
0
    def mod_names_are_active(self, type, match, names):
        """Test whether a set of modifiers are active in a given keyboard
        state by name.

        type is the component of the state against which to match the
        given modifiers.

        match is the manner by which to match the state against the
        given modifiers.

        names is an iterable of modifier names to test.

        Returns True if the modifiers are active, False if they are
        not.  If any of the modifier names do not exist, raises
        XKBModifierDoesNotExist(None).
        """
        args = [ffi.new("char []", n.encode('ascii')) for n in names]
        args.append(ffi.NULL)
        r = lib.xkb_state_mod_names_are_active(self._state, type, match, *args)
        if r == -1:
            raise XKBModifierDoesNotExist(None)
        return r == 1
Example #16
0
    def key_get_syms(self, key):
        """Get the keysyms obtained from pressing a particular key in a given
        keyboard state.

        Get the keysyms for a key according to the current active
        layout, modifiers and shift level for the key, as determined
        by a keyboard state.

        As an extension to XKB, this function can return more than one
        keysym. If you do not want to handle this case, you can use
        KeyboardState.key_get_one_sym() for a simpler interface.

        This function does not perform any Keysym
        Transformations. (This might change).
        """
        syms_out = ffi.new("const xkb_keysym_t **")
        r = lib.xkb_state_key_get_syms(self._state, key, syms_out)
        syms = []
        if r > 0:
            assert syms_out[0] != ffi.NULL
        for i in range(0, r):
            syms.append(syms_out[0][i])
        return syms