Example #1
0
File: common.py Project: kivy/kivy
    def setUp(self):
        '''Prepare the graphic test, with:
            - Window size fixed to 320x240
            - Default kivy configuration
            - Without any kivy input
        '''

        # use default kivy configuration (don't load user file.)
        from os import environ
        environ['KIVY_USE_DEFAULTCONFIG'] = '1'

        # force window size + remove all inputs
        from kivy.config import Config
        Config.set('graphics', 'width', '320')
        Config.set('graphics', 'height', '240')
        for items in Config.items('input'):
            Config.remove_option('input', items[0])

        # bind ourself for the later screenshot
        from kivy.core.window import Window
        self.Window = Window
        Window.bind(on_flip=self.on_window_flip)

        # ensure our window is correctly created
        Window.create_window()
        Window.register()
        Window.initialized = True
        Window.canvas.clear()
        Window.close = lambda *s: True
Example #2
0
    def run(self):
        q = self._queue.appendleft
        url = self.url
        req_body = self.req_body
        req_headers = self.req_headers or {}
        if (Config.has_section('network')
                and 'useragent' in Config.items('network')):
            useragent = Config.get('network', 'useragent')
            req_headers.setdefault('User-Agent', useragent)

        try:
            result, resp = self._fetch_url(url, req_body, req_headers, q)
            if self.decode:
                result = self.decode_result(result, resp)
        except Exception as e:
            q(('error', None, e))
        else:
            if not self._cancel_event.is_set():
                q(('success', resp, result))
            else:
                q(('killed', None, None))

        # using trigger can result in a missed on_success event
        self._trigger_result()

        # clean ourself when the queue is empty
        while len(self._queue):
            sleep(.1)
            self._trigger_result()

        # ok, authorize the GC to clean us.
        if self in g_requests:
            g_requests.remove(self)
Example #3
0
    def run(self):
        q = self._queue.appendleft
        url = self.url
        req_body = self.req_body
        req_headers = self.req_headers or {}
        if (
            Config.has_section('network')
            and 'useragent' in Config.items('network')
        ):
            useragent = Config.get('network', 'useragent')
            req_headers.setdefault('User-Agent', useragent)

        try:
            result, resp = self._fetch_url(url, req_body, req_headers, q)
            if self.decode:
                result = self.decode_result(result, resp)
        except Exception as e:
            q(('error', None, e))
        else:
            q(('success', resp, result))

        # using trigger can result in a missed on_success event
        self._trigger_result()

        # clean ourself when the queue is empty
        while len(self._queue):
            sleep(.1)
            self._trigger_result()

        # ok, authorize the GC to clean us.
        if self in g_requests:
            g_requests.remove(self)
Example #4
0
    def setUp(self):
        '''Prepare the graphic test, with:
            - Window size fixed to 320x240
            - Default kivy configuration
            - Without any kivy input
        '''

        # use default kivy configuration (don't load user file.)
        from os import environ
        environ['KIVY_USE_DEFAULTCONFIG'] = '1'

        # force window size + remove all inputs
        from kivy.config import Config
        Config.set('graphics', 'width', '320')
        Config.set('graphics', 'height', '240')
        for items in Config.items('input'):
            Config.remove_option('input', items[0])

        # bind ourself for the later screenshot
        from kivy.core.window import Window
        self.Window = Window
        Window.bind(on_flip=self.on_window_flip)

        # ensure our window is correctly created
        Window.create_window()
        Window.register()
        Window.initialized = True
        Window.canvas.clear()
        Window.close = lambda *s: True
Example #5
0
 def configure(self):
     """(internal) Configure all the modules before using them.
     """
     modules_to_configure = [x[0] for x in Config.items("modules")]
     for name in modules_to_configure:
         if name not in self.mods:
             Logger.warning("Modules: Module <%s> not found" % name)
             continue
         self._configure_module(name)
Example #6
0
 def configure(self):
     '''(internal) Configure all the modules before using it.
     '''
     modules_to_configure = map(lambda x: x[0], Config.items('modules'))
     for name in modules_to_configure:
         if name not in self.mods:
             Logger.warning('Modules: Module <%s> not found' % name)
             continue
         self._configure_module(name)
 def configure(self):
     '''(internal) Configure all the modules before using them.
     '''
     modules_to_configure = [x[0] for x in Config.items('modules')]
     for name in modules_to_configure:
         if name not in self.mods:
             Logger.warning('Modules: Module <%s> not found' % name)
             continue
         self._configure_module(name)
Example #8
0
 def update(self):
     '''Update status of module for each windows'''
     modules_to_activate = map(lambda x: x[0], Config.items('modules'))
     for win in self.wins:
         for name in self.mods:
             if not name in modules_to_activate:
                 self.deactivate_module(name, win)
         for name in modules_to_activate:
             self.activate_module(name, win)
Example #9
0
 def configure(self):
     '''(internal) Configure all the modules before using it.
     '''
     modules_to_configure = map(lambda x: x[0], Config.items('modules'))
     for name in modules_to_configure:
         if name not in self.mods:
             Logger.warning('Modules: Module <%s> not found' % name)
             continue
         self._configure_module(name)
Example #10
0
 def configure(self):
     '''(internal) Configure all the modules before using them.
     '''
     modules_to_configure = [x[0] for x in Config.items('modules')]
     for name in modules_to_configure:
         if name not in self.mods:
             Logger.warning('Modules: Module <%s> not found' % name)
             continue
         self._configure_module(name)
Example #11
0
 def update(self):
     '''Update status of module for each windows'''
     modules_to_activate = map(lambda x: x[0], Config.items('modules'))
     for win in self.wins:
         for name in self.mods:
             if not name in modules_to_activate:
                 self.deactivate_module(name, win)
         for name in modules_to_activate:
             self.activate_module(name, win)
 def update(self):
     '''Update the status of the module for each window'''
     modules_to_activate = [x[0] for x in Config.items('modules')]
     for win in self.wins:
         for name in self.mods:
             if not name in modules_to_activate:
                 self.deactivate_module(name, win)
         for name in modules_to_activate:
             try:
                 self.activate_module(name, win)
             except:
                 import traceback
                 traceback.print_exc()
                 raise
Example #13
0
 def update(self):
     '''Update status of module for each windows'''
     modules_to_activate = map(lambda x: x[0], Config.items('modules'))
     for win in self.wins:
         for name in self.mods:
             if not name in modules_to_activate:
                 self.deactivate_module(name, win)
         for name in modules_to_activate:
             try:
                 self.activate_module(name, win)
             except:
                 import traceback
                 traceback.print_exc()
                 raise
Example #14
0
 def update(self):
     '''Update status of module for each windows'''
     modules_to_activate = map(lambda x: x[0], Config.items('modules'))
     for win in self.wins:
         for name in self.mods:
             if not name in modules_to_activate:
                 self.deactivate_module(name, win)
         for name in modules_to_activate:
             try:
                 self.activate_module(name, win)
             except:
                 import traceback
                 traceback.print_exc()
                 raise
Example #15
0
 def update(self):
     '''Update the status of the module for each window'''
     modules_to_activate = [x[0] for x in Config.items('modules')]
     for win in self.wins:
         for name in self.mods:
             if not name in modules_to_activate:
                 self.deactivate_module(name, win)
         for name in modules_to_activate:
             try:
                 self.activate_module(name, win)
             except:
                 import traceback
                 traceback.print_exc()
                 raise
Example #16
0
File: base.py Project: sonnyky/kivy
def _runTouchApp_prepare(widget=None, slave=False):
    from kivy.input import MotionEventFactory, kivy_postproc_modules

    # Ok, we got one widget, and we are not in slave mode
    # so, user don't create the window, let's create it for him !
    if widget:
        EventLoop.ensure_window()

    # Instance all configured input
    for key, value in Config.items('input'):
        Logger.debug('Base: Create provider from %s' % (str(value)))

        # split value
        args = str(value).split(',', 1)
        if len(args) == 1:
            args.append('')
        provider_id, args = args
        provider = MotionEventFactory.get(provider_id)
        if provider is None:
            Logger.warning('Base: Unknown <%s> provider' % str(provider_id))
            continue

        # create provider
        p = provider(key, args)
        if p:
            EventLoop.add_input_provider(p, True)

    # add postproc modules
    for mod in list(kivy_postproc_modules.values()):
        EventLoop.add_postproc_module(mod)

    # add main widget
    if widget and EventLoop.window:
        if widget not in EventLoop.window.children:
            EventLoop.window.add_widget(widget)

    # start event loop
    Logger.info('Base: Start application main loop')
    EventLoop.start()

    # remove presplash on the next frame
    if platform == 'android':
        Clock.schedule_once(EventLoop.remove_android_splash)
 def __init__(self):
     super(InputPostprocCalibration, self).__init__()
     self.devices = {}
     self.frame = 0
     if not Config.has_section('postproc:calibration'):
         return
     default_params = {'xoffset': 0, 'yoffset': 0, 'xratio': 1, 'yratio': 1}
     for device_key, params_str in Config.items('postproc:calibration'):
         params = default_params.copy()
         for param in params_str.split(','):
             param = param.strip()
             if not param:
                 continue
             key, value = param.split('=', 1)
             if key not in ('xoffset', 'yoffset', 'xratio', 'yratio'):
                 Logger.error(
                     'Calibration: invalid key provided: {}'.format(key))
             params[key] = float(value)
         self.devices[device_key] = params
Example #18
0
from kivy.uix.screenmanager import ScreenManager, Screen

from kivy.core.window import Window

import data_capture_lessons
import data_lessons

from indic_transliteration import sanscript, xsanscript
from indic_transliteration.sanscript import transliterate
from kivy.utils import platform

Window.softinput_mode = 'below_target'
from kivy.config import Config
if platform != 'android':
    Config.remove_option('input', '%(name)s')
    print(Config.items('input'))


class LessonGroupScreen(Screen):
    container = ObjectProperty(None)
    lesson_list_names = []

    def __init__(self, **kwargs):
        super(LessonGroupScreen, self).__init__(**kwargs)
        Window.bind(on_keyboard=self.on_key)
        Clock.schedule_once(self.add_buttons, 1)

    def on_key(self, window, key, *args):
        if key == 27:  # the esc key
            if self.manager.current == 'lessons':
                return False
Example #19
0
def runTouchApp(widget=None, slave=False):
    '''Static main function that starts the application loop.
    You got some magic things, if you are using argument like this :

    :Parameters:
        `<empty>`
            To make dispatching work, you need at least one
            input listener. If not, application will leave.
            (MTWindow act as an input listener)

        `widget`
            If you pass only a widget, a MTWindow will be created,
            and your widget will be added on the window as the root
            widget.

        `slave`
            No event dispatching are done. This will be your job.

        `widget + slave`
            No event dispatching are done. This will be your job, but
            we are trying to get the window (must be created by you before),
            and add the widget on it. Very usefull for embedding Kivy
            in another toolkit. (like Qt, check kivy-designed)

    '''

    from kivy.input import MotionEventFactory, kivy_postproc_modules

    # Ok, we got one widget, and we are not in slave mode
    # so, user don't create the window, let's create it for him !
    if widget:
        EventLoop.ensure_window()

    # Instance all configured input
    for key, value in Config.items('input'):
        Logger.debug('Base: Create provider from %s' % (str(value)))

        # split value
        args = str(value).split(',', 1)
        if len(args) == 1:
            args.append('')
        provider_id, args = args
        provider = MotionEventFactory.get(provider_id)
        if provider is None:
            Logger.warning('Base: Unknown <%s> provider' % str(provider_id))
            continue

        # create provider
        p = provider(key, args)
        if p:
            EventLoop.add_input_provider(p, True)

    # add postproc modules
    for mod in kivy_postproc_modules.values():
        EventLoop.add_postproc_module(mod)

    # add main widget
    if widget and EventLoop.window:
        if widget not in EventLoop.window.children:
            EventLoop.window.add_widget(widget)

    # start event loop
    Logger.info('Base: Start application main loop')
    EventLoop.start()

    # we are in a slave mode, don't do dispatching.
    if slave:
        return

    # in non-slave mode, they are 2 issues
    #
    # 1. if user created a window, call the mainloop from window.
    #    This is due to glut, it need to be called with
    #    glutMainLoop(). Only FreeGLUT got a gluMainLoopEvent().
    #    So, we are executing the dispatching function inside
    #    a redisplay event.
    #
    # 2. if no window is created, we are dispatching event lopp
    #    ourself (previous behavior.)
    #
    try:
        if EventLoop.window is None:
            _run_mainloop()
        else:
            EventLoop.window.mainloop()
    finally:
        stopTouchApp()
Example #20
0
 def set_kivy_config(self):
     from kivy.config import Config
     Config.set('graphics', 'width', str(self.width))
     Config.set('graphics', 'height', str(self.height))
     for items in Config.items('input'):
         Config.remove_option('input', items[0])
    def _load_urllib(self, filename, kwargs):
        '''(internal) Loading a network file. First download it, save it to a
        temporary file, and pass it to _load_local().'''
        if PY2:
            import urllib2 as urllib_request

            def gettype(info):
                return info.gettype()
        else:
            import urllib.request as urllib_request

            def gettype(info):
                return info.get_content_type()

        proto = filename.split(':', 1)[0]
        if proto == 'smb':
            try:
                # note: it's important to load SMBHandler every time
                # otherwise the data is occasionally not loaded
                from smb.SMBHandler import SMBHandler
            except ImportError:
                Logger.warning(
                    'Loader: can not load PySMB: make sure it is installed')
                return
        import tempfile
        data = fd = _out_osfd = None
        try:
            _out_filename = ''

            if proto == 'smb':
                # read from samba shares
                fd = urllib_request.build_opener(SMBHandler).open(filename)
            else:
                # read from internet
                request = urllib_request.Request(filename)
                if (Config.has_section('network')
                        and 'useragent' in Config.items('network')):
                    useragent = Config.get('network', 'useragent')
                    if useragent:
                        request.add_header('User-Agent', useragent)
                opener = urllib_request.build_opener()
                fd = opener.open(request)

            if '#.' in filename:
                # allow extension override from URL fragment
                suffix = '.' + filename.split('#.')[-1]
            else:
                ctype = gettype(fd.info())
                suffix = mimetypes.guess_extension(ctype)
                suffix = LoaderBase.EXT_ALIAS.get(suffix, suffix)
                if not suffix:
                    # strip query string and split on path
                    parts = filename.split('?')[0].split('/')[1:]
                    while len(parts) > 1 and not parts[0]:
                        # strip out blanks from '//'
                        parts = parts[1:]
                    if len(parts) > 1 and '.' in parts[-1]:
                        # we don't want '.com', '.net', etc. as the extension
                        suffix = '.' + parts[-1].split('.')[-1]
            _out_osfd, _out_filename = tempfile.mkstemp(prefix='kivyloader',
                                                        suffix=suffix)

            idata = fd.read()
            fd.close()
            fd = None

            # write to local filename
            write(_out_osfd, idata)
            close(_out_osfd)
            _out_osfd = None

            # load data
            data = self._load_local(_out_filename, kwargs)

            # FIXME create a clean API for that
            for imdata in data._data:
                imdata.source = filename
        except Exception as ex:
            Logger.exception('Loader: Failed to load image <%s>' % filename)
            # close file when remote file not found or download error
            try:
                if _out_osfd:
                    close(_out_osfd)
            except OSError:
                pass

            # update client
            for c_filename, client in self._client[:]:
                if filename != c_filename:
                    continue
                # got one client to update
                client.image = self.error_image
                client.dispatch('on_error', error=ex)
                self._client.remove((c_filename, client))

            return self.error_image
        finally:
            if fd:
                fd.close()
            if _out_osfd:
                close(_out_osfd)
            if _out_filename != '':
                unlink(_out_filename)

        return data
Example #22
0
import os
import trio

from kivy.config import Config

Config.set('graphics', 'width', '1600')
Config.set('graphics', 'height', '900')
Config.set('modules', 'touchring', '')
for items in Config.items('input'):
    Config.remove_option('input', items[0])

from ceed.main import CeedApp
from kivy.tests.async_common import UnitKivyApp


class CeedTestApp(CeedApp, UnitKivyApp):
    def __init__(self, ini_file, **kwargs):
        self._ini_config_filename = ini_file
        self._data_path = os.path.dirname(ini_file)
        super(CeedTestApp, self).__init__(**kwargs)

    async def async_sleep(self, dt):
        await trio.sleep(dt)

    def check_close(self):
        super(CeedTestApp, self).check_close()
        return True

    def handle_exception(self, msg, exc_info=None, level='error', *largs):
        super(CeedApp, self).handle_exception(msg, exc_info, level, *largs)
Example #23
0
    def _load_urllib(self, filename, kwargs):
        '''(internal) Loading a network file. First download it, save it to a
        temporary file, and pass it to _load_local().'''
        if PY2:
            import urllib2 as urllib_request

            def gettype(info):
                return info.gettype()
        else:
            import urllib.request as urllib_request

            def gettype(info):
                return info.get_content_type()
        proto = filename.split(':', 1)[0]
        if proto == 'smb':
            try:
                # note: it's important to load SMBHandler every time
                # otherwise the data is occasionally not loaded
                from smb.SMBHandler import SMBHandler
            except ImportError:
                Logger.warning(
                    'Loader: can not load PySMB: make sure it is installed')
                return
        import tempfile
        data = fd = _out_osfd = None
        try:
            _out_filename = ''

            if proto == 'smb':
                # read from samba shares
                fd = urllib_request.build_opener(SMBHandler).open(filename)
            else:
                # read from internet
                request = urllib_request.Request(filename)
                if (
                    Config.has_section('network')
                    and 'useragent' in Config.items('network')
                ):
                    useragent = Config.get('network', 'useragent')
                    if useragent:
                        request.add_header('User-Agent', useragent)
                opener = urllib_request.build_opener()
                fd = opener.open(request)

            if '#.' in filename:
                # allow extension override from URL fragment
                suffix = '.' + filename.split('#.')[-1]
            else:
                ctype = gettype(fd.info())
                suffix = mimetypes.guess_extension(ctype)
                if not suffix:
                    # strip query string and split on path
                    parts = filename.split('?')[0].split('/')[1:]
                    while len(parts) > 1 and not parts[0]:
                        # strip out blanks from '//'
                        parts = parts[1:]
                    if len(parts) > 1 and '.' in parts[-1]:
                        # we don't want '.com', '.net', etc. as the extension
                        suffix = '.' + parts[-1].split('.')[-1]
            _out_osfd, _out_filename = tempfile.mkstemp(
                prefix='kivyloader', suffix=suffix)

            idata = fd.read()
            fd.close()
            fd = None

            # write to local filename
            write(_out_osfd, idata)
            close(_out_osfd)
            _out_osfd = None

            # load data
            data = self._load_local(_out_filename, kwargs)

            # FIXME create a clean API for that
            for imdata in data._data:
                imdata.source = filename
        except Exception as ex:
            Logger.exception('Loader: Failed to load image <%s>' % filename)
            # close file when remote file not found or download error
            try:
                if _out_osfd:
                    close(_out_osfd)
            except OSError:
                pass

            # update client
            for c_filename, client in self._client[:]:
                if filename != c_filename:
                    continue
                # got one client to update
                client.image = self.error_image
                client.dispatch('on_error', error=ex)
                self._client.remove((c_filename, client))

            return self.error_image
        finally:
            if fd:
                fd.close()
            if _out_osfd:
                close(_out_osfd)
            if _out_filename != '':
                unlink(_out_filename)

        return data
Example #24
0
async def kivy_app(request, nursery):
    gc.collect()
    if apps:
        last_app, last_request = apps.pop()
        assert last_app() is None, \
            'Memory leak: failed to release app for test ' + repr(last_request)

    from os import environ
    environ['KIVY_USE_DEFAULTCONFIG'] = '1'

    # force window size + remove all inputs
    from kivy.config import Config
    Config.set('graphics', 'width', '320')
    Config.set('graphics', 'height', '240')
    for items in Config.items('input'):
        Config.remove_option('input', items[0])

    from kivy.core.window import Window
    from kivy.context import Context
    from kivy.clock import ClockBase
    from kivy.factory import FactoryBase, Factory
    from kivy.app import App
    from kivy.lang.builder import BuilderBase, Builder
    from kivy.base import stopTouchApp
    from kivy import kivy_data_dir
    from kivy.logger import LoggerHistory

    kivy_eventloop = environ.get('KIVY_EVENTLOOP', 'asyncio')
    if kivy_eventloop == 'asyncio':
        pytest.importorskip(
            'pytest_asyncio',
            reason='KIVY_EVENTLOOP == "asyncio" but '
                   '"pytest_asyncio" is not installed')
        async_lib = 'asyncio'
    elif kivy_eventloop == 'trio':
        pytest.importorskip(
            'pytest_trio',
            reason='KIVY_EVENTLOOP == "trio" but '
                   '"pytest_trio" is not installed')
        async_lib = 'trio'
    else:
        pytest.skip(
            'KIVY_EVENTLOOP must be set to either of "asyncio" or '
            '"trio" to run async tests')

    context = Context(init=False)
    context['Clock'] = ClockBase(async_lib=async_lib)

    # have to make sure all global kv files are loaded before this because
    # globally read kv files (e.g. on module import) will not be loaded again
    # in the new builder, except if manually loaded, which we don't do
    context['Factory'] = FactoryBase.create_from(Factory)
    context['Builder'] = BuilderBase.create_from(Builder)
    context.push()

    Window.create_window()
    Window.register()
    Window.initialized = True
    Window.canvas.clear()

    app = request.param[0]()
    app.set_async_lib(async_lib)

    if async_lib == 'asyncio':
        import asyncio
        loop = asyncio.get_event_loop()
        loop.create_task(app.async_run())
    else:
        nursery.start_soon(app.async_run)
    from kivy.clock import Clock
    Clock._max_fps = 0

    ts = time.perf_counter()
    while not app.app_has_started:
        await app.async_sleep(.1)
        if time.perf_counter() - ts >= 10:
            raise TimeoutError()

    await app.wait_clock_frames(5)

    yield app

    stopTouchApp()

    ts = time.perf_counter()
    while not app.app_has_stopped:
        await app.async_sleep(.1)
        if time.perf_counter() - ts >= 10:
            raise TimeoutError()

    for child in Window.children[:]:
        Window.remove_widget(child)
    context.pop()

    # release all the resources
    del context
    LoggerHistory.clear_history()
    apps.append((weakref.ref(app), request))
    del app
    gc.collect()
Example #25
0
async def kivy_app(request, nursery):
    from os import environ
    environ['KIVY_USE_DEFAULTCONFIG'] = '1'

    # force window size + remove all inputs
    from kivy.config import Config
    Config.set('graphics', 'width', '320')
    Config.set('graphics', 'height', '240')
    for items in Config.items('input'):
        Config.remove_option('input', items[0])

    from kivy.core.window import Window
    from kivy.context import Context
    from kivy.clock import ClockBase
    from kivy.lang.builder import BuilderBase, Builder
    from kivy.base import stopTouchApp
    from kivy import kivy_data_dir

    kivy_eventloop = environ.get('KIVY_EVENTLOOP', 'asyncio')
    if kivy_eventloop == 'asyncio':
        pytest.importorskip('pytest_asyncio',
                            reason='KIVY_EVENTLOOP == "asyncio" but '
                            '"pytest_asyncio" is not installed')
        async_lib = 'asyncio'
    elif kivy_eventloop == 'trio':
        pytest.importorskip('pytest_trio',
                            reason='KIVY_EVENTLOOP == "trio" but '
                            '"pytest_trio" is not installed')
        async_lib = 'trio'
    else:
        pytest.skip(
            reason='KIVY_EVENTLOOP must be set to either of "asyncio" or '
            '"trio" to run async tests')

    context = Context(init=False)
    context['Clock'] = ClockBase(async_lib=async_lib)
    # context['Builder'] = BuilderBase()
    context.push()
    # Builder.load_file(
    #     os.path.join(kivy_data_dir, 'style.kv'), rulesonly=True)

    Window.create_window()
    Window.register()
    Window.initialized = True
    Window.canvas.clear()

    app = request.param[0]()

    if async_lib == 'asyncio':
        import asyncio
        loop = asyncio.get_event_loop()
        loop.create_task(app.async_run())
    else:
        nursery.start_soon(app.async_run)

    ts = time.perf_counter()
    while not app.app_has_started:
        await async_sleep(.1)
        if time.perf_counter() - ts >= 10:
            raise TimeoutError()

    await app.wait_clock_frames(5)

    yield app

    stopTouchApp()

    ts = time.perf_counter()
    while not app.app_has_stopped:
        await async_sleep(.1)
        if time.perf_counter() - ts >= 10:
            raise TimeoutError()

    for child in Window.children[:]:
        Window.remove_widget(child)
    context.pop()
    gc.collect()
Example #26
0
def runTouchApp(widget=None, slave=False):
    '''Static main function that starts the application loop.
    You can access some magic via the following arguments:

    :Parameters:
        `<empty>`
            To make dispatching work, you need at least one
            input listener. If not, application will leave.
            (MTWindow act as an input listener)

        `widget`
            If you pass only a widget, a MTWindow will be created
            and your widget will be added to the window as the root
            widget.

        `slave`
            No event dispatching is done. This will be your job.

        `widget + slave`
            No event dispatching is done. This will be your job but
            we try to get the window (must be created by you beforehand)
            and add the widget to it. Very usefull for embedding Kivy
            in another toolkit. (like Qt, check kivy-designed)

    '''

    from kivy.input import MotionEventFactory, kivy_postproc_modules

    # Ok, we got one widget, and we are not in slave mode
    # so, user don't create the window, let's create it for him !
    if widget:
        EventLoop.ensure_window()

    # Instance all configured input
    for key, value in Config.items('input'):
        Logger.debug('Base: Create provider from %s' % (str(value)))

        # split value
        args = str(value).split(',', 1)
        if len(args) == 1:
            args.append('')
        provider_id, args = args
        provider = MotionEventFactory.get(provider_id)
        if provider is None:
            Logger.warning('Base: Unknown <%s> provider' % str(provider_id))
            continue

        # create provider
        p = provider(key, args)
        if p:
            EventLoop.add_input_provider(p, True)

    # add postproc modules
    for mod in list(kivy_postproc_modules.values()):
        EventLoop.add_postproc_module(mod)

    # add main widget
    if widget and EventLoop.window:
        if widget not in EventLoop.window.children:
            EventLoop.window.add_widget(widget)

    # start event loop
    Logger.info('Base: Start application main loop')
    EventLoop.start()

    # we are in a slave mode, don't do dispatching.
    if slave:
        return

    # in non-slave mode, they are 2 issues
    #
    # 1. if user created a window, call the mainloop from window.
    #    This is due to glut, it need to be called with
    #    glutMainLoop(). Only FreeGLUT got a gluMainLoopEvent().
    #    So, we are executing the dispatching function inside
    #    a redisplay event.
    #
    # 2. if no window is created, we are dispatching event lopp
    #    ourself (previous behavior.)
    #
    try:
        if EventLoop.window is None:
            _run_mainloop()
        else:
            EventLoop.window.mainloop()
    finally:
        stopTouchApp()