~doanac/autopilot/autopilot-touch-depend

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
#
# Autopilot Functional Test Tool
# Copyright (C) 2012-2013 Canonical
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#


"""Functions to deal with ibus service."""

from __future__ import absolute_import

from gi.repository import IBus, GLib
import os
import logging
import subprocess
from gi.repository import GConf


logger = logging.getLogger(__name__)


def get_ibus_bus():
    """Get the ibus bus object, possibly starting the ibus daemon if it's
    not already running.

    :raises: **RuntimeError** in the case of ibus-daemon being unavailable.

    """
    bus = IBus.Bus()
    if bus.is_connected():
        return bus

    main_loop = GLib.MainLoop()

    timeout = 5
    GLib.timeout_add_seconds(timeout, lambda *args: main_loop.quit())
    bus.connect("connected", lambda *args: main_loop.quit())

    os.spawnlp(os.P_NOWAIT, "ibus-daemon", "ibus-daemon", "--xim")

    main_loop.run()

    if not bus.is_connected():
        raise RuntimeError(
            "Could not start ibus-daemon after %d seconds." % (timeout))
    return bus


def get_available_input_engines():
    """Get a list of available input engines."""
    bus = get_ibus_bus()
    return [e.get_name() for e in bus.list_engines()]


def get_active_input_engines():
    """Get the list of input engines that have been activated."""
    bus = get_ibus_bus()
    return [e.get_name() for e in bus.list_active_engines()]


def set_active_engines(engine_list):
    """Installs the engines in *engine_list* into the list of active iBus
    engines.

    The specified engines must appear in the return list from
    get_available_input_engines().

    .. note:: This function removes all other engines.

    This function returns the list of engines installed before this function
    was called. The caller should pass this list to set_active_engines to
    restore ibus to it's old state once the test has finished.

    :param engine_list: List of engine names
    :type engine_list: List of strings
    :raises: **TypeError** on invalid *engine_list* parameter.
    :raises: **ValueError** when engine_list contains invalid engine name.

    """
    if type(engine_list) is not list:
        raise TypeError("engine_list must be a list of valid engine names.")
    available_engines = get_available_input_engines()
    for engine in engine_list:
        if not isinstance(engine, basestring):
            raise TypeError("Engines in engine_list must all be strings.")
        if engine not in available_engines:
            raise ValueError(
                "engine_list contains invalid engine name: '%s'", engine)

    bus = get_ibus_bus()
    config = bus.get_config()

    config.set_value("general",
                     "preload_engine_mode",
                     GLib.Variant.new_int32(IBus.PreloadEngineMode.USER))

    old_engines = get_active_input_engines()
    config.set_value(
        "general", "preload_engines", GLib.Variant("as", engine_list))

    return old_engines


def set_gconf_option(path, value):
    """Set the gconf setting on `path` to the defined `value`"""
    _set_gconf_list(path, value)


def get_gconf_option(path):
    """Get the gconf setting on `path`"""
    client = GConf.Client.get_default()
    value = client.get(path)
    return _get_native_gconf_value(value)


def _set_gconf_list(path, values):
    gconf_value = '[%s]' % ','.join(values)
    subprocess.check_output(
        ["gconftool-2", "--set", "--type=list", "--list-type=string", path,
         gconf_value])


def _get_native_gconf_value(value):
    """Translates a GConfValue to a native one"""
    if value.type is GConf.ValueType.STRING:
        return value.get_string()
    elif value.type is GConf.ValueType.INT:
        return value.get_int()
    elif value.type is GConf.ValueType.FLOAT:
        return value.get_float()
    elif value.type is GConf.ValueType.BOOL:
        return value.get_bool()
    elif value.type is GConf.ValueType.LIST:
        return [_get_native_gconf_value(val) for val in value.get_list()]
    else:
        raise TypeError("Invalid gconf value type")