""" gtasklets demo program #2 needs patch at http://bugzilla.gnome.org/show_bug.cgi?id=139176 """ from optparse import OptionParser import os import subprocess import sys import gobject import gtk import pango from kiwi import tasklet try: import win32api def killproc(pid): """kill function for Win32""" handle = win32api.OpenProcess(1, 0, pid) return (0 != win32api.TerminateProcess(handle, 0)) except ImportError: import signal def killproc(pid): """kill function for POSIX""" return os.kill(pid, signal.SIGTERM) def process_stdout_sink(chan, buffer, view): timeout = tasklet.WaitForTimeout(200) iowait = tasklet.WaitForIO(chan, priority=1000) msgwait = tasklet.WaitForMessages(accept='quit') while True: yield iowait, msgwait ev = tasklet.get_event() if isinstance(ev, tasklet.Message) and ev.name == 'quit': return assert ev is iowait text = chan.read() buffer.insert(buffer.get_end_iter(), text) view.scroll_to_mark(buffer.get_insert(), 0) ## Now wait for some time, don't let process output "drown" ## the TextView updates yield timeout, tasklet.WaitForMessages(defer='quit') ev = tasklet.get_event() assert ev is timeout def main(): parser = OptionParser(usage="usage: %prog command") (options, args) = parser.parse_args() if len(args) != 1: parser.print_help() sys.exit(1) win = gtk.Window() textview = gtk.TextView() textview.modify_font(pango.FontDescription("Monospace")) textview.show() sw = gtk.ScrolledWindow() sw.add(textview) sw.show() win.add(sw) win.set_default_size(gtk.gdk.screen_width()*2/3, gtk.gdk.screen_height()*2/3) win.show() ## launch process proc = subprocess.Popen(args[0], shell=True, stdout=subprocess.PIPE, bufsize=1, close_fds=True) win.set_title("%s (running)" % args[0]) #print proc.stdout, type(proc.stdout), dir(proc.stdout) chan = gobject.IOChannel(filedes=proc.stdout.fileno()) chan.set_flags(gobject.IO_FLAG_NONBLOCK) sink = tasklet.run(process_stdout_sink(chan, textview.get_buffer(), textview)) ## child watch yield (tasklet.WaitForProcess(proc.pid), tasklet.WaitForSignal(win, "destroy")) if isinstance(tasklet.get_event(), tasklet.WaitForSignal): killproc(proc.pid) gtk.main_quit() else: ## stop reader yield tasklet.Message("quit", dest=sink) win.set_title("%s (completed)" % args[0]) yield tasklet.WaitForSignal(win, "destroy") tasklet.get_event() gtk.main_quit() if __name__ == '__main__': tasklet.run(main()) gtk.main()