Merge heads

This commit is contained in:
Daniel P. Berrange 2006-08-17 15:56:10 -04:00
commit 7b650dca01
6 changed files with 160 additions and 83 deletions

View File

@ -3289,6 +3289,22 @@ Máirín Duffy <duffy@redhat.com>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<widget class="GtkToolButton" id="control-screenshot">
<property name="visible">True</property>
<property name="label" translatable="yes">Take screenshot</property>
<property name="use_underline">True</property>
<property name="visible_horizontal">True</property>
<property name="visible_vertical">True</property>
<property name="is_important">False</property>
<signal name="clicked" handler="on_control_screenshot_clicked" last_modification_time="Tue, 15 Aug 2006 20:47:57 GMT"/>
</widget>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
@ -3358,8 +3374,8 @@ Máirín Duffy &lt;duffy@redhat.com&gt;
<widget class="GtkScrolledWindow" id="scrolledwindow6">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
<property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
@ -3371,8 +3387,8 @@ Máirín Duffy &lt;duffy@redhat.com&gt;
<child>
<widget class="GtkImage" id="console-screenshot">
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xalign">0</property>
<property name="yalign">0</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>

View File

@ -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__":

View File

@ -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:

View File

@ -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):

View File

@ -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()

View File

@ -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