2006-08-11 00:47:14 +04:00
#
# Copyright (C) 2006 Red Hat, Inc.
# Copyright (C) 2006 Daniel P. Berrange <berrange@redhat.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
2007-11-20 19:12:20 +03:00
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA.
2006-08-11 00:47:14 +04:00
#
import gtk
import vte
import os
import gobject
import termios
import tty
2008-02-03 20:42:21 +03:00
import pty
2006-08-11 00:47:14 +04:00
class vmmSerialConsole :
def __init__ ( self , config , vm ) :
self . vm = vm
self . config = config
self . window = gtk . Window ( )
self . window . hide ( )
2006-08-19 01:01:00 +04:00
self . window . set_title ( vm . get_name ( ) + " " + _ ( " serial console " ) )
2006-08-11 00:47:14 +04:00
self . terminal = vte . Terminal ( )
self . terminal . set_cursor_blinks ( True )
self . terminal . set_emulation ( " xterm " )
self . terminal . set_font_from_string ( " fixed 10 " )
self . terminal . set_scrollback_lines ( 1000 )
self . terminal . set_audible_bell ( False )
self . terminal . set_visible_bell ( True )
2006-12-04 20:22:45 +03:00
# XXX python VTE binding has bug failing to register constants
#self.terminal.set_backspace_binding(vte.ERASE_ASCII_BACKSPACE)
self . terminal . set_backspace_binding ( 1 )
2006-08-11 00:47:14 +04:00
self . terminal . connect ( " commit " , self . send_data )
self . terminal . show ( )
scrollbar = gtk . VScrollbar ( )
scrollbar . set_adjustment ( self . terminal . get_adjustment ( ) )
box = gtk . HBox ( )
box . pack_start ( self . terminal )
box . pack_start ( scrollbar )
self . window . add ( box )
self . ptyio = None
self . ptysrc = None
self . ptytermios = None
2006-08-19 01:01:00 +04:00
self . window . connect ( " delete-event " , self . close )
2006-08-11 00:47:14 +04:00
def show ( self ) :
2006-08-19 01:01:00 +04:00
self . opentty ( )
2006-11-03 17:51:23 +03:00
self . window . show_all ( )
self . window . present ( )
2006-08-11 00:47:14 +04:00
2006-08-19 01:01:00 +04:00
def close ( self , src = None , ignore = None ) :
self . closetty ( )
2006-08-11 00:47:14 +04:00
self . window . hide ( )
return True
2006-11-03 18:02:02 +03:00
def is_visible ( self ) :
if self . window . flags ( ) & gtk . VISIBLE :
return 1
return 0
2006-08-19 01:01:00 +04:00
def opentty ( self ) :
2006-08-11 00:47:14 +04:00
if self . ptyio != None :
2006-08-19 01:01:00 +04:00
self . closetty ( )
2008-02-03 20:42:21 +03:00
ipty = self . vm . get_serial_console_tty ( )
2006-08-11 00:47:14 +04:00
2008-02-03 20:42:21 +03:00
if ipty == None :
2006-08-11 00:47:14 +04:00
return
2008-02-03 20:42:21 +03:00
self . ptyio = pty . slave_open ( ipty )
2006-08-11 00:47:14 +04:00
self . ptysrc = gobject . io_add_watch ( self . ptyio , gobject . IO_IN | gobject . IO_ERR | gobject . IO_HUP , self . display_data )
# Save term settings & set to raw mode
self . ptytermios = termios . tcgetattr ( self . ptyio )
2008-07-25 00:42:43 +04:00
tty . setraw ( self . ptyio , termios . TCSANOW )
2006-08-11 00:47:14 +04:00
2006-08-19 01:01:00 +04:00
def closetty ( self ) :
2006-08-11 00:47:14 +04:00
if self . ptyio == None :
return
# Restore term settings
2006-08-19 00:39:41 +04:00
try :
2008-07-25 00:42:43 +04:00
termios . tcsetattr ( self . ptyio , termios . TCSANOW , self . ptytermios )
2006-08-19 00:39:41 +04:00
except :
# The domain may already have exited, destroying the pty, so ignore
pass
2006-08-11 00:47:14 +04:00
os . close ( self . ptyio )
gobject . source_remove ( self . ptysrc )
self . ptyio = None
self . ptysrc = None
self . ptytermios = None
def send_data ( self , src , text , length ) :
if self . ptyio != None :
os . write ( self . ptyio , text )
def display_data ( self , src , cond ) :
if cond == gobject . IO_IN :
data = os . read ( self . ptyio , 1024 )
self . terminal . feed ( data , len ( data ) )
return True
else :
2006-08-19 01:01:00 +04:00
self . closetty ( )
2006-08-11 00:47:14 +04:00
return False