#!/usr/bin/env python # Copyright (C) 2006, Red Hat, Inc. # # 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 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import os import sys import socket import logging log = logging.getLogger( 'sugar-emulator' ) log.setLevel( logging.DEBUG ) import pygtk pygtk.require('2.0') import gtk import gobject from sugar import env def _get_display_number(): """Find a free display number trying to connect to 6000+ ports""" log.info( "Attempting to find free port for X11 (Xephyr)" ) retries = 20 display_number = 1 display_is_free = False while not display_is_free and retries > 0: lockstr = "/tmp/.X%d-lock" % display_number if not os.path.exists(lockstr): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: s.connect(('127.0.0.1', 6000 + display_number)) s.close() except: display_is_free = True break display_number += 1 retries -= 1 if display_is_free: log.info( ' Found free port: #%s (%s)', display_number, display_number+6000 ) return display_number else: logging.error('Cannot find a free display.') sys.exit(0) def _start_xephyr(): display = _get_display_number() log.info( 'Starting the Xephyr nested X display on display %s', display ) cmd = [ 'Xephyr' ] cmd.append(':%d' % display) cmd.append('-ac') if gtk.gdk.screen_width() < 1200 or gtk.gdk.screen_height() < 900: cmd.append('-fullscreen') else: cmd.append('-screen') cmd.append('%dx%d' % (1200, 900)) dpi = gtk.settings_get_default().get_property('gtk-xft-dpi') if dpi > 0: cmd.append('-dpi') cmd.append('%d' % int(dpi/1024)) log.debug( 'Xephyr command: %s', " ".join( cmd ) ) result = gobject.spawn_async(cmd, flags=gobject.SPAWN_SEARCH_PATH) pid = result[0] os.environ['DISPLAY'] = ":%d" % (display) os.environ['SUGAR_EMULATOR_PID'] = str(pid) def _start_matchbox(): log.info( 'Starting the matchbox window manager' ) cmd = ['matchbox-window-manager'] cmd.extend(['-use_titlebar', 'no']) cmd.extend(['-theme', 'olpc']) log.debug( 'Matchbox command: %s', " ".join( cmd) ) gobject.spawn_async(cmd, flags=gobject.SPAWN_SEARCH_PATH) def _setup_env(): os.environ['SUGAR_EMULATOR'] = 'yes' source_dir = os.path.dirname(os.path.abspath(__file__)) if os.path.isfile(os.path.join(source_dir, 'autogen.sh')): os.environ['SUGAR_PATH'] = source_dir if os.environ.has_key('PYTHONPATH'): path = os.environ['PYTHONPATH'] os.environ['PYTHONPATH'] = source_dir + ':' + path log.info( 'Set PYTHONPATH=%s', os.environ['PYTHONPATH'] ) os.environ['GABBLE_LOGFILE'] = os.path.join(env.get_profile_path(), 'logs', 'telepathy-gabble.log') os.environ['SALUT_LOGFILE'] = os.path.join(env.get_profile_path(), 'logs', 'telepathy-salut.log') os.environ['STREAM_ENGINE_LOGFILE'] = os.path.join(env.get_profile_path(), 'logs', 'telepathy-stream-engine.log') def main(): """Script-level operations""" logging.basicConfig() _setup_env() _start_xephyr() from sugar import env if env.is_emulator(): gtkrc_filename = 'sugar.gtkrc' else: gtkrc_filename = 'sugar-xo.gtkrc' os.environ['GTK2_RC_FILES'] = env.get_data_path(gtkrc_filename) if len(sys.argv) == 1: program = 'sugar-shell' else: _start_matchbox() program = sys.argv[1] command = ['dbus-launch', 'dbus-launch', '--exit-with-session', program] log.info( "Attempting to launch sugar to replace this process: %s", " ".join(command) ) os.execlp( *command ) if __name__ == "__main__": main()