So finally i got a first version of the resource system as discussed before. I'm sure it isn't yet perfect. There are some position in the code where i don't know how to do it better. So i thought i post it here and some one may take a look at it. What works so far. In my test everything that worked before and in addition the joystick plugin can release the joystick for a game and gets resumed afterward. So it should work but maybe there should be some clean up.
Tell me what you think.

Thanks

Mathias
Index: freevo_trunk/core/src/resources.py
===================================================================
--- freevo_trunk/core/src/resources.py	(revision 9421)
+++ freevo_trunk/core/src/resources.py	(working copy)
@@ -29,32 +29,113 @@
 #
 # -----------------------------------------------------------------------------
 
+# kaa imports
+from kaa.notifier import InProgress, Callback
+
 _resources = {}
 
-def get_resources(instance, *resources):
+class ResourceHandler(object):
     """
-    Reserve a list of resources. If one or more resources can not be
-    reserved, the whole operation fails. The function will return the
-    list of failed resources with the instance having this resource.
+    The ResourceHandler inherit from it if you want to use resources that need
+    a specific access rights.
     """
-    blocked = {}
-    for r in resources:
-        if r in _resources:
-            blocked[r] = _resources[r]
-    if blocked:
-        # failed to reserve
-        return blocked
-    # reserve all resources
-    for r in resources:
-        _resources[r] = instance
-    return {}
+    suspended_handler = []
 
+    def get_resources(self, *resources):
+        """
+        Reserve a list of resources. If one or more resources can not be
+        reserved, the whole operation fails. The function will return the
+        list of failed resources with this instance having this resource.
+        """
+        blocked = {}
+        for r in resources:
+            if r in _resources:
+                if _resources[r].can_suspend():
+                    blocked[r] = _resources[r]
+                else:
+                    return False
+        if blocked:
+            # failed to reserve
+            return blocked
+        # reserve all resources
+        for r in resources:
+            _resources[r] = self
+        return {}
 
-def free_resources(instance, *resources):
-    """
-    Free all resources blocked by the instance. If not resources are
-    provided, free all resources.
-    """
-    for res, app in _resources.items()[:]:
-        if app == instance and (not resources or res in resources):
-            del _resources[res]
+
+    def free_resources(self, *resources):
+        """
+        Free all resources blocked by this instance. If no resources are
+        provided, free all resources.
+        """
+        for res, app in _resources.items()[:]:
+            if app == self and (not resources or res in resources):
+                del _resources[res]
+
+
+    def _handler_suspended(self, t, blocked, callback):
+        """
+        Callback for handler that need some more time to release a resource.
+        """
+        for resource in blocked.keys():
+            if resource in _resources:
+                # not yet all resources are free yet
+                return
+
+        # all resource are free now call the handler
+        callback()
+
+
+    def suspend_all(self, blocked, callback):
+        """
+        Suspend all handler that block a resource if done call the callback
+        method.
+        """
+        wait = False
+        # call for all the suspend
+        for handler in blocked:
+            self.suspended_handler.append(blocked[handler])
+            answer = blocked[handler].suspend()
+            if isinstance(answer, InProgress):
+                callback = Callback(self._handler_suspended, blocked, callback)
+#                answer.connect(self._handler_suspended, blocked, callback)
+                answer.connect(callback)
+                wait = True
+            
+        if wait == True:
+            return
+        else:
+            callback()
+
+
+    def resume_all(self):   
+        """
+        Resume all handler suspended by this handler. Clear list at the end.
+        """
+        # resume suspended handlers
+        for handler in self.suspended_handler:
+            handler.resume()
+        # clear list with suspended handler since all resumed
+        self.suspended_handler = []
+
+
+    def can_suspend(self):
+        """
+        Return if it is possible for this handler to release its resource.
+        """
+        return False
+
+
+    def suspend(self):
+        """
+        Suspend this resource handler. Should free all the resources.
+        """
+        return False
+
+
+    def resume(self):
+        """
+        Resume the plugin acquire all the resources again.
+        """
+        pass
+
Index: freevo_trunk/ui/src/games/emulator.py
===================================================================
--- freevo_trunk/ui/src/games/emulator.py	(revision 9422)
+++ freevo_trunk/ui/src/games/emulator.py	(working copy)
@@ -47,9 +47,11 @@
 
 # freevo imports
 import freevo.conf
+from freevo.resources import ResourceHandler
 from freevo.ui.mainmenu import MainMenuItem, MainMenuPlugin
 from freevo.ui.directory import DirItem
 from freevo.ui.event import *
+from freevo.ui import plugin, application
 from freevo.ui.menu import Item, Action, Menu
 from freevo.ui.plugins.mediamenu import MediaMenu
 
@@ -135,7 +137,7 @@
                 Action(_('Remove %s') % self.name, self.remove)]
 
 
-class EmulatorPlayer(object):
+class EmulatorPlayer(ResourceHandler):
     """
     Generic game player.
     """
@@ -165,7 +167,6 @@
         Play game. Should work with most emulators. Will start
         [command_name] [parameters] [url]
         """
-        self._releaseJoystick()
         params = "%s %s" % (self.parameters, self.url)
         log.info('Start playing EmulatorItem (%s %s)' % \
                 (self.command_name, params))
@@ -191,7 +192,6 @@
         The game was quit. Send stop event to get back to the menu.
         """
         Event(STOP, handler=gameplayer.player.eventhandler).post()
-        self._acquireJoystick()
         log.info('emulator completed')
 
 
@@ -203,23 +203,7 @@
             self.child.stop()
 
 
-    def _releaseJoystick(self):
-        """
-        Release Joystick that it can be used by the game/emulator
-        """
-        #FIXME
-        pass
 
-
-    def _acquireJoystick(self):
-        """
-        Acquire Joysitck back that it can be used by freevo
-        """
-        #FIXME
-        pass
-
-
-
 class EmulatorMenuItem(MainMenuItem):
     """
     This is a menu entry for the different emulators in the games subdirectory.
Index: freevo_trunk/ui/src/games/plugins/pcgames.py
===================================================================
--- freevo_trunk/ui/src/games/plugins/pcgames.py	(revision 9422)
+++ freevo_trunk/ui/src/games/plugins/pcgames.py	(working copy)
@@ -75,7 +75,6 @@
         Play PcGame
         """
         log.info('Start playing PcGame (%s %s)', self.command_name, self.parameters)
-        self._releaseJoystick()
         self.child = kaa.notifier.Process(self.command_name)
         self.child.start(self.parameters).connect(self.completed)
         self.signals = self.child.signals
@@ -88,7 +87,6 @@
         The game was quit. Send Stop event to get back to the menu.
         """
         Event(STOP, handler=gameplayer.player.eventhandler).post()
-        self._acquireJoystick()
         log.info('Game completed')
 
 
Index: freevo_trunk/ui/src/games/plugins/scummvm.py
===================================================================
--- freevo_trunk/ui/src/games/plugins/scummvm.py	(revision 9422)
+++ freevo_trunk/ui/src/games/plugins/scummvm.py	(working copy)
@@ -36,7 +36,6 @@
 
 # python imports
 import logging
-from subprocess import Popen, PIPE
 
 # kaa imports
 import kaa.utils
@@ -74,7 +73,6 @@
         """
         log.info('Start playing PcGame (Scummvm: %s)', self.emulator_item)
         parameters = '%s %s' % (config.parameters, self.emulator_item)
-        self._releaseJoystick()
         self.child = kaa.notifier.Process(config.bin)
         self.child.start(parameters).connect(self.completed)
         self.signals = self.child.signals
@@ -97,25 +95,54 @@
     """
     romlist = []
     finished = False
+    parent = None
+    items = None
+    list_started = False
 
+    def completed(self, exit_code):
+        """
+        The ScummVM returned all configured games, append them to the menu.
+        Add an entry for the ScummVM it self to configure new games or the
+        ScummVM it self.
+        """
+        if self.items == None:
+            self.items = []
+        self.items.append(ScummvmItem(self.parent, 'ScummVM', ''))
+        self.parent.pushmenu(Menu(config.name, self.items, type='games'))
+        self.parent = None
+
+
+    def get_stdout(self, data):
+        """
+        Receive updates from the stdout of the ScummVM. Wait with parsing
+        until a line that starts with '---'
+        """
+        if self.items == None:
+            if data.startswith('---'):
+                self.items = []
+            return
+        # since list was started there are now the configured games coming    
+        name = data[:data.find(' ')]
+        description = data[data.find(' '):].strip()
+        self.items.append(ScummvmItem(self.parent, description, name))        
+
+
     def roms(self, parent):
         """
         Show all games.
         """
+        # allready waiting for updated menu?
+        if self.parent != None:
+            return
+        self.parent = parent
+        self.items = None
         items = []
-        # get list of scummvm
-        pipe = Popen([config.bin, '-t'], stdout=PIPE).stdout
-        # FIXME: this blocks the notifier loop. Maybe better use
-        # kaa.notifier.Process and yield_execution.
-        for item in pipe.readlines()[2:]:
-            name = item[:item.find(' ')]
-            description = item[item.find(' '):].strip()
-            items.append(ScummvmItem(parent, description, name))
-        # append the scummvm it self, to configure new games
-        items.append(ScummvmItem(parent, 'ScummVM', ''))
-        parent.pushmenu(Menu(config.name, items, type='games'))
+        # get list of scummvm start a new process
+        self.child = kaa.notifier.Process(config.bin)
+        self.child.start('-t').connect(self.completed)
+        self.child.signals['stdout'].connect(self.get_stdout)
+        
 
-
     def items(self, parent):
         """
         Return the main menu item.
Index: freevo_trunk/ui/src/games/player.py
===================================================================
--- freevo_trunk/ui/src/games/player.py	(revision 9422)
+++ freevo_trunk/ui/src/games/player.py	(working copy)
@@ -65,6 +65,7 @@
         if player == None:
             return False
         self.player = player
+        retry = kaa.notifier.Callback(self.play, item, player)
         if not self.status in (STATUS_IDLE, STATUS_STOPPED):
             # Already running, stop the current player by sending a STOP
             # event. The event will also get to the playlist behind the
@@ -83,38 +84,13 @@
         # Try to get VIDEO and AUDIO resources. The ressouces will be freed
         # by the system when the application switches to STATUS_STOPPED or
         # STATUS_IDLE.
-        blocked = self.get_resources('AUDIO', 'VIDEO')
-        if 'VIDEO' in blocked:
-            # Something has the video resource blocked. The only application
-            # possible is the tv player right now. It would be possible to
-            # ask the user what to do with a popup but we assume the user
-            # does not care about the tv and just stop it. FIXME ask user
-            Event(STOP, handler=blocked['VIDEO'].eventhandler).post()
-            # Now connect to the 'stop' signal once to repeat this current
-            # function call without the player playing
-            blocked['VIDEO'].signals['stop'].connect_once(retry)
+        blocked = self.get_resources('AUDIO', 'VIDEO', 'JOYSTICK')
+        if blocked == False:
+            log.error("Can't get resource AUDIO, VIDEO, JOYSTICK")
+            return False
+        elif len(blocked) > 0:
+            self.suspend_all(blocked, retry)
             return True
-        if 'AUDIO' in blocked:
-            # AUDIO is blocked, VIDEO is not. This is most likely the audio
-            # player and we can pause it. Do this if possible.
-            if not blocked['AUDIO'].has_capability(CAPABILITY_PAUSE):
-                # Unable to pause, just stop it
-                Event(STOP, handler=blocked['AUDIO'].eventhandler).post()
-                # Now connect to the 'stop' signal once to repeat this current
-                # function call without the player playing
-                blocked['AUDIO'].signals['stop'].connect_once(retry)
-                return True
-            # Now pause the current player. On its pause signal this player can
-            # play again. And on the stop signal of this player (STATUS_IDLE)
-            # the other player can be resumed again.
-            in_progress = blocked['AUDIO'].pause()
-            if isinstance(in_progress, kaa.notifier.InProgress):
-                # takes some time, wait
-                in_progress.connect(retry).set_ignore_caller_args()
-            if in_progress is not False:
-                # we paused the application, resume on our stop
-                self.signals['stop'].connect_once(blocked['AUDIO'].resume)
-            return True
 
         # store item
         self.item = item
@@ -144,6 +120,40 @@
         self.status = STATUS_STOPPING
 
 
+    def can_suspend(self):
+        """
+        Return true since it is possible to stop the game. If it is allways the
+        best thing to just stop a game is more questionable. Maybe False would
+        be better.
+        """
+        return True
+
+
+    def suspend(self):
+        """
+        Release the audio, video, joystick resource. (Stop the game)
+        """
+        if not self.status == STATUS_RUNNING:
+            yield False
+        self.status = STATUS_STOPPING
+        self.player.stop()
+        yield kaa.notifiert.YieldCallback(self.player.signals['end'])
+        self.free_resources()
+        yield True
+
+
+    def resume(self):
+        """
+        Replay the game? At the moment this does nothing. The game won't 
+        restart.
+        """
+        # restart the handler stoped by this handler before since we don't
+        # run anymore
+        if not self.status == STATUS_RUNNING:
+            return False
+        self.resume_all()
+        return True
+
     def eventhandler(self, event):
         """
         React on events and do the right command with the game.
Index: freevo_trunk/ui/src/input/plugins/joystick.py
===================================================================
--- freevo_trunk/ui/src/input/plugins/joystick.py	(revision 9422)
+++ freevo_trunk/ui/src/input/plugins/joystick.py	(working copy)
@@ -31,51 +31,56 @@
 #
 # -----------------------------------------------------------------------------
 
-import kaa.notifier
-
+# python imports
 import sys
 import os
 import select
 import struct
 from time import sleep
 
-from freevo.ui import config
+# kaa imports
+import kaa.notifier
+
+# freevo imports
+from freevo.resources import ResourceHandler
+from freevo.ui import config, application
 from interface import InputPlugin
+from freevo.ui.config import config
 
 import logging
 log = logging.getLogger('input')
 
-class PluginInterface(InputPlugin):
+class PluginInterface(InputPlugin, ResourceHandler):
 
     # Hardcoded for now to make it work at the CeBIT. This needs to
     # be a config variable.
-    
-    KEYMAP = {
-        'button 1' : 'PLAY',
-        'button 3' : 'STOP',
-        'button 5' : 'EXIT',
-        'button 7' : 'EXIT',
-        'button 8' : 'SELECT',
-        'button 6' : 'ENTER',
-        'up 2'     : 'UP',
-        'down 2'   : 'DOWN',
-        'left 2'   : 'LEFT',
-        'right 2'  : 'RIGHT' }
+    KEYMAP = {}
 
-
     def __init__(self):
         InputPlugin.__init__(self)
 
-        # TODO: this needs to be a parameter to the plugin
-        self.device_name = '/dev/input/js0'
+        self.config = config.input.plugin.joystick
 
+        self.device_name = self.config.device
+
+        blocked = self.get_resources('JOYSTICK')
+        if len(blocked) != 0:
+            # FIXME maybe different joysticks possible?
+            log.error("Joystick is allready used, can't start joystick plugin")
+            return
+
+        for mapping in self.config.events:
+            self.KEYMAP[mapping.input] = mapping.event
         try:
             self.joyfd = os.open(self.device_name, os.O_RDONLY|os.O_NONBLOCK)
         except OSError:
-            reason = 'Unable to open %s' % self.device_name
+#            reason = 'Unable to open %s' % self.device_name
+            log.error('Could not open joystick interface (%s)'%self.device_name)
+            self.free_resources()
             return
 
-        kaa.notifier.SocketDispatcher(self.handle).register(self.joyfd)
+        self.socket_dispatcher = kaa.notifier.SocketDispatcher(self.handle)
+        self.socket_dispatcher.register(self.joyfd)
         self.timer = kaa.notifier.OneShotTimer(self.axis)
         self.movement = {}
         self.events = {}
@@ -118,7 +123,7 @@
             if button in self.KEYMAP:
                 self.post_key(self.KEYMAP[button])
             return True
-        
+
         if data[2] == 2:
             # stick, this is all very ugly!!!
 
@@ -145,3 +150,53 @@
             self.events[button].append(data[1])
             self.timer.start(0.1)
         return True
+    
+
+    def can_suspend(self):
+        """
+        Return true since the plugin can be suspended.
+        """
+        return True
+
+
+    def suspend(self):
+        """
+        Release the joystick that it can be used by others.
+        """
+        try:
+            self.timer.stop()
+            self.socket_dispatcher.unregister()
+            os.close(self.joyfd)
+            self.free_resources()
+        except OSError:
+            log.error('Could not close Filedescriptor for joystick')
+            return False
+        return True
+        log.info('Joystick plugin suspended.')
+
+
+
+    def resume(self):
+        """
+        Acquire Joystick to be used as a remote.
+        """
+        blocked = self.get_resources('JOYSTICK')
+        if blocked == False:
+            return False
+        elif len(blocked) != 0:
+            # FIXME maybe different joysticks possible?
+            log.error("Joystick is allready used, can't start joystick plugin")
+            return False
+
+        try:
+            self.joyfd = os.open(self.device_name, os.O_RDONLY|os.O_NONBLOCK)
+        except OSError:
+            log.error('Could not open joystick interface (%s)'%self.device_name)
+            return
+
+        self.socket_dispatcher.register(self.joyfd)
+        self.movement = {}
+        self.events = {}
+        self.timer.start(0.1)
+        log.info('Jostick plugin resumed')
+
Index: freevo_trunk/ui/src/input/plugins/config.cxml
===================================================================
--- freevo_trunk/ui/src/input/plugins/config.cxml	(revision 9422)
+++ freevo_trunk/ui/src/input/plugins/config.cxml	(working copy)
@@ -26,9 +26,25 @@
 
     <group name="joystick" plugin="true">
         <desc>
-            Joystick plugin. This plugin defines a fixed mapping. If someone
-            needs more, please send a patch using a config here.
+            Joystick plugin.
         </desc>
+        <var name="device" type="str">
+            <desc>The Joystick input device for example /dev/input/js0</desc>
+        </var>
+        <list name="events">
+            <var name="event" type="str">
+                <desc>The event to send on this button/axis event. For
+                example EXIT, SELECT, UP, DOWN,...</desc>
+            </var>
+            <var name="input" type="str">
+                <desc>The input that raises the event. Example:
+                      button 1 (for the first button no the joystick)
+                      button 2 ...
+                      up 0 (the first axis up)
+                      down 1 (the second axis down)
+                </desc>
+            </var>
+        </list>
     </group>
 
 </config>
Index: freevo_trunk/ui/src/audio/player.py
===================================================================
--- freevo_trunk/ui/src/audio/player.py	(revision 9422)
+++ freevo_trunk/ui/src/audio/player.py	(working copy)
@@ -44,8 +44,8 @@
 
 from freevo.ui.event import *
 from freevo.ui.application import Application, STATUS_RUNNING, STATUS_STOPPING, \
-	 STATUS_STOPPED, STATUS_IDLE, CAPABILITY_TOGGLE, CAPABILITY_PAUSE, \
-	 CAPABILITY_FULLSCREEN
+     STATUS_STOPPED, STATUS_IDLE, CAPABILITY_TOGGLE, CAPABILITY_PAUSE, \
+     CAPABILITY_FULLSCREEN
 
 # get logging object
 log = logging.getLogger('audio')
@@ -66,6 +66,7 @@
         """
         play an item
         """
+        retry = kaa.notifier.Callback(self.play, item)
         if not self.status in (STATUS_IDLE, STATUS_STOPPED):
             # Already running, stop the current player by sending a STOP
             # event. The event will also get to the playlist behind the
@@ -73,7 +74,7 @@
             Event(STOP, handler=self.eventhandler).post()
             # Now connect to our own 'stop' signal once to repeat this current
             # function call without the player playing
-            self.signals['stop'].connect_once(self.play, item)
+            self.signals['stop'].connect_once(retry)
             return True
 
         if not kaa.notifier.running:
@@ -84,12 +85,11 @@
         # Try to get AUDIO resource. The ressouce will be freed by the system
         # when the application switches to STATUS_STOPPED or STATUS_IDLE.
         blocked = self.get_resources('AUDIO')
-        if 'AUDIO' in blocked:
-            # Something has the audio resource blocked, stop it
-            Event(STOP, handler=blocked['AUDIO'].eventhandler).post()
-            # Now connect to the 'stop' signal once to repeat this current
-            # function call without the player playing
-            blocked['AUDIO'].signals['stop'].connect_once(self.play, item)
+        if blocked == False:
+            log.error("Can't get Audio resource.")
+            return False
+        elif len(blocked) != 0:
+            self.suspend_all(blocked, retry)
             return True
 
         # Store item and playlist. We need to keep the playlist object
@@ -141,41 +141,6 @@
         self.status = STATUS_STOPPING
 
 
-    @kaa.notifier.yield_execution()
-    def pause(self):
-        """
-        Pause Playback. Return False if already paused.
-        """
-        # FIXME: make sure this function is not called twice
-        if not self.status == STATUS_RUNNING:
-            yield False
-        if self.player.get_state() == kaa.popcorn.STATE_PAUSED:
-            yield None
-        # FIXME: what happens if we send pause() the same time the file
-        # is finished? This would create a race condition.
-        self.player.pause()
-        yield kaa.notifier.YieldCallback(self.player.signals['pause'])
-        self.free_resources()
-
-
-    @kaa.notifier.yield_execution()
-    def resume(self):
-        """
-        Resume Playback. Return False if already resumed.
-        """
-        # FIXME: make sure this function is not called twice
-        if not self.status == STATUS_RUNNING:
-            yield False
-        if self.player.get_state() == kaa.popcorn.STATE_PLAYING:
-            yield False
-        if self.get_resources('AUDIO'):
-            # FIXME: what to do in this case?
-            log.error('unable to get AUDIO ressource')
-            yield False
-        self.player.resume()
-        yield kaa.notifier.YieldCallback(self.player.signals['play'])
-
-
     def elapsed(self):
         """
         Callback for elapsed time changes.
@@ -216,7 +181,7 @@
 
         if event in (PAUSE, PLAY):
             if self.player.get_state() == kaa.popcorn.STATE_PLAYING:
-                self.pause()
+                self.suspend() 
                 return True
             if self.player.get_state() == kaa.popcorn.STATE_PAUSED:
                 self.resume()
@@ -230,6 +195,52 @@
         return self.item.eventhandler(event)
 
 
+    def can_suspend(self):
+        """
+        Return true since the application can be suspended.
+        """
+        return True
+
+    @kaa.notifier.yield_execution()
+    def suspend(self):
+        """
+        Release the audio resource that others can use it.
+        """
+        # FIXME: make sure this function is not called twice
+        if not self.status == STATUS_RUNNING:
+            yield False
+        if self.player.get_state() == kaa.popcorn.STATE_PAUSED:
+            yield None
+        # FIXME: what happens if we send pause() the same time the file
+        # is finished? This would create a race condition.
+        self.player.pause()
+        yield kaa.notifier.YieldCallback(self.player.signals['pause'])
+        self.free_resources()
+
+    
+    @kaa.notifier.yield_execution()
+    def resume(self):
+        """
+        Resume playing the audio, at the position before.
+        """
+        # FIXME: make sure this function is not called twice
+        if not self.status == STATUS_RUNNING:
+            yield False
+        if self.player.get_state() == kaa.popcorn.STATE_PLAYING:
+            yield False
+        blocked = self.get_resources('AUDIO')
+        if blocked == False:
+            # FIXME: what to do in this case?
+            log.error('unable to get AUDIO ressource')
+            yield False
+        elif len(blocked) > 0:
+            self.suspend_all(blocked, self.resume)
+            # FIXME: return an YieldCallback
+            yield None
+        self.player.resume()
+        yield kaa.notifier.YieldCallback(self.player.signals['play'])
+
+
 # create singleton object
 player = kaa.utils.Singleton(Player)
 
Index: freevo_trunk/ui/src/application/base.py
===================================================================
--- freevo_trunk/ui/src/application/base.py	(revision 9422)
+++ freevo_trunk/ui/src/application/base.py	(working copy)
@@ -38,11 +38,11 @@
 from kaa.notifier import Signal
 
 # freevo imports
+from freevo.resources import ResourceHandler
 from freevo.ui import gui
 
 # application imports
 from handler import handler
-from resources import get_resources, free_resources
 
 # get logging object
 log = logging.getLogger()
@@ -56,7 +56,7 @@
 CAPABILITY_PAUSE      = 2
 CAPABILITY_FULLSCREEN = 4
 
-class Application(object):
+class Application(ResourceHandler):
     """
     A basic application
     """
@@ -98,6 +98,7 @@
         """
         if status in (STATUS_STOPPED, STATUS_IDLE):
             self.free_resources()
+            self.resume_all()
         if status == STATUS_RUNNING and self._status == STATUS_IDLE:
             handler.show_application(self)
             self._status = status
@@ -178,23 +179,6 @@
         return self.__name
 
 
-    def get_resources(self, *resources):
-        """
-        Reserve a list of resources. If one or more resources can not be
-        reserved, the whole operation fails. The function will return the
-        list of failed resources with the application having this resource.
-        """
-        return get_resources(self, *resources)
-
-
-    def free_resources(self, *resources):
-        """
-        Free all resources blocked by this application. If not resources are
-        provided, free all resources.
-        """
-        return free_resources(self, *resources)
-
-
     def __repr__(self):
         """
         String for debugging.
Index: freevo_trunk/ui/src/application/resources.py
===================================================================
--- freevo_trunk/ui/src/application/resources.py	(revision 9422)
+++ freevo_trunk/ui/src/application/resources.py	(working copy)
@@ -1,60 +0,0 @@
-# -*- coding: iso-8859-1 -*-
-# -----------------------------------------------------------------------------
-# resources.py - Ressource Management
-# -----------------------------------------------------------------------------
-# $Id$
-#
-# -----------------------------------------------------------------------------
-# Freevo - A Home Theater PC framework
-# Copyright (C) 2007 Dirk Meyer, et al.
-#
-# First Edition: Dirk Meyer <[EMAIL PROTECTED]>
-# Maintainer:    Dirk Meyer <[EMAIL PROTECTED]>
-#
-# Please see the file AUTHORS for a complete list of authors.
-#
-# 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 2 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 MER-
-# CHANTABILITY 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, write to the Free Software Foundation, Inc.,
-# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# -----------------------------------------------------------------------------
-
-_resources = {}
-
-def get_resources(instance, *resources):
-    """
-    Reserve a list of resources. If one or more resources can not be
-    reserved, the whole operation fails. The function will return the
-    list of failed resources with the instance having this resource.
-    """
-    blocked = {}
-    for r in resources:
-        if r in _resources:
-            blocked[r] = _resources[r]
-    if blocked:
-        # failed to reserve
-        return blocked
-    # reserve all resources
-    for r in resources:
-        _resources[r] = instance
-    return {}
-
-
-def free_resources(instance, *resources):
-    """
-    Free all resources blocked by the instance. If not resources are
-    provided, free all resources.
-    """
-    for res, app in _resources.items()[:]:
-        if app == instance and (not resources or res in resources):
-            del _resources[res]
Index: freevo_trunk/ui/src/application/__init__.py
===================================================================
--- freevo_trunk/ui/src/application/__init__.py	(revision 9422)
+++ freevo_trunk/ui/src/application/__init__.py	(working copy)
@@ -29,7 +29,6 @@
 #
 # -----------------------------------------------------------------------------
 
-from resources import get_resources, free_resources
 from base import Application, STATUS_RUNNING, STATUS_STOPPING, \
      STATUS_STOPPED, STATUS_IDLE, CAPABILITY_TOGGLE, CAPABILITY_PAUSE, \
      CAPABILITY_FULLSCREEN
Index: freevo_trunk/ui/src/video/player.py
===================================================================
--- freevo_trunk/ui/src/video/player.py	(revision 9422)
+++ freevo_trunk/ui/src/video/player.py	(working copy)
@@ -44,8 +44,8 @@
 
 from freevo.ui.event import *
 from freevo.ui.application import Application, STATUS_RUNNING, STATUS_STOPPING, \
-	 STATUS_STOPPED, STATUS_IDLE, CAPABILITY_TOGGLE, CAPABILITY_PAUSE, \
-	 CAPABILITY_FULLSCREEN
+    STATUS_STOPPED, STATUS_IDLE, CAPABILITY_TOGGLE, CAPABILITY_PAUSE, \
+    CAPABILITY_FULLSCREEN
 
 # get logging object
 log = logging.getLogger('video')
@@ -87,37 +87,12 @@
         # by the system when the application switches to STATUS_STOPPED or
         # STATUS_IDLE.
         blocked = self.get_resources('AUDIO', 'VIDEO')
-        if 'VIDEO' in blocked:
-            # Something has the video resource blocked. The only application
-            # possible is the tv player right now. It would be possible to
-            # ask the user what to do with a popup but we assume the user
-            # does not care about the tv and just stop it.
-            Event(STOP, handler=blocked['VIDEO'].eventhandler).post()
-            # Now connect to the 'stop' signal once to repeat this current
-            # function call without the player playing
-            blocked['VIDEO'].signals['stop'].connect_once(retry)
+        if blocked == False:
+            log.error("Can't get resource AUDIO, VIDEO")
+            return False
+        elif len(blocked) > 0:
+            self.suspend_all(blocked, retry)
             return True
-        if 'AUDIO' in blocked:
-            # AUDIO is blocked, VIDEO is not. This is most likely the audio
-            # player and we can pause it. Do this if possible.
-            if not blocked['AUDIO'].has_capability(CAPABILITY_PAUSE):
-                # Unable to pause, just stop it
-                Event(STOP, handler=blocked['AUDIO'].eventhandler).post()
-                # Now connect to the 'stop' signal once to repeat this current
-                # function call without the player playing
-                blocked['AUDIO'].signals['stop'].connect_once(retry)
-                return True
-            # Now pause the current player. On its pause signal this player can
-            # play again. And on the stop signal of this player (STATUS_IDLE)
-            # the other player can be resumed again.
-            in_progress = blocked['AUDIO'].pause()
-            if isinstance(in_progress, kaa.notifier.InProgress):
-                # takes some time, wait
-                in_progress.connect(retry).set_ignore_caller_args()
-            if in_progress is not False:
-                # we paused the application, resume on our stop
-                self.signals['stop'].connect_once(blocked['AUDIO'].resume)
-            return True
 
         # store item and playlist
         self.item = item
@@ -179,6 +154,44 @@
         self.item.elapsed = round(self.player.get_position())
 
 
+    def can_suspend(self):
+        """
+        Return true since the video player can be suspended. It is more likely
+        to be stoped, but still it will release the resource.
+        """
+        return True
+
+    @kaa.notifier.yield_execution()
+    def suspend(self):
+        """
+        Release the audio and video resource.
+        """
+        if not self.status == STATUS_RUNNING:
+            yield False
+        if self.player.get_state == kaa.popcorn.STATE_PAUSED:
+            yield False
+        self.player.stop()
+        self.status = STATUS_STOPPING
+        yield kaa.notifier.YieldCallback(self.player.signals['stop'])
+        self.free_resources()
+        yield True
+
+
+    def resume(self):
+        """
+        Resume video. At the moment do nothing so video is only stoped, but
+        does not restart. TODO
+        """
+        if not self.status == STATUS_RUNNING:
+            return False
+        if self.player.get_state == kaa.popcorn.STATUS_RUNNING:
+            return False
+        # since we don't pause the video player we stop it restart everything
+        # that was running before.
+        self.resume_all()
+        return True
+
+
     def eventhandler(self, event):
         """
         React on some events or send them to the real player or the
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Freevo-devel mailing list
Freevo-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/freevo-devel

Reply via email to