summaryrefslogtreecommitdiff
path: root/screen_dump_qxl
blob: 1511f96e5237262f6640be411ed08ec3506ef88d (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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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()