コード例 #1
0
def toggle(program, state):
    '''
    Toggles the running state of the given progam.

    If state is true, the program will be spawned.

    :param str program: Name of the program
    :param bool state: Desired state
    :returns: None
    '''
    if state:
        try:
            tps.check_output(['pgrep', program], logger)
        except subprocess.CalledProcessError:
            if tps.has_program(program):
                logger.debug(program)
                subprocess.Popen([program])
            else:
                logger.warning('{} is not installed'.format(program))
    else:
        try:
            tps.check_output(['pgrep', program], logger)
            tps.check_call(['killall', program], logger)
        except subprocess.CalledProcessError:
            pass
コード例 #2
0
def toggle(program, state):
    '''
    Toggles the running state of the given progam.

    If state is true, the program will be spawned.

    :param str program: Name of the program
    :param bool state: Desired state
    :returns: None
    '''
    if state:
        try:
            tps.check_output(['pgrep', program], logger)
        except subprocess.CalledProcessError:
            if tps.has_program(program):
                logger.debug(program)
                subprocess.Popen([program])
            else:
                logger.warning('{} is not installed'.format(program))
    else:
        try:
            tps.check_output(['pgrep', program], logger)
            tps.check_call(['killall', program], logger)
        except subprocess.CalledProcessError:
            pass
コード例 #3
0
ファイル: rotate.py プロジェクト: sniffer/thinkpad-scripts
def can_use_chvt():
    """
    Checks whether ``chvt`` can be called with ``sudo`` without a password.

    The ``sudo`` command has the ``-n`` option which will just make the command
    fail when the user does not have the appropriate permissions. The problem
    with ``chvt`` is that it does not have any intelligent command line
    argument parsing. If will return code 1 if no argument is given, the same
    code that ``sudo`` gives when no permission is available. Therefore I chose
    to use ``sudo -l` to get the whole list and see whether the full path to
    ``chvt`` is in there. This might break on Fedora where the ``usr``-merge
    has been done now.

    The following line is needed in a file like ``/etc/sudoers.d/chvt``::

        myuser  ALL = NOPASSWD: /bin/chvt

    You have to replace ``myuser`` which your username. Giving too broad
    permissions to every other user account is probably not a good idea.

    :rtype: bool
    """
    command = ["sudo", "-l"]
    output = tps.check_output(command, logger)

    return b"/bin/chvt" in output
コード例 #4
0
def set_subpixel_order(direction):
    '''
    Sets the text subpixel anti-alias order.

    :param tps.Direction direction: New direction
    :returns: None
    '''
    if tps.has_program('xfconf-query'):
        try:
            tps.check_call([
                'xfconf-query', '-c', 'xsettings', '-p', '/Xft/RGBA', '-s',
                direction.subpixel
            ], logger)
        except subprocess.CalledProcessError as e:
            logger.error(e)

    elif tps.has_program('gsettings'):
        try:
            schemas = tps.check_output(['gsettings', 'list-schemas'],
                                       logger).decode().split('\n')
            schema = 'org.gnome.settings-daemon.plugins.xsettings'
            if schema in schemas:
                tps.check_call([
                    'gsettings', 'set', schema, 'rgba-order',
                    direction.subpixel
                ], logger)
            else:
                logger.warning('gsettings is installed, but the "{}" schema '
                               'is not available'.format(schema))
        except subprocess.CalledProcessError as e:
            logger.error(e)
    else:
        logger.warning('neither xfconf-query nor gsettings is installed')
コード例 #5
0
def get_resolution_and_shift(output):
    '''
    Retrieves the total resolution of the virtual screen and the position of
    the given output within that.

    The X server seems to generate a huge screen which is then displayed by the
    physical displays. ``xrandr`` gives the size of that (virtual) screen as
    well as the positions of each display in that.

    For example, I currently have the 12.5" 1366×768 ThinkPad X220 display on
    the right of a 23" 1920×1080 pixel display. ``xrandr`` tells me the
    following::

        Screen 0: … current 3286 x 1080 …
        LVDS1 … 1366x768+1920+0
        DP2 … 1920x1080+0+0

    This only shows the interesting parts. The size of the (virtual) screen is
    3286×1080 and the position of the internal screen is 1366×768+1920+0. This
    allows to compute the transformation matrix for this.
    '''
    xrandr_output = tps.check_output(['xrandr', '-q'], logger).strip().decode()
    lines = xrandr_output.split('\n')

    pattern_output = re.compile(
        r'''
                                {}
                                \D+
                                (?P<width>\d+)
                                x
                                (?P<height>\d+)
                                \+
                                (?P<x>\d+)
                                \+
                                (?P<y>\d+)
                                '''.format(output), re.VERBOSE)
    pattern_screen = re.compile('current (?P<width>\d+) x (?P<height>\d+)')

    result = {}

    for line in lines:
        m_output = pattern_output.search(line)
        if m_output:
            result['output_width'] = int(m_output.group('width'))
            result['output_height'] = int(m_output.group('height'))
            result['output_x'] = int(m_output.group('x'))
            result['output_y'] = int(m_output.group('y'))

        m_screen = pattern_screen.search(line)
        if m_screen:
            result['screen_width'] = int(m_screen.group('width'))
            result['screen_height'] = int(m_screen.group('height'))

    if len(result) != 6:
        raise ScreenNotFoundException(
            'The screen and output dimensions could not be gathered from '
            'xrandr. Maybe the "{}" output is not attached or enabled? Please '
            'report a bug otherwise.'.format(output))

    return result
コード例 #6
0
def can_use_chvt():
    '''
    Checks whether ``chvt`` can be called with ``sudo`` without a password.

    The ``sudo`` command has the ``-n`` option which will just make the command
    fail when the user does not have the appropriate permissions. The problem
    with ``chvt`` is that it does not have any intelligent command line
    argument parsing. If will return code 1 if no argument is given, the same
    code that ``sudo`` gives when no permission is available. Therefore I chose
    to use ``sudo -l` to get the whole list and see whether the full path to
    ``chvt`` is in there. This might break on Fedora where the ``usr``-merge
    has been done now.

    The following line is needed in a file like ``/etc/sudoers.d/chvt``::

        myuser  ALL = NOPASSWD: /bin/chvt

    You have to replace ``myuser`` which your username. Giving too broad
    permissions to every other user account is probably not a good idea.

    :rtype: bool
    '''
    command = ['sudo', '-l']
    output = tps.check_output(command, logger)

    return b'/bin/chvt' in output
コード例 #7
0
ファイル: network.py プロジェクト: wjkennedy/thinkpad-scripts
def get_ethernet_con_name():
    '''
    Gets the lexicographically first ethernet connection name from nmcli.

    :returns: str
    :raises tps.network.MissingEthernetException:
    '''
    if not tps.has_program('nmcli'):
        logger.warning('nmcli is not installed')
        return

    if get_nmcli_version() >= (0, 9, 10):
        command = ['nmcli', '--terse', '--fields', 'NAME,TYPE', 'con', 'show']
    else:
        command = ['nmcli', '--terse', '--fields', 'NAME,TYPE', 'con', 'list']
    lines = tps.check_output(command, logger).decode()
    ethernet_cons = []
    for line in lines.split('\n'):
        if line.strip():
            name, type = parse_terse_line(line)
            if 'ethernet' in type.lower():
                ethernet_cons.append(name)
    if ethernet_cons:
        return sorted(ethernet_cons)[0]
    else:
        raise MissingEthernetException('No configured Ethernet connections.')
コード例 #8
0
ファイル: network.py プロジェクト: dmgerman/thinkpad-scripts
def get_ethernet_con_name():
    '''
    Gets the lexicographically first ethernet connection name from nmcli.

    :returns: str
    :raises tps.network.MissingEthernetException:
    '''
    if not tps.has_program('nmcli'):
        logger.warning('nmcli is not installed')
        return

    if get_nmcli_version() >= (0, 9, 10):
        command = ['nmcli', '--terse', '--fields', 'NAME,TYPE', 'con', 'show']
    else:
        command = ['nmcli', '--terse', '--fields', 'NAME,TYPE', 'con', 'list']
    lines = tps.check_output(command, logger).decode()
    ethernet_cons = []
    for line in lines.split('\n'):
        if line.strip():
            name, type = parse_terse_line(line)
            if 'ethernet' in type.lower():
                ethernet_cons.append(name)
    if ethernet_cons:
        return sorted(ethernet_cons)[0]
    else:
        raise MissingEthernetException('No configured Ethernet connections.')
コード例 #9
0
def get_wacom_device_ids():
    '''
    Gets the IDs of the built-in Wacom touch devices.

    This calls ``xinput`` to get the list and parses that with a regular
    expression. Only device names starting with ``Wacom ISD`` (default regex)
    are taken into account. If you have an external device, this will not be
    picked up.

    :rtype: list
    '''
    config = tps.config.get_config()

    regex = config['touch']['regex']
    logger.debug('Using “%s” as regex to find Wacom devices.', regex)
    pattern = re.compile(regex.encode())
    output = tps.check_output(['xinput'], logger)
    lines = output.split(b'\n')
    ids = []
    for line in lines:
        matcher = pattern.search(line)
        if matcher:
            ids.append(int(matcher.group(1)))

    return ids
コード例 #10
0
ファイル: dock.py プロジェクト: jturner314/thinkpad-scripts
def _is_docked_lsusb(regex):
    '''
    Queries ``lsusb`` and checks whether the devices are present.
    '''
    output = tps.check_output(['lsusb'], logger).decode().strip()
    match = re.search(regex, output)
    return bool(match)
コード例 #11
0
def _is_docked_lsusb(regex):
    '''
    Queries ``lsusb`` and checks whether the devices are present.
    '''
    output = tps.check_output(['lsusb'], logger).decode().strip()
    match = re.search(regex, output)
    return bool(match)
コード例 #12
0
def get_wacom_device_ids():
    '''
    Gets the IDs of the built-in Wacom touch devices.

    This calls ``xinput`` to get the list and parses that with a regular
    expression. Only device names starting with ``Wacom ISD`` (default regex)
    are taken into account. If you have an external device, this will not be
    picked up.

    :rtype: list
    '''
    config = tps.config.get_config()

    regex = config['touch']['regex']
    logger.debug('Using “%s” as regex to find Wacom devices.', regex)
    pattern = re.compile(regex.encode())
    output = tps.check_output(['xinput'], logger)
    lines = output.split(b'\n')
    ids = []
    for line in lines:
        matcher = pattern.search(line)
        if matcher:
            ids.append(int(matcher.group(1)))

    return ids
コード例 #13
0
ファイル: screen.py プロジェクト: jturner314/thinkpad-scripts
def set_subpixel_order(direction):
    '''
    Sets the text subpixel anti-alias order.

    :param tps.Direction direction: New direction
    :returns: None
    '''
    if tps.has_program('xfconf-query'):
        try:
            tps.check_call(['xfconf-query', '-c', 'xsettings', '-p',
                            '/Xft/RGBA', '-s', direction.subpixel], logger)
        except subprocess.CalledProcessError as e:
            logger.error(e)

    elif tps.has_program('gsettings'):
        try:
            schemas = tps.check_output(
                ['gsettings', 'list-schemas'], logger).decode().split('\n')
            schema = 'org.gnome.settings-daemon.plugins.xsettings'
            if schema in schemas:
                tps.check_call(['gsettings', 'set', schema, 'rgba-order',
                                direction.subpixel], logger)
            else:
                logger.warning('gsettings is installed, but the "{}" schema '
                               'is not available'.format(schema))
        except subprocess.CalledProcessError as e:
            logger.error(e)
    else:
        logger.warning('neither xfconf-query nor gsettings is installed')
コード例 #14
0
ファイル: screen.py プロジェクト: jturner314/thinkpad-scripts
def get_resolution_and_shift(output):
    '''
    Retrieves the total resolution of the virtual screen and the position of
    the given output within that.

    The X server seems to generate a huge screen which is then displayed by the
    physical displays. ``xrandr`` gives the size of that (virtual) screen as
    well as the positions of each display in that.

    For example, I currently have the 12.5" 1366×768 ThinkPad X220 display on
    the right of a 23" 1920×1080 pixel display. ``xrandr`` tells me the
    following::

        Screen 0: … current 3286 x 1080 …
        LVDS1 … 1366x768+1920+0
        DP2 … 1920x1080+0+0

    This only shows the interesting parts. The size of the (virtual) screen is
    3286×1080 and the position of the internal screen is 1366×768+1920+0. This
    allows to compute the transformation matrix for this.
    '''
    xrandr_output = tps.check_output(['xrandr', '-q'], logger).strip().decode()
    lines = xrandr_output.split('\n')

    pattern_output = re.compile(r'''
                                {}
                                \D+
                                (?P<width>\d+)
                                x
                                (?P<height>\d+)
                                \+
                                (?P<x>\d+)
                                \+
                                (?P<y>\d+)
                                '''.format(output), re.VERBOSE)
    pattern_screen = re.compile('current (?P<width>\d+) x (?P<height>\d+)')

    result = {}

    for line in lines:
        m_output = pattern_output.search(line)
        if m_output:
            result['output_width'] = int(m_output.group('width'))
            result['output_height'] = int(m_output.group('height'))
            result['output_x'] = int(m_output.group('x'))
            result['output_y'] = int(m_output.group('y'))

        m_screen = pattern_screen.search(line)
        if m_screen:
            result['screen_width'] = int(m_screen.group('width'))
            result['screen_height'] = int(m_screen.group('height'))

    if len(result) != 6:
        raise ScreenNotFoundException(
            'The screen and output dimensions could not be gathered from '
            'xrandr. Maybe the "{}" output is not attached or enabled? Please '
            'report a bug otherwise.'.format(output))

    return result
コード例 #15
0
ファイル: hooks.py プロジェクト: hughker/thinkpad-scripts
def get_graphicsl_user():
    pattern = re.compile(r'\(:0(\.0)?\)')

    lines = tps.check_output(['who', '-u'], logger).decode().split('\n')
    for line in lines:
        m = pattern.search(line)
        if m:
            words = line.split()
            return words[0]
コード例 #16
0
def get_graphicsl_user():
    pattern = re.compile(r'\(:0(\.0)?\)')

    lines = tps.check_output(['who', '-u'], logger).decode().split('\n')
    for line in lines:
        m = pattern.search(line)
        if m:
            words = line.split()
            return words[0]
コード例 #17
0
def has_device_property(device, property_):
    '''
    Checks whether a given device supports a property.
    '''
    command = ['xinput', '--list-props', str(device)]
    output = tps.check_output(command, logger).decode()
    regex = r'^\s+({})\s+\(\d+\):'.format(re.escape(property_))
    has_property = re.search(regex, output, re.MULTILINE) is not None
    logger.debug('Device %i %s property “%s”', device,
                 'has' if has_property else 'does not have', property_)
    return has_property
コード例 #18
0
def get_xinput_state(device):
    '''
    Gets the device state.

    :param device: ``xinput`` ID of devicwe
    :type device: int
    :returns: Whether device is enabled
    :rtype: bool
    '''
    output = tps.check_output(['xinput', '--list', str(device)], logger)
    return b'disabled' not in output
コード例 #19
0
def get_xinput_state(device):
    """
    Gets the device state.

    :param device: ``xinput`` ID of devicwe
    :type device: int
    :returns: Whether device is enabled
    :rtype: bool
    """
    output = tps.check_output(["xinput", "--list", str(device)], logger)
    return b"disabled" not in output
コード例 #20
0
def get_xinput_state(device):
    '''
    Gets the device state.

    :param device: ``xinput`` ID of devicwe
    :type device: int
    :returns: Whether device is enabled
    :rtype: bool
    '''
    output = tps.check_output(['xinput', '--list', str(device)], logger)
    return b'disabled' not in output
コード例 #21
0
def has_device_property(device, property_):
    '''
    Checks whether a given device supports a property.
    '''
    command = ['xinput', '--list-props', str(device)]
    output = tps.check_output(command, logger).decode()
    regex = r'^\s+({})\s+\(\d+\):'.format(re.escape(property_))
    has_property = re.search(regex, output, re.MULTILINE) is not None
    logger.debug('Device %i %s property “%s”', device,
                 'has' if has_property else 'does not have', property_)
    return has_property
コード例 #22
0
ファイル: sound.py プロジェクト: hughker/thinkpad-scripts
def get_pulseaudio_sinks():
    '''
    Retrieves the available PulseAudio sinks on the current system
    and returns them in a set of strings

    :returns: List of sinks. If ``pactl`` is not installed, an empty list is
    returned instead.
    :rtype: list of str
    '''
    if not tps.has_program('pactl'):
        logger.warning('pactl is not installed')
        return []

    output = tps.check_output(['pactl', 'list', 'sinks'], logger).decode()
    sinks = re.findall('^Sink #(\d+)$', output, flags=re.MULTILINE)
    return sinks
コード例 #23
0
def get_xinput_id(name):
    """
    Gets the ``xinput`` ID for given device.

    The first parts of the name may be omitted. To get “TPPS/2 IBM TrackPoint”,
    it is sufficient to use “TrackPoint”.

    :raises InputDeviceNotFoundException: Device not found in ``xinput`` output
    :rtype: int
    """
    output = tps.check_output(["xinput", "list"], logger).decode()
    matcher = re.search(name + r"\s*id=(\d+)", output)
    if matcher:
        return int(matcher.group(1))

    raise InputDeviceNotFoundException("Input device “{}” could not be found".format(name))
コード例 #24
0
ファイル: network.py プロジェクト: dmgerman/thinkpad-scripts
def get_nmcli_version():
    '''
    Gets the version of nmcli, removing trailing zeroes.

    :returns: tuple, e.g. (0, 9, 10) for version 0.9.10.0
    '''
    if not tps.has_program('nmcli'):
        logger.warning('nmcli is not installed')
        return

    response = tps.check_output(['nmcli', '--version'], logger).decode()
    version_str = re.search(r'\d+(\.\d+)*', response).group(0)
    version_list = [int(n) for n in version_str.split('.')]
    while version_list[-1] == 0:
        version_list.pop()
    return tuple(version_list)
コード例 #25
0
def get_pulseaudio_sinks():
    '''
    Retrieves the available PulseAudio sinks on the current system
    and returns them in a set of strings

    :returns: List of sinks. If ``pactl`` is not installed, an empty list is
    returned instead.
    :rtype: list of str
    '''
    if not tps.has_program('pactl'):
        logger.warning('pactl is not installed')
        return []

    output = tps.check_output(['pactl', 'list', 'sinks'], logger).decode()
    sinks = re.findall('^Sink #(\d+)$', output, flags=re.MULTILINE)
    return sinks
コード例 #26
0
ファイル: network.py プロジェクト: wjkennedy/thinkpad-scripts
def get_nmcli_version():
    '''
    Gets the version of nmcli, removing trailing zeroes.

    :returns: tuple, e.g. (0, 9, 10) for version 0.9.10.0
    '''
    if not tps.has_program('nmcli'):
        logger.warning('nmcli is not installed')
        return

    response = tps.check_output(['nmcli', '--version'], logger).decode()
    version_str = re.search(r'\d+(\.\d+)*', response).group(0)
    version_list = [int(n) for n in version_str.split('.')]
    while version_list[-1] == 0:
        version_list.pop()
    return tuple(version_list)
コード例 #27
0
def get_xinput_id(name):
    '''
    Gets the ``xinput`` ID for given device.

    The first parts of the name may be omitted. To get “TPPS/2 IBM TrackPoint”,
    it is sufficient to use “TrackPoint”.

    :raises InputDeviceNotFoundException: Device not found in ``xinput`` output
    :rtype: int
    '''
    output = tps.check_output(['xinput', 'list'], logger).decode()
    matcher = re.search(name + r'\s*id=(\d+)', output)
    if matcher:
        return int(matcher.group(1))

    raise InputDeviceNotFoundException(
        'Input device “{}” could not be found'.format(name))
コード例 #28
0
ファイル: screen.py プロジェクト: jturner314/thinkpad-scripts
def get_externals(internal):
    '''
    Gets the external screens.

    You have to specify the internal screen to exclude that from the listing.

    ;param str internal: Name of the internal screen
    :returns: List of external screen names
    :rtype: str
    '''
    externals = []
    lines = tps.check_output(['xrandr'], logger).decode().split('\n')
    for line in lines:
        if not line.startswith(internal):
            matcher = re.search(r'^(\S+) connected', line)
            if matcher:
                externals.append(matcher.group(1))
    return externals
コード例 #29
0
def get_externals(internal):
    '''
    Gets the external screens.

    You have to specify the internal screen to exclude that from the listing.

    ;param str internal: Name of the internal screen
    :returns: List of external screen names
    :rtype: str
    '''
    externals = []
    lines = tps.check_output(['xrandr'], logger).decode().split('\n')
    for line in lines:
        if not line.startswith(internal):
            matcher = re.search(r'^(\S+) connected', line)
            if matcher:
                externals.append(matcher.group(1))
    return externals
コード例 #30
0
def get_internal(config, cache=True):
    '''
    Matches the regular expression in the config and retrieves the actual name
    of the internal screen.

    The names of the outputs that XRandR reports may be ``LVDS1`` or
    ``LVDS-1``. The former happens with the Intel driver, the latter with the
    generic kernel modesetting driver. We do not know what the system will
    provide, therefore it was decided in GH-125 to use a regular expression in
    the configuration file. This also gives out-of-the-box support for Yoga
    users where the internal screen is called ``eDP1`` or ``eDP-1``.

    :param config: Configuration parser instance
    :param bool cache: Compute the value again even if it is cached
    '''

    if cache and get_internal.cached_internal is not None:
        return get_internal.cached_internal

    if 'internal' in config['screen']:
        # The user has this key in his configuration. The default does not have
        # it any more, so this must be manual. The user could have specified
        # that by hand, it is perhaps not really what is wanted.
        logger.warning(
            'You have specified the screen.internal option in your configuration file. Since version 4.8.0 this option is not used by default but screen.internal_regex (valued `%s`) is used instead. Please take a look at the new default regular expression and see whether that covers your use case already. In that case you can delete the entry from your own configuration file. This program will use your value and not try to match the regular expression.',
            config['screen']['internal_regex'])
        internal = config['screen']['internal']
    else:
        # There is no such option, therefore we need to match the regular
        # expression against the output of XRandR now.
        output = tps.check_output(['xrandr'], logger).decode().strip()
        screens = get_available_screens(output)
        logger.debug('Screens available on this system are %s.',
                     ', '.join(screens))
        internal = filter_outputs(screens, config['screen']['internal_regex'])
        logger.debug('Internal screen is determined to be %s.', internal)

    get_internal.cached_internal = internal

    return internal
コード例 #31
0
ファイル: screen.py プロジェクト: jturner314/thinkpad-scripts
def get_rotation(screen):
    '''
    Gets the current rotation of the given screen.

    :param str screen: Find rotation of given output
    :returns: Current direction
    :rtype: tps.Direction
    '''
    output = tps.check_output(['xrandr', '-q', '--verbose'], logger).decode()
    lines = output.split('\n')
    for line in lines:
        if screen in line:
            matcher = re.search(r'\) (normal|left|inverted|right) \(', line)
            if matcher:
                rotation = tps.translate_direction(matcher.group(1))
                logger.info('Current rotation is “{}”.'.format(rotation))
                return rotation
    else:
        raise ScreenNotFoundException(
            'Screen "{}" is not enabled. Do you have a screen like that in '
            'the output of "xrandr", and is it enabled? Maybe you have to '
            'adjust the option of screen.internal in the '
            'configuration.'.format(screen))
コード例 #32
0
def get_rotation(screen):
    '''
    Gets the current rotation of the given screen.

    :param str screen: Find rotation of given output
    :returns: Current direction
    :rtype: tps.Direction
    '''
    output = tps.check_output(['xrandr', '-q', '--verbose'], logger).decode()
    lines = output.split('\n')
    for line in lines:
        if screen in line:
            matcher = re.search(r'\) (normal|left|inverted|right) \(', line)
            if matcher:
                rotation = tps.translate_direction(matcher.group(1))
                logger.info('Current rotation is “{}”.'.format(rotation))
                return rotation
    else:
        raise ScreenNotFoundException(
            'Screen "{}" is not enabled. Do you have a screen like that in '
            'the output of "xrandr", and is it enabled? Maybe you have to '
            'adjust the option of screen.internal in the '
            'configuration.'.format(screen))
コード例 #33
0
ファイル: screen.py プロジェクト: jturner314/thinkpad-scripts
def get_internal(config, cache=True):
    '''
    Matches the regular expression in the config and retrieves the actual name
    of the internal screen.

    The names of the outputs that XRandR reports may be ``LVDS1`` or
    ``LVDS-1``. The former happens with the Intel driver, the latter with the
    generic kernel modesetting driver. We do not know what the system will
    provide, therefore it was decided in GH-125 to use a regular expression in
    the configuration file. This also gives out-of-the-box support for Yoga
    users where the internal screen is called ``eDP1`` or ``eDP-1``.

    :param config: Configuration parser instance
    :param bool cache: Compute the value again even if it is cached
    '''

    if cache and get_internal.cached_internal is not None:
        return get_internal.cached_internal

    if 'internal' in config['screen']:
        # The user has this key in his configuration. The default does not have
        # it any more, so this must be manual. The user could have specified
        # that by hand, it is perhaps not really what is wanted.
        logger.warning('You have specified the screen.internal option in your configuration file. Since version 4.8.0 this option is not used by default but screen.internal_regex (valued `%s`) is used instead. Please take a look at the new default regular expression and see whether that covers your use case already. In that case you can delete the entry from your own configuration file. This program will use your value and not try to match the regular expression.', config['screen']['internal_regex'])
        internal = config['screen']['internal']
    else:
        # There is no such option, therefore we need to match the regular
        # expression against the output of XRandR now.
        output = tps.check_output(['xrandr'], logger).decode().strip()
        screens = get_available_screens(output)
        logger.debug('Screens available on this system are %s.', ', '.join(screens))
        internal = filter_outputs(screens, config['screen']['internal_regex'])
        logger.debug('Internal screen is determined to be %s.', internal)

    get_internal.cached_internal = internal

    return internal
コード例 #34
0
def has_xinput_prop(device, prop):
    """
    Checks whether the device has the given xinput propery.
    """
    output = tps.check_output(["xinput", "list-props", str(device)], logger)
    return prop in output
コード例 #35
0
def has_xinput_prop(device, prop):
    '''
    Checks whether the device has the given xinput propery.
    '''
    output = tps.check_output(['xinput', 'list-props', str(device)], logger)
    return prop in output
コード例 #36
0
def has_xinput_prop(device, prop):
    '''
    Checks whether the device has the given xinput propery.
    '''
    output = tps.check_output(['xinput', 'list-props', str(device)], logger)
    return prop in output
コード例 #37
0
def get_graphicsl_user():
    lines = tps.check_output(['who', '-u'], logger)\
               .decode().strip().split('\n')
    return parse_graphical_user(lines)