diff --git a/src/virt-manager.glade b/src/virt-manager.glade
index 6b28d5bd..228ee895 100644
--- a/src/virt-manager.glade
+++ b/src/virt-manager.glade
@@ -3289,6 +3289,22 @@ Máirín Duffy <duffy@redhat.com>
True
+
+
+
+ True
+ Take screenshot
+ True
+ True
+ True
+ False
+
+
+
+ False
+ True
+
+
0
@@ -3358,8 +3374,8 @@ Máirín Duffy <duffy@redhat.com>
True
True
- GTK_POLICY_ALWAYS
- GTK_POLICY_ALWAYS
+ GTK_POLICY_AUTOMATIC
+ GTK_POLICY_AUTOMATIC
GTK_SHADOW_NONE
GTK_CORNER_TOP_LEFT
@@ -3371,8 +3387,8 @@ Máirín Duffy <duffy@redhat.com>
True
- 0.5
- 0.5
+ 0
+ 0
0
0
diff --git a/src/virt-manager.py.in b/src/virt-manager.py.in
index 7ad74bd4..e2437433 100755
--- a/src/virt-manager.py.in
+++ b/src/virt-manager.py.in
@@ -76,39 +76,46 @@ gtk.window_set_default_icon_from_file(icon_dir + "/" + appname + "-icon.svg")
def main():
optParser = OptionParser()
optParser.add_option("-c", "--connect", dest="uri", help="Connect to hypervisor at URI", metavar="URI")
+ optParser.add_option("--no-dbus", action="store_true", dest="nodbus", help="Disable DBus service for controlling UI")
(options, args) = optParser.parse_args()
config = vmmConfig(appname, appversion, gconf_dir, glade_dir, icon_dir)
engine = vmmEngine(config)
- bus = None
- try:
- bus = dbus.SessionBus()
-
- dbusProxy = bus.get_object("org.freedesktop.DBus", "/org/freedesktop/DBus")
- dbusObj = dbus.Interface(dbusProxy, "org.freedesktop.DBus")
-
- # If we're already running, then just talk to existing process
- if os.getenv("DBUS_STARTER_ADDRESS"):
- name = dbus.service.BusName("com.redhat.virt.manager", bus=bus)
- remote = vmmRemote(engine, name)
- else:
- managerProxy = bus.get_object("com.redhat.virt.manager", "/com/redhat/virt/manager")
- managerObj = dbus.Interface(managerProxy, "com.redhat.virt.manager")
-
- if options.uri != None:
- managerObj.show_host_summary(options.uri)
- else:
- managerObj.show_connect()
- # yes, we exit completely now - remote service is in charge
- return
- except:
- print str(sys.exc_info()[0]) + " " + str(sys.exc_info()[1])
- print _("Could not connection to session bus, disabling DBus service")
+ if options.nodbus:
if options.uri != None:
engine.show_manager(options.uri)
else:
engine.show_connect()
+ else:
+ bus = None
+ try:
+ bus = dbus.SessionBus()
+
+ dbusProxy = bus.get_object("org.freedesktop.DBus", "/org/freedesktop/DBus")
+ dbusObj = dbus.Interface(dbusProxy, "org.freedesktop.DBus")
+
+ # If we're already running, then just talk to existing process
+ if os.getenv("DBUS_STARTER_ADDRESS"):
+ name = dbus.service.BusName("com.redhat.virt.manager", bus=bus)
+ remote = vmmRemote(engine, name)
+ else:
+ managerProxy = bus.get_object("com.redhat.virt.manager", "/com/redhat/virt/manager")
+ managerObj = dbus.Interface(managerProxy, "com.redhat.virt.manager")
+
+ if options.uri != None:
+ managerObj.show_host_summary(options.uri)
+ else:
+ managerObj.show_connect()
+ # yes, we exit completely now - remote service is in charge
+ return
+ except:
+ print str(sys.exc_info()[0]) + " " + str(sys.exc_info()[1])
+ print _("Could not connection to session bus, disabling DBus service")
+ if options.uri != None:
+ engine.show_manager(options.uri)
+ else:
+ engine.show_connect()
gtk.main()
if __name__ == "__main__":
diff --git a/src/virtManager/console.py b/src/virtManager/console.py
index b7b9f6f8..819dbd8d 100644
--- a/src/virtManager/console.py
+++ b/src/virtManager/console.py
@@ -64,6 +64,7 @@ class vmmConsole(gobject.GObject):
self.vncViewer = GRFBViewer()
scrolledWin = gtk.ScrolledWindow()
+ scrolledWin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
vp = gtk.Viewport()
vp.set_shadow_type(gtk.SHADOW_NONE)
@@ -74,6 +75,7 @@ class vmmConsole(gobject.GObject):
self.window.get_widget("console-pages").append_page(scrolledWin, gtk.Label("VNC"))
scrolledWin.show()
+ self.vncViewer.connect("size-request", self.autosize, vp)
self.vncViewer.show()
self.ignorePause = False
@@ -108,6 +110,23 @@ class vmmConsole(gobject.GObject):
self.vncViewer.connect("disconnected", self._vnc_disconnected)
+ # Auto-increase the window size to fit the console - within reason
+ # though, cos we don't want a min window size greater than the screen
+ # the user has scrollbars anyway if they want it smaller / it can't fit
+ def autosize(self, src, size, vp):
+ rootWidth = gtk.gdk.screen_width()
+ rootHeight = gtk.gdk.screen_height()
+
+ vncWidth, vncHeight = src.get_size_request()
+
+ if vncWidth > (rootWidth-200):
+ vncWidth = rootWidth - 200
+ if vncHeight > (rootHeight-200):
+ vncHeight = rootHeight - 200
+
+ vp.set_size_request(vncWidth+3, vncHeight+3)
+
+
def show(self):
dialog = self.window.get_widget("vmm-console")
dialog.show_all()
@@ -319,12 +338,12 @@ class vmmConsole(gobject.GObject):
if screenshot != None:
cr = screenshot.cairo_create()
width, height = screenshot.get_size()
-
- # Set 60% gray overlayed
- cr.set_source_rgba(0, 0, 0, 0.6)
+
+ # Set 50% gray overlayed
+ cr.set_source_rgba(0, 0, 0, 0.5)
cr.rectangle(0, 0, width, height)
cr.fill()
-
+
# Render a big text 'paused' across it
cr.set_source_rgba(1, 1,1, 1)
cr.set_font_size(80)
@@ -335,7 +354,7 @@ class vmmConsole(gobject.GObject):
y = height/2 - (extents[3]/2)
cr.move_to(x, y)
cr.show_text(overlay)
-
+
self.window.get_widget("console-screenshot").set_from_pixmap(screenshot, None)
self.activate_screenshot_page()
else:
diff --git a/src/vncViewer/rfb.py b/src/vncViewer/rfb.py
index bc3d5e30..6699d45f 100644
--- a/src/vncViewer/rfb.py
+++ b/src/vncViewer/rfb.py
@@ -43,7 +43,16 @@ class RFBError(Exception): pass
class RFBAuthError(RFBError): pass
class RFBProtocolError(RFBError): pass
-
+ENCODING_RAW = 0
+ENCODING_COPY_RECT = 1
+ENCODING_RRE = 2
+ENCODING_CORRE = 4
+ENCODING_HEXTILE = 5
+ENCODING_ZRLE = 16
+ENCODING_DESKTOP_RESIZE = -223
+ENCODING_CURSOR_POS = -232
+ENCODING_RICH_CURSOR = -239
+ENCODING_XCURSOR = -240
## RFBFrameBuffer
##
@@ -53,6 +62,9 @@ class RFBFrameBuffer:
#print >>stderr, 'init_screen: %dx%d, name=%r' % (width, height, name)
raise NotImplementedError
+ def resize_screen(self, width, height):
+ raise NotImplementedError
+
def set_converter(self, convert_pixels, convert_color1):
self.convert_pixels = convert_pixels
self.convert_color1 = convert_color1
@@ -88,7 +100,7 @@ class RFBFrameBuffer:
class RFBProxy:
"Abstract class of RFB clients."
- def __init__(self, fb=None, preferred_encoding=(5,0), debug=0):
+ def __init__(self, fb=None, preferred_encoding=(ENCODING_RAW,ENCODING_HEXTILE), debug=0):
self.fb = fb
self.debug = debug
self.preferred_encoding = preferred_encoding
@@ -274,19 +286,19 @@ class RFBProxy:
(x0, y0, width, height, t) = unpack('>HHHHl', self.recv_relay(12))
if self.debug:
print >>stderr, ' %d: %d x %d at (%d,%d), type=%d' % (rectindex, width, height, x0, y0, t)
- # RawEncoding
- if t == 0:
+
+ if t == ENCODING_RAW:
l = width*height*self.bytesperpixel
data = self.recv_relay(l)
if self.debug:
print >>stderr, ' RawEncoding: len=%d, received=%d' % (l, len(data))
if self.fb:
self.fb.process_pixels(x0, y0, width, height, data)
- # CopyRectEncoding
- elif t == 1:
+
+ elif t == ENCODING_COPY_RECT:
raise RFBProtocolError('unsupported: CopyRectEncoding')
- # RREEncoding
- elif t == 2:
+
+ elif t == ENCODING_RRE:
(nsubrects,) = unpack('>L', self.recv_relay(4))
bgcolor = self.recv_relay(self.bytesperpixel)
if self.debug:
@@ -300,8 +312,8 @@ class RFBProxy:
self.fb.process_solid(x0+x, y0+y, w, h, fgcolor)
if 2 <= self.debug:
print >>stderr, ' RREEncoding: ', (x,y,w,h,fgcolor)
- # CoRREEncoding
- elif t == 4:
+
+ elif t == ENCODING_CORRE:
(nsubrects,) = unpack('>L', self.recv_relay(4))
bgcolor = self.recv_relay(self.bytesperpixel)
if self.debug:
@@ -315,8 +327,8 @@ class RFBProxy:
self.fb.process_solid(x0+x, y0+y, w, h, fgcolor)
if 2 <= self.debug:
print >>stderr, ' CoRREEncoding: ', (x,y,w,h,fgcolor)
- # HextileEncoding
- elif t == 5:
+
+ elif t == ENCODING_HEXTILE:
if self.debug:
print >>stderr, ' HextileEncoding'
(fgcolor, bgcolor) = (None, None)
@@ -368,11 +380,14 @@ class RFBProxy:
self.fb.process_solid(x0+x+(xy>>4), y0+y+(xy&15), (wh>>4)+1, (wh&15)+1, fgcolor)
if 3 <= self.debug:
print >>stderr, ' ', (xy,wh)
- # ZRLEEncoding
- elif t == 16:
+
+ elif t == ENCODING_ZRLE:
raise RFBProtocolError('unsupported: ZRLEEncoding')
- # RichCursor
- elif t == -239:
+
+ elif t == ENCODING_DESKTOP_RESIZE:
+ self.clipping = self.fb.resize_screen(width, height)
+
+ elif t == ENCODING_RICH_CURSOR:
if width and height:
rowbytes = (width + 7) / 8;
# Cursor image RGB
@@ -392,8 +407,8 @@ class RFBProxy:
return '\x00\x00\x00\x00'
data = ''.join([ conv1(i) for i in xrange(0, len(data), 4) ])
self.fb.change_cursor(width, height, x0, y0, data)
- # XCursor
- elif t == -240:
+
+ elif t == ENCODING_XCURSOR:
if width and height:
rowbytes = (width + 7) / 8;
# Foreground RGB
@@ -419,8 +434,8 @@ class RFBProxy:
return '\x00\x00\x00\x00'
data = ''.join([ conv1(i) for i in xrange(len(data)) ])
self.fb.change_cursor(width, height, x0, y0, data)
- # CursorPos -> only change the cursor position
- elif t == -232:
+
+ elif t == ENCODING_CURSOR_POS:
if self.debug:
print >>stderr, 'CursorPos: %d,%d' % (x0,y0)
if self.fb:
@@ -467,7 +482,7 @@ class RFBProxy:
class RFBNetworkClient(RFBProxy):
def __init__(self, host, port, fb=None, pwdfile=None,
- preferred_encoding=(0,5), debug=0):
+ preferred_encoding=(ENCODING_RAW,ENCODING_HEXTILE), debug=0):
RFBProxy.__init__(self, fb=fb, preferred_encoding=preferred_encoding, debug=debug)
self.host = host
self.port = port
@@ -478,8 +493,6 @@ class RFBNetworkClient(RFBProxy):
def init(self):
self.sock.connect((self.host, self.port))
x = RFBProxy.init(self)
- print >>stderr, 'Connected: %s:%d, protocol_version=3.%d, preferred_encoding=%s' % \
- (self.host, self.port, self.protocol_version, self.preferred_encoding)
return x
def recv(self, n):
diff --git a/src/vncViewer/vnc.py b/src/vncViewer/vnc.py
index 54661eb7..b63bb57b 100755
--- a/src/vncViewer/vnc.py
+++ b/src/vncViewer/vnc.py
@@ -29,10 +29,6 @@ stderr = sys.stderr
from time import time
-#host = "courgette"
-host = "localhost"
-port = 5901
-
class GRFBFrameBuffer(rfb.RFBFrameBuffer, gobject.GObject):
__gsignals__= {
"resize": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, [int,int]),
@@ -43,6 +39,10 @@ class GRFBFrameBuffer(rfb.RFBFrameBuffer, gobject.GObject):
self.__gobject_init__()
self.canvas = canvas
self.pixmap = None
+ self.name = "VNC"
+
+ def get_name(self):
+ return self.name
def get_pixmap(self):
return self.pixmap
@@ -57,8 +57,11 @@ class GRFBFrameBuffer(rfb.RFBFrameBuffer, gobject.GObject):
return clone
def init_screen(self, width, height, name):
- self.pixmap = gtk.gdk.Pixmap(self.canvas.window, width, height)
+ self.name = name
+ return self.resize_screen(width, height)
+ def resize_screen(self, width, height):
+ self.pixmap = gtk.gdk.Pixmap(self.canvas.window, width, height)
self.emit("resize", width, height)
return (0, 0, width, height)
@@ -92,8 +95,8 @@ class GRFBNetworkClient(rfb.RFBNetworkClient, gobject.GObject):
"disconnected": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, [])
}
- def __init__(self, host, port, converter):
- rfb.RFBNetworkClient.__init__(self, host, port, converter)
+ def __init__(self, host, port, converter, debug=0):
+ rfb.RFBNetworkClient.__init__(self, host, port, converter, debug=debug,preferred_encoding=(rfb.ENCODING_RAW,rfb.ENCODING_DESKTOP_RESIZE))
self.__gobject_init__()
self.watch = None
@@ -177,6 +180,9 @@ class GRFBViewer(gtk.DrawingArea):
self.set_property("can-focus", True)
+ def get_framebuffer_name(self):
+ return self.fb.get_name()
+
def connect_to_host(self, host, port):
if self.client != None:
self.disconnect_from_host()
@@ -249,16 +255,19 @@ class GRFBViewer(gtk.DrawingArea):
return self.fb.clone_pixmap()
def update_pointer(self, win, event):
- x, y, state = event.window.get_pointer()
- self.client.update_pointer(self.state_to_mask(state), x, y)
+ if self.client != None:
+ x, y, state = event.window.get_pointer()
+ self.client.update_pointer(self.state_to_mask(state), x, y)
return True
def key_press(self, win, event):
- self.client.update_key(1, event.keyval)
+ if self.client != None:
+ self.client.update_key(1, event.keyval)
return True
def key_release(self, win, event):
- self.client.update_key(0, event.keyval)
+ if self.client != None:
+ self.client.update_key(0, event.keyval)
return True
def get_frame_buffer(self):
@@ -283,7 +292,10 @@ gobject.type_register(GRFBViewer)
def main():
-
+ host = sys.argv[1]
+ port = int(sys.argv[2])
+ password = sys.argv[3]
+
win = gtk.Window()
win.set_name("VNC")
win.connect("destroy", lambda w: gtk.main_quit())
@@ -291,31 +303,39 @@ def main():
pane = gtk.ScrolledWindow()
pane.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
win.add(pane)
- pane.show()
vp = gtk.Viewport()
pane.add(vp)
- vp.show()
-
- vnc = GRFBWidget()
- vp.add(vnc)
- vnc.show()
+ vnc = GRFBViewer()
+ vp.add(vnc)
+
+ win.show_all()
win.present()
vnc.connect_to_host(host, port)
+ vnc.authenticate(password)
+ vnc.activate()
+ win.set_title(vnc.get_framebuffer_name())
- rootWidth = gtk.gdk.screen_width()
- rootHeight = gtk.gdk.screen_height()
+ def autosize():
+ rootWidth = gtk.gdk.screen_width()
+ rootHeight = gtk.gdk.screen_height()
- vncWidth, vncHeight = vnc.get_size_request()
+ vncWidth, vncHeight = vnc.get_size_request()
+
+ if vncWidth > (rootWidth-200):
+ vncWidth = rootWidth - 200
+ if vncHeight > (rootHeight-200):
+ vncHeight = rootHeight - 200
+
+ vp.set_size_request(vncWidth+3, vncHeight+3)
+
+ def resize(src, size):
+ autosize()
+
+ vnc.connect('size-request', resize)
- if vncWidth > (rootWidth-200):
- vncWidth = rootWidth - 200
- if vncHeight > (rootHeight-200):
- vncHeight = rootHeight - 200
-
- vp.set_size_request(vncWidth+2, vncHeight+2)
gtk.main()
vnc.disconnect_from_host()
diff --git a/virt-manager.spec.in b/virt-manager.spec.in
index 2392fb7f..97ba989f 100644
--- a/virt-manager.spec.in
+++ b/virt-manager.spec.in
@@ -31,6 +31,8 @@ Requires: gnome-keyring >= 0.4.9
Requires: gnome-python2-gnomekeyring >= 2.15.4
# Minimum we've tested with
Requires: libxml2-python >= 2.6.23
+# Required to install Xen guests
+Requires: python-xeninst >= 0.90.0
# Earlier vte hand broken python binding module
Requires: vte >= 0.12.2