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
|