summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Levy <alevy@redhat.com>2011-10-12 14:54:36 +0200
committerAlon Levy <alevy@redhat.com>2011-10-12 14:54:36 +0200
commitfd2e94cb5cf10127dff244ea40d20c85b26028f4 (patch)
treef7ac9c3ea5a10431b361d1c99b3984fb03c30321
parentecfc7f6751ba3fe29cb720a3c65da92adf82732a (diff)
screen_dump_qxl
gtk utility to take screen dumps for normal or qxl devices (despite the name) via qmp: qemu -chardev socket,path=/tmp/qmp,server,nowait,id=qmp -mon \ chardev=qmp,mode=control screen_dump_qxl --path /tmp/qmp --times 10000 screen_dump_qxl --path /tmp/qmp --times 1
-rwxr-xr-xscreen_dump_qxl124
1 files changed, 124 insertions, 0 deletions
diff --git a/screen_dump_qxl b/screen_dump_qxl
new file mode 100755
index 0000000..1511f96
--- /dev/null
+++ b/screen_dump_qxl
@@ -0,0 +1,124 @@
+#!/usr/bin/python
+
+import argparse
+import sys
+import os
+import subprocess
+import pyinotify
+import time
+import gtk
+import Image
+import atexit
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--qmp-shell-root', default='/home/alon/src/spice_upstream/qemu/QMP')
+parser.add_argument('--host', default='localhost')
+parser.add_argument('--port', default=0, type=int)
+parser.add_argument('--path', default='')
+parser.add_argument('--filename', default='/tmp/a.ppm')
+parser.add_argument('--show', default='showimage')
+parser.add_argument('--noerase', dest='erase', default=True, action='store_false')
+parser.add_argument('--id', default='')
+parser.add_argument('--times', default=1, type=int)
+parser.add_argument('--sleep', default=0, type=int)
+args = parser.parse_args(sys.argv[1:])
+if not args.path and not args.port:
+ qmp_addr = '/tmp/qmp'
+elif args.path:
+ qmp_addr = args.path
+else:
+ qmp_addr = (args.host, args.port)
+print "connecting to %s" % str(qmp_addr)
+qmp_shell = '%s/qmp-shell' % args.qmp_shell_root
+if not os.path.exists(qmp_shell):
+ print("qmp_shell not at %s" % qmp_shell)
+ os.exit(1)
+sys.path.append(args.qmp_shell_root)
+import qmp
+mon = qmp.QEMUMonitorProtocol(address=qmp_addr)
+mon.connect()
+
+def get_notifier_events():
+ notifier.process_events()
+ if notifier.check_events(10):
+ # read notified events and enqeue them
+ notifier.read_events()
+ return True
+
+class GUI:
+ def __init__(self, args):
+ self.window = gtk.Window()
+ self.image = gtk.Image()
+ self.vbox = gtk.VBox()
+ self.window.add(self.vbox)
+ self.vbox.add(self.image)
+ self.button = gtk.Button()
+ self.button.set_label('take screenshot')
+ self.button.connect("clicked", self.take_screenshot)
+ self.vbox.add(self.button)
+ self.current_image = 0
+ self.times = args.times
+ self.args = args
+ self.window.show_all()
+
+ def take_screenshot(self, _button):
+ # use timeout_add to avoid being inside the button callback.
+ gtk.timeout_add(0, self.take_screen_shot)
+
+ def show_image(self, filename):
+ im = Image.open('/tmp/a.ppm')
+ buf=gtk.gdk.pixbuf_new_from_data(im.tostring(),
+ gtk.gdk.COLORSPACE_RGB, 0, 8, im.size[0], im.size[1],
+ im.size[0]*3)
+ self.image.set_from_pixbuf(buf)
+ self.current_image += 1
+ self.window.set_title(str(self.current_image))
+ # proceed in a different stack to allow update of screen
+ gtk.timeout_add(args.sleep, self.take_screen_shot)
+
+ def take_screen_shot(self):
+ if self.current_image < self.times:
+ take_screen_dump(self.args.id, self.args.filename)
+ else:
+ raw_input('press enter to quit')
+ sys.exit(0)
+ return False
+
+gui = GUI(args)
+
+if os.path.exists(args.filename):
+ print "removing old %s" % args.filename
+ os.unlink(args.filename)
+
+def cleanup():
+ if args.erase:
+ print("erasing %s" % args.filename)
+ os.unlink(args.filename)
+
+atexit.register(cleanup)
+
+# watch for write to target
+class ProcessFile(pyinotify.ProcessEvent):
+ def process_IN_CLOSE_WRITE(self, event):
+ if event.name != os.path.basename(args.filename):
+ return
+ gui.show_image(args.filename)
+
+if args.show:
+ wm = pyinotify.WatchManager()
+ notifier = pyinotify.Notifier(wm, ProcessFile())
+ wdd = wm.add_watch(os.path.dirname(args.filename), pyinotify.IN_CLOSE_WRITE)
+
+def take_screen_dump(qxl_id, filename):
+ print "saving qxl_id %r to %s" % (qxl_id, filename)
+ if qxl_id != '':
+ mon.cmd('__com.redhat_qxl_screendump', dict(id=str(qxl_id),
+ filename=filename))
+ else:
+ mon.cmd('screendump', dict(filename=filename))
+
+take_screen_dump(args.id, args.filename)
+
+# ugly - can't we connect gtk to inotify directly
+gtk.timeout_add(10, get_notifier_events)
+gtk.mainloop()