| Index: third_party/twisted_8_1/twisted/internet/gtk2reactor.py
|
| diff --git a/third_party/twisted_8_1/twisted/internet/gtk2reactor.py b/third_party/twisted_8_1/twisted/internet/gtk2reactor.py
|
| deleted file mode 100644
|
| index d2aaf030c196c6f07a82cbf41c30c9f222adb597..0000000000000000000000000000000000000000
|
| --- a/third_party/twisted_8_1/twisted/internet/gtk2reactor.py
|
| +++ /dev/null
|
| @@ -1,295 +0,0 @@
|
| -# -*- test-case-name: twisted.internet.test.test_gtk2reactor -*-
|
| -# Copyright (c) 2001-2008 Twisted Matrix Laboratories.
|
| -# See LICENSE for details.
|
| -
|
| -
|
| -"""
|
| -This module provides support for Twisted to interact with the glib/gtk2
|
| -mainloop.
|
| -
|
| -In order to use this support, simply do the following::
|
| -
|
| - | from twisted.internet import gtk2reactor
|
| - | gtk2reactor.install()
|
| -
|
| -Then use twisted.internet APIs as usual. The other methods here are not
|
| -intended to be called directly.
|
| -
|
| -When installing the reactor, you can choose whether to use the glib
|
| -event loop or the GTK+ event loop which is based on it but adds GUI
|
| -integration.
|
| -
|
| -Maintainer: U{Itamar Shtull-Trauring<mailto:twisted@itamarst.org>}
|
| -"""
|
| -
|
| -# System Imports
|
| -import sys
|
| -from zope.interface import implements
|
| -try:
|
| - if not hasattr(sys, 'frozen'):
|
| - # Don't want to check this for py2exe
|
| - import pygtk
|
| - pygtk.require('2.0')
|
| -except (ImportError, AttributeError):
|
| - pass # maybe we're using pygtk before this hack existed.
|
| -import gobject
|
| -if hasattr(gobject, "threads_init"):
|
| - # recent versions of python-gtk expose this. python-gtk=2.4.1
|
| - # (wrapping glib-2.4.7) does. python-gtk=2.0.0 (wrapping
|
| - # glib-2.2.3) does not.
|
| - gobject.threads_init()
|
| -
|
| -# Twisted Imports
|
| -from twisted.python import log, runtime, failure
|
| -from twisted.internet.interfaces import IReactorFDSet
|
| -from twisted.internet import main, posixbase, error, selectreactor
|
| -
|
| -POLL_DISCONNECTED = gobject.IO_HUP | gobject.IO_ERR | gobject.IO_NVAL
|
| -
|
| -# glib's iochannel sources won't tell us about any events that we haven't
|
| -# asked for, even if those events aren't sensible inputs to the poll()
|
| -# call.
|
| -INFLAGS = gobject.IO_IN | POLL_DISCONNECTED
|
| -OUTFLAGS = gobject.IO_OUT | POLL_DISCONNECTED
|
| -
|
| -def _our_mainquit():
|
| - # XXX: gtk.main_quit() (which is used for crash()) raises an exception if
|
| - # gtk.main_level() == 0; however, all the tests freeze if we use this
|
| - # function to stop the reactor. what gives? (I believe this may have been
|
| - # a stupid mistake where I forgot to import gtk here... I will remove this
|
| - # comment if the tests pass)
|
| - import gtk
|
| - if gtk.main_level():
|
| - gtk.main_quit()
|
| -
|
| -class Gtk2Reactor(posixbase.PosixReactorBase):
|
| - """
|
| - GTK+-2 event loop reactor.
|
| -
|
| - @ivar _reads: A dictionary mapping L{FileDescriptor} instances to gtk
|
| - INPUT_READ watch handles.
|
| -
|
| - @ivar _writes: A dictionary mapping L{FileDescriptor} instances to gtk
|
| - INTPUT_WRITE watch handles.
|
| -
|
| - @ivar _simtag: A gtk timeout handle for the next L{simulate} call.
|
| - """
|
| - implements(IReactorFDSet)
|
| -
|
| - def __init__(self, useGtk=True):
|
| - self.context = gobject.main_context_default()
|
| - self.loop = gobject.MainLoop()
|
| - self._simtag = None
|
| - self._reads = {}
|
| - self._writes = {}
|
| - posixbase.PosixReactorBase.__init__(self)
|
| - # pre 2.3.91 the glib iteration and mainloop functions didn't release
|
| - # global interpreter lock, thus breaking thread and signal support.
|
| - if (hasattr(gobject, "pygtk_version") and gobject.pygtk_version >= (2, 3, 91)
|
| - and not useGtk):
|
| - self.__pending = self.context.pending
|
| - self.__iteration = self.context.iteration
|
| - self.__crash = self.loop.quit
|
| - self.__run = self.loop.run
|
| - else:
|
| - import gtk
|
| - self.__pending = gtk.events_pending
|
| - self.__iteration = gtk.main_iteration
|
| - self.__crash = _our_mainquit
|
| - self.__run = gtk.main
|
| -
|
| - # The input_add function in pygtk1 checks for objects with a
|
| - # 'fileno' method and, if present, uses the result of that method
|
| - # as the input source. The pygtk2 input_add does not do this. The
|
| - # function below replicates the pygtk1 functionality.
|
| -
|
| - # In addition, pygtk maps gtk.input_add to _gobject.io_add_watch, and
|
| - # g_io_add_watch() takes different condition bitfields than
|
| - # gtk_input_add(). We use g_io_add_watch() here in case pygtk fixes this
|
| - # bug.
|
| - def input_add(self, source, condition, callback):
|
| - if hasattr(source, 'fileno'):
|
| - # handle python objects
|
| - def wrapper(source, condition, real_s=source, real_cb=callback):
|
| - return real_cb(real_s, condition)
|
| - return gobject.io_add_watch(source.fileno(), condition, wrapper)
|
| - else:
|
| - return gobject.io_add_watch(source, condition, callback)
|
| -
|
| - def addReader(self, reader):
|
| - if reader not in self._reads:
|
| - self._reads[reader] = self.input_add(reader, INFLAGS, self.callback)
|
| -
|
| - def addWriter(self, writer):
|
| - if writer not in self._writes:
|
| - self._writes[writer] = self.input_add(writer, OUTFLAGS, self.callback)
|
| -
|
| -
|
| - def getReaders(self):
|
| - return self._reads.keys()
|
| -
|
| -
|
| - def getWriters(self):
|
| - return self._writes.keys()
|
| -
|
| -
|
| - def removeAll(self):
|
| - return self._removeAll(self._reads, self._writes)
|
| -
|
| - def removeReader(self, reader):
|
| - if reader in self._reads:
|
| - gobject.source_remove(self._reads[reader])
|
| - del self._reads[reader]
|
| -
|
| - def removeWriter(self, writer):
|
| - if writer in self._writes:
|
| - gobject.source_remove(self._writes[writer])
|
| - del self._writes[writer]
|
| -
|
| - doIterationTimer = None
|
| -
|
| - def doIterationTimeout(self, *args):
|
| - self.doIterationTimer = None
|
| - return 0 # auto-remove
|
| -
|
| - def doIteration(self, delay):
|
| - # flush some pending events, return if there was something to do
|
| - # don't use the usual "while self.context.pending(): self.context.iteration()"
|
| - # idiom because lots of IO (in particular test_tcp's
|
| - # ProperlyCloseFilesTestCase) can keep us from ever exiting.
|
| - log.msg(channel='system', event='iteration', reactor=self)
|
| - if self.__pending():
|
| - self.__iteration(0)
|
| - return
|
| - # nothing to do, must delay
|
| - if delay == 0:
|
| - return # shouldn't delay, so just return
|
| - self.doIterationTimer = gobject.timeout_add(int(delay * 1000),
|
| - self.doIterationTimeout)
|
| - # This will either wake up from IO or from a timeout.
|
| - self.__iteration(1) # block
|
| - # note: with the .simulate timer below, delays > 0.1 will always be
|
| - # woken up by the .simulate timer
|
| - if self.doIterationTimer:
|
| - # if woken by IO, need to cancel the timer
|
| - gobject.source_remove(self.doIterationTimer)
|
| - self.doIterationTimer = None
|
| -
|
| - def crash(self):
|
| - posixbase.PosixReactorBase.crash(self)
|
| - self.__crash()
|
| -
|
| - def run(self, installSignalHandlers=1):
|
| - self.startRunning(installSignalHandlers=installSignalHandlers)
|
| - gobject.timeout_add(0, self.simulate)
|
| - if not self._stopped:
|
| - self.__run()
|
| -
|
| - def _doReadOrWrite(self, source, condition, faildict={
|
| - error.ConnectionDone: failure.Failure(error.ConnectionDone()),
|
| - error.ConnectionLost: failure.Failure(error.ConnectionLost()),
|
| - }):
|
| - why = None
|
| - didRead = None
|
| - if condition & POLL_DISCONNECTED and \
|
| - not (condition & gobject.IO_IN):
|
| - why = main.CONNECTION_LOST
|
| - else:
|
| - try:
|
| - if condition & gobject.IO_IN:
|
| - why = source.doRead()
|
| - didRead = source.doRead
|
| - if not why and condition & gobject.IO_OUT:
|
| - # if doRead caused connectionLost, don't call doWrite
|
| - # if doRead is doWrite, don't call it again.
|
| - if not source.disconnected and source.doWrite != didRead:
|
| - why = source.doWrite()
|
| - didRead = source.doWrite # if failed it was in write
|
| - except:
|
| - why = sys.exc_info()[1]
|
| - log.msg('Error In %s' % source)
|
| - log.deferr()
|
| -
|
| - if why:
|
| - self._disconnectSelectable(source, why, didRead == source.doRead)
|
| -
|
| - def callback(self, source, condition):
|
| - log.callWithLogger(source, self._doReadOrWrite, source, condition)
|
| - self.simulate() # fire Twisted timers
|
| - return 1 # 1=don't auto-remove the source
|
| -
|
| - def simulate(self):
|
| - """Run simulation loops and reschedule callbacks.
|
| - """
|
| - if self._simtag is not None:
|
| - gobject.source_remove(self._simtag)
|
| - self.runUntilCurrent()
|
| - timeout = min(self.timeout(), 0.1)
|
| - if timeout is None:
|
| - timeout = 0.1
|
| - # grumble
|
| - self._simtag = gobject.timeout_add(int(timeout * 1010), self.simulate)
|
| -
|
| -
|
| -class PortableGtkReactor(selectreactor.SelectReactor):
|
| - """Reactor that works on Windows.
|
| -
|
| - input_add is not supported on GTK+ for Win32, apparently.
|
| - """
|
| -
|
| - def crash(self):
|
| - selectreactor.SelectReactor.crash(self)
|
| - import gtk
|
| - # mainquit is deprecated in newer versions
|
| - if hasattr(gtk, 'main_quit'):
|
| - gtk.main_quit()
|
| - else:
|
| - gtk.mainquit()
|
| -
|
| - def run(self, installSignalHandlers=1):
|
| - import gtk
|
| - self.startRunning(installSignalHandlers=installSignalHandlers)
|
| - self.simulate()
|
| - # mainloop is deprecated in newer versions
|
| - if hasattr(gtk, 'main'):
|
| - gtk.main()
|
| - else:
|
| - gtk.mainloop()
|
| -
|
| - def simulate(self):
|
| - """Run simulation loops and reschedule callbacks.
|
| - """
|
| - if self._simtag is not None:
|
| - gobject.source_remove(self._simtag)
|
| - self.iterate()
|
| - timeout = min(self.timeout(), 0.1)
|
| - if timeout is None:
|
| - timeout = 0.1
|
| - # grumble
|
| - self._simtag = gobject.timeout_add(int(timeout * 1010), self.simulate)
|
| -
|
| -
|
| -def install(useGtk=True):
|
| - """Configure the twisted mainloop to be run inside the gtk mainloop.
|
| -
|
| - @param useGtk: should glib rather than GTK+ event loop be
|
| - used (this will be slightly faster but does not support GUI).
|
| - """
|
| - reactor = Gtk2Reactor(useGtk)
|
| - from twisted.internet.main import installReactor
|
| - installReactor(reactor)
|
| - return reactor
|
| -
|
| -def portableInstall(useGtk=True):
|
| - """Configure the twisted mainloop to be run inside the gtk mainloop.
|
| - """
|
| - reactor = PortableGtkReactor()
|
| - from twisted.internet.main import installReactor
|
| - installReactor(reactor)
|
| - return reactor
|
| -
|
| -if runtime.platform.getType() != 'posix':
|
| - install = portableInstall
|
| -
|
| -
|
| -__all__ = ['install']
|
|
|