Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/olpcgames/_gtkmain.py
blob: 33a6a83aa27641df4cbd6ab24384c41765502d4c (plain)
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
"""Support for GObject mainloop-requiring libraries when not inside GTK

INITIALIZED -- whether we have a running gobject loop yet...
LOOP_TRACKER -- if present, the manual gtk event loop used to 
    support gobject-based code running in a non-Gobject event loop

Holder -- objects which can be held as attributes to keep the mainloop running
"""
import threading, logging
log = logging.getLogger( 'olpcgames._gtkmain' )
##log.setLevel( logging.DEBUG )

INITIALIZED = False
LOOP_TRACKER = None

class _TrackLoop( object ):
    """Tracks the number of open loops and stops when finished"""
    count = 0
    _mainloop = None
    def increment( self ):
        log.info( 'Increment from %s', self.count )
        self.count += 1 # XXX race condition here?
        if self.count == 1:
            log.info( 'Creating GObject mainloop')
            self.t_loop = threading.Thread(target=self.loop)
            self.t_loop.setDaemon( True )
            self.t_loop.start()
    def decrement( self ):
        log.info( 'Decrement from %s', self.count )
        self.count -= 1
    def loop( self ):
        """Little thread loop that replicates the gtk mainloop"""
        import gtk
        while self.count >= 1:
            log.debug( 'GTK loop restarting' )
            while gtk.events_pending():
                gtk.main_iteration()
        log.debug( 'GTK loop exiting' )
        try:
            del self.t_loop
        except AttributeError, err:
            pass

class Holder():
    """Object which, while held, keeps the gtk mainloop running"""
    def __init__( self ):
        log.info( 'Beginning hold on GTK mainloop with Holder object' )
        startGTK()
    def __del__( self ):
        log.info( 'Releasing hold on GTK mainloop with Holder object' )
        stopGTK()

def startGTK( ):
    """GTK support is required here, process..."""
    if not INITIALIZED:
        init()
    if LOOP_TRACKER:
        LOOP_TRACKER.increment()
def stopGTK( ):
    """GTK support is no longer required, release"""
    if LOOP_TRACKER:
        LOOP_TRACKER.decrement()
def init( ):
    """Create a gobject mainloop in a sub-thread (you don't need to call this normally)"""
    global INITIALIZED, LOOP_TRACKER
    if not INITIALIZED:
        if not LOOP_TRACKER:
            LOOP_TRACKER = _TrackLoop()
        INITIALIZED = True
    return LOOP_TRACKER