Logo Search packages:      
Sourcecode: ibus version File versions

register.py

# vim:set et sts=4 sw=4:
#
# ibus - The Input Bus
#
# Copyright (c) 2007-2008 Huang Peng <shawn.p.huang@gmail.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library 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 Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
# Boston, MA  02111-1307  USA

import os
from os import path
import signal
import glob
import ibus
import locale

locale.setlocale(locale.LC_ALL, "")

LANG = tuple()
try:
    LANG = locale.getlocale()[0], locale.getlocale()[0].split("_")[0]
except:
    pass

IBUS_DATAROOTDIR = os.getenv("IBUS_DATAROOTDIR")

class Engine(ibus.Object):
    def __init__(self, name, local_name, lang = "other", icon = "", author = "", credits = "", _exec = "", pid = 0):
        super(Engine, self).__init__()
        self.name = name
        self.local_name = local_name
        self.lang = lang
        self.icon = icon
        self.author = author
        self.credits = credits
        self._exec = _exec
        self.pid = pid

    def start(self):
        if self.pid != 0:
            return
        pid = os.fork()
        if pid > 0: # parent
            self.pid = pid
        elif pid == 0: # child
            os.setpgrp()
            args = self._exec.split()
            os.execv(args[0], args)
            sys.exit(1)

    def stop(self, force = False):
        if self.pid == 0:
            return
        try:
            if force:
                os.kill(-self.pid, signal.SIGKILL)
            else:
                os.kill(-self.pid, signal.SIGTERM)
        except:
            pass

    def engine_exit(self, pid):
        if self.pid == pid:
            self.pid = 0
            return True
        return False

    def __eq__(self, o):
        # We don't test icon author & credits
        return self.name == o.name and \
            self.lang == o.lang and \
            self._exec == o._exec

    def __str__(self):
        return "Engine('%s', '%s', '%s', '%s', '%s', '%s', '%s', %d" % (self.name, self.local_name, self.lang, \
            self.icon, self.author, \
            self.credits, self._exec, \
            self.pid)

class Register(ibus.Object):
    def __init__(self):
        super(Register, self).__init__()
        self.__engines = dict()
        self.__load()
        signal.signal(signal.SIGCHLD, self.__sigchld_cb)

    def start_engine(self, lang, name):
        key = (lang, name)
        if key not in self.__engines:
            raise ibus.IBusException("Can not find engine(%s, %s)" % (lang, name))

        engine = self.__engines[(lang, name)]
        engine.start()

    def stop_engine(self, lang, name):
        key = (lang, name)
        if key not in self.__engines:
            raise ibus.IBusException("Can not find engine(%s, %s)" % (lang, name))

        engine = self.__engines[(lang, name)]
        engine.stop()

    def restart_engine(self, lang, name):
        key = (lang, name)
        if key not in self.__engines:
            raise ibus.IBusException("Can not find engine (%s, %s)" % (lang, name))

        engine = self.__engines[(lang, name)]
        engine.stop()
        engine.start()

    def list_engines(self):
        engines = []
        for key, e in self.__engines.items():
            engines.append((e.name, e.local_name, e.lang, e.icon, e.author, e.credits, e._exec, e.pid != 0))
        return engines

    def reload_engines(self):
        self.__load()

    def __sigchld_cb(self, sig, f):
        pid, state = os.wait()
        for key, engine in self.__engines.items():
            if engine.engine_exit(pid):
                break

    def __load(self):
        _dir = path.join(IBUS_DATAROOTDIR, "ibus/engine")
        for _file in glob.glob(_dir + "/*.engine"):
            engine = self.__load_engine(_file)
            if (engine.lang, engine.name) in self.__engines:
                old_engine = self.__engines[(engine.lang, engine.name)]
                if old_engine == engine:
                    engine.pid = old_engine.pid
                    self.__engines[(engine.lang, engine.name)] = engine
                else:
                    self.__engines[(engine.lang, engine.name + " (old)")] = old_engine
                    self.__engines[(engine.lang, engine.name)] = engine
            else:
                self.__engines[(engine.lang, engine.name)] = engine



    def __load_engine(self, _file):
        f = file(_file)
        name = None
        local_name = None
        lang = "other"
        icon = ""
        author = ""
        credits = ""
        _exec = None
        line = 0
        for l in f:
            line += 1
            l = l.strip()
            if l.startswith("#"):
                continue
            n, v = l.split("=")
            if n == "Name":
                name = v
                if local_name == None:
                    local_name = name
            elif n.startswith("Name."):
                if n[5:] in LANG:
                    local_name = v
            elif n == "Lang":
                lang = v
            elif n == "Icon":
                icon = v
            elif n == "Author":
                author = v
            elif n == "Credits":
                credits = v
            elif n == "Exec":
                _exec = v
            else:
                raise Exception("%s:%d\nUnknown value name = %s" % (_file, line, n))

        if name == None:
            raise Exception("%s: no name" % _file)
        if _exec == None:
            raise Exception("%s: no exec" % _file)

        return Engine(name, local_name, lang, icon, author, credits, _exec)

if __name__ == "__main__":
    import time
    reg = Register()
    reg.start_engine("zh", "py")
    time.sleep(3)
    reg.stop_engine("zh", "py")


Generated by  Doxygen 1.6.0   Back to index