Merge heads
This commit is contained in:
commit
7b650dca01
|
@ -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 <duffy@redhat.com>
|
|||
<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 <duffy@redhat.com>
|
|||
<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>
|
||||
|
|
|
@ -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__":
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue